Вопрос или проблема
Я использую Next 14 в качестве фронтенда, Spring Boot в качестве бэкенда и Nginx в качестве обратного прокси, размещенного на AWS Ubuntu EC2. Я использую PM2 для управления процессами.
Сайт работает нормально, но через некоторое время (в основном около недели) Next.js выдает ошибки (из error.tsx). Лог Nginx показывает, что некоторые запросы возвращают статус 403 случайным образом, а некоторые — 200. Запросы с 403 не принимаются бэкенд-шлюзом, в то время как 200 — принимаются. Это странная ошибка, с которой я не знаю, что делать и с чего начать отладку.
Я обновил свой файл nginx sites-available.
upstream backend_service {
server 127.0.0.1:3001;
keepalive 32;
}
upstream prod_backend {
server prod-backend.rb.ai;
keepalive 32; # Повторное использование соединений для повышения производительности
}
server {
listen 80;
listen [::]:80;
server_name testing.com www.testing.com;
# Включить Gzip-сжатие для этого сайта
gzip on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# Конечная точка для проверки состояния
location /health {
return 200 'Healthy';
add_header Content-Type text/plain;
}
# Обработка запросов на /bm-main... это перенаправление запросов на URL бэкенда
location /bm-main {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://testing.com' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
add_header 'Access-Control-Max-Age' 86400;
add_header 'Content-Length' 0;
add_header 'Content-Type' 'text/plain';
return 204;
}
add_header 'Access-Control-Allow-Origin' 'https://testing.com' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
proxy_pass https://prod-backend.rb.ai/bm-main; # балансировка нагрузки по URL
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_next_upstream error timeout invalid_header http_502 http_503 http_504;
}
# Маршрут по умолчанию (для всех остальных запросов)
location / {
proxy_pass http://backend_service;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Connection "";
proxy_redirect off;
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
proxy_next_upstream error timeout invalid_header http_502 http_503 http_504;
}
}
Моя конфигурация PM2
module.exports = {
apps: [
{
name: 'testing', // Название проекта
cwd: '/var/www/testing-nextjs', // Путь к папке вашего проекта Next.js
script: 'yarn', // Используйте Yarn для запуска приложения
args: 'start', // Скрипт запуска Yarn для Next.js
instances: 'max', // Используйте столько CPU, сколько доступно для масштабирования
exec_mode: 'cluster', // Включите кластерный режим для распределения нагрузки
watch: false, // Отключить наблюдение за изменениями файлов в продакшене (оптимизация производительности)
autorestart: true, // Автоматически перезапускать, если приложение зависает
max_memory_restart: '1G', // Перезапускать приложение, если оно превышает 1 ГБ использования памяти
env: {
NODE_ENV: 'production', // Установить окружение на продакшн
PORT: 3001 // Порт, на котором будет работать ваше приложение Next.js
},
log_date_format: 'YYYY-MM-DD HH:mm Z', // Формат для временных меток логов
error_file: '/var/www//logs/error.log', // Путь к логам ошибок
out_file: '/var/www/logs/out.log', // Путь к логам вывода
}
]
Ответ или решение
Замедление работы сайта Next.js после недели: Анализ и решение проблемы
Введение
Ваша проблема по замедлению работы сайта на Next.js после недели эксплуатации с возможностью устранения путем перезапуска Nginx предполагает несколько возможных причин. Мы проведем детальный анализ возможных участков кода, окружения и конфигурации, а также предложим шаги для диагностики и улучшения рабочей нагрузки вашего приложения.
1. Описание проблемы
Судя по вашему описанию, вы используете Next.js 14 в качестве фронтенда, Spring Boot как бэкенд и Nginx в качестве обратного прокси на сервере AWS EC2 с операционной системой Ubuntu. Обработка процессов осуществляется с помощью PM2. Проблема в том, что через определенный промежуток времени (чаще всего через неделю) ваше приложение начинает вызывать ошибки (из файла error.tsx), что подтверждается логами Nginx, где фиксируются случайные 403 и 200 ответы.
2. Диагностика
A. Анализ логов Nginx
-
403 Ошибки: Происходят ограничения доступа к ресурсам вашего сайта. Вам следует убедиться, что конфигурация CORS в вашем Nginx настроена корректно, особенно для методов OPTIONS и других методов, которые могут вызывать ошибки доступа. Проверьте, получаете ли вы эти 403 ошибки только для определенных маршрутов или пользовательских действий.
-
200 Ошибки: Это означает, что запросы к вашему приложению успешно завершены. Следует выяснить, что именно происходит между вашими серверными компонентами при получении запросов с кодом 200.
B. Настройки Nginx
-
Проверьте, правильно ли настроены заголовки
Access-Control-Allow-Origin
. Убедитесь, что они не блокируют определенные запросы от других источников. -
Проверьте, не истекает ли тайм-аут соединений. Неправильные значения времени ожидания могут привести к потере соединений и, как следствие, к ошибкам.
C. Конфигурация PM2
Обратите внимание на конфигурацию PM2. Ваша настройка max_memory_restart: '1G'
может привести к тому, что приложение Restarts, если его использование памяти превышает 1 ГБ, что часто может происходить из-за утечек памяти. Проверьте логи PM2 на наличие частых перезапусков.
3. Возможные решения
-
Оптимизация конфигурации Nginx:
- Убедитесь в корректности всех настроек CORS.
- Увеличьте значение
proxy_read_timeout
, чтобы избежать неожиданного завершения соединений.
-
Мониторинг работы приложения:
- Внедрите мониторинг для получения метрик использования памяти и производительности вашего приложения. Используйте инструменты, такие как PM2 Monitor, для отслеживания ресурсов вашего процесса.
-
Обновление кода:
- Проверьте наличие утечек памяти в коде вашего приложения Next.js. Используйте инструменты анализа производительности, чтобы выявить и исправить проблемные участки кода.
-
Периодическое перезапуска PM2 и Nginx:
- Настройте автоматический перезапуск процесса PM2 или Nginx через crontab каждые несколько дней, чтобы избежать замедления без необходимости ручного вмешательства.
-
Серверное окружение:
- Убедитесь, что ваша инстанция AWS EC2 имеет достаточные ресурсы (ЦП, память), чтобы поддерживать ожидаемую нагрузку. Возможно, вам будет полезно обновить инстанцию или добавить авто-масштабирование.
Заключение
Проблема с замедлением приложения Next.js, возникающая через определенное время, может быть вызвана множеством факторов, включая неправильные настройки Nginx, проблемы в коде или недостатки в ресурсах сервера. Предложенные рекомендации могут помочь вам улучшить производительность вашего приложения и устранить ошибки 403 и 200, а также обеспечить стабильную работу в долгоиграющем режиме. Применяя системный подход и анализируя каждую деталь, вы сможете создать более надежное и производительное веб-приложение.