Балансировка нагрузки с помощью Docker Compose + Nginx + Nestjs
Всем привет.
Возможно, вы сталкивались со случаями, когда ваш сервер перегружен, тормозит и не может обрабатывать входящие запросы.
И когда вы сталкиваетесь с этим случаем, есть несколько способов решения этой проблемы, например:
- Вариант 1. Определите основную причину кода, вызывающего ошибку.
- Вариант 2. Увеличение мощности сервера.
- Вариант 3. Используйте Docker + Nginx для создания балансировки нагрузки для распределения входящих запросов.
и т. д,...
Сегодня я расскажу, как реализовать Вариант 3. Технологии, которые я использую:
- NestJS
- Docker: Nginx, PM2
1. Создайте простой исходный код NestJs
Предварительные условия
Убедитесь, что Node.js (версия >= 16) установлен в вашей операционной системе.
Настройка
Настроить новый проект с помощью Nest CLI довольно просто. Установив npm, вы можете создать новый проект Nest с помощью следующих команд в терминале вашей ОС:
npm i -g @nestjs/cli
nest new load-balance-with-docker
Затем перейдите в папку с исходным кодом:
cd load-balance-with-docker
И у вас есть структура папки, как на картинке:
2. Конфигурация докера
Предварительные условия
Установите докер для вашего устройства: https://docs.docker.com/engine/install/
Нам нужно настроить 3 части:
- Nginx
- Server
- Pm2
2.1 Nginx
Создайте корневой каталог, создайте новую папку с именем nginx:
Создайте файл с именем Dockerfile в каталоге nginx следующим образом:
# nginx/Dockerfile
FROM nginx:stable-alpine
COPY default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Приведенный выше фрагмент конфигурации представляет собой файл Dockerfile для создания образа Docker на основе образа nginx:stable-alpine.
FROM nginx:stable-alpine: эта строка определяет базовый образ, на котором будет основан новый образ, в данном случаеnginx:stable-alpine. Изображениеnginx:stable-alpine— это стабильная версия Nginx для Alpine Linux.
COPY default.conf /etc/nginx/conf.d/default.conf: эта строка копирует файл default.conf в путь/etc/nginx/conf.d/default.confв образе. Файлdefault.confсодержит конфигурацию Nginx, которая будет использоваться при запуске контейнера.
EXPOSE 80: эта строка указывает, что контейнер будет прослушивать порт 80. Однако использованиеEXPOSEне открывает порт на хост-компьютере, это просто инструкция, сообщающая другим, какой порт будет прослушивать контейнер.
CMD ["nginx", "-g", "daemon off;"]: эта строка определяет команду, которую контейнер выполнит при запуске. В этом случае контейнер выполнит командуnginx -g 'daemon off;'запустить Nginx в режиме без демона, чтобы контейнер не закрывался сразу после запуска Nginx.
Затем создайте файл default.conf в каталоге nginx.
# nginx/default.conf
upstream my-loadbalancer {
server my-loadbalancer:3000;
}
server {
listen 80;
location / {
proxy_pass http://my-loadbalancer/;
}
}
upstream my-loadbalancer { server my-loadbalancer:3000; }: Этот фрагмент определяет группу серверов (восходящих) с именем «my-loadbalancer». В этом случае на порту 3000 работает только один внутренний сервер.
server { listen 80; ... }: это конфигурация сервера Nginx. Он прослушивает порт 80 для обработки входящих HTTP-запросов.
location / { proxy_pass http://my-loadbalancer/; }: В этом разделе определяется местоположение по умолчанию для всех запросов. Он используетproxy_passдля перенаправления всех запросов на вышестоящий «бэкэнд». Это позволяет Nginx действовать как прокси-сервер и перенаправлять запросы на внутренний сервер, работающий на порту 3000.
2.2 Сервер
В основном каталоге создайте файл Dockerfile для сервера следующим образом:
# Use node:18 image
FROM node:18.0.0
# Set working directory
WORKDIR /app
# Install dependencies
COPY package*.json ./
RUN npm install
# Copy source code
COPY . .
# Build app
RUN npm run build
# Install PM2 globally
RUN npm install pm2 -g
# Set environment variables
ENV PORT 3000
# Expose port
EXPOSE $PORT
# Start app
CMD ["pm2-runtime", "start", "ecosystem.config.js"]
Затем создайте файл docker-compose.yml:
version: '1'
services:
nginx:
build: ./nginx
ports:
- "80:80"
depends_on:
- my-loadbalancer
my-loadbalancer:
build: .
environment:
- PORT=3000
deploy:
replicas: 4
Приведенная выше конфигурация представляет собой файл, созданный докером, используемый для определения и запуска служб в среде Docker.
- Сначала он определяет две службы:
nginxиmy-loadbalancer.
- Служба
nginxсоздается из каталога./nginxи предоставляет порт80на хосте и в контейнере.
- Перед запуском служба
nginxтакже зависит от службыmy-loadbalancer.
- Сервис
my-loadbalancerсоздается из текущего каталога (каталога, содержащего файлdocker-compose) и устанавливает переменную средыPORT=3000.
- Наконец, сервис
my-loadbalancerразвертывается с четырьмя репликами для создания среды с балансировкой нагрузки. Вы можете изменить количество реплик на сервере.
2,3 м2
Создайте файл ecosystem.config.js в корневом каталоге:
module.exports = {
apps: [{
name: 'my-loadbalancer',
script: 'dist/main.js',
instances: 'max',
autorestart: true,
watch: false,
max_memory_restart: '1G',
}]
};
3. Готово
Наконец, чтобы запустить сервер, вы можете использовать команду:
docker-compose up -d
Затем вы можете проверить контейнеры с помощью docker ps:
Наконец, вы можете получить доступ к серверу по URL: http://localhost:80.
Вы можете проверить статистику контейнеров с помощью команды docker stats.
Вы можете найти исходный код здесь.
Спасибо за чтение.