DevGang
Авторизоваться

Балансировка нагрузки с помощью 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.

Вы можете найти исходный код здесь.

Спасибо за чтение.

Источник:

#NestJS #Nginx #Docker
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу