В настоящее время я использую Nginx в качестве балансировщика нагрузки, чтобы сбалансировать сетевой трафик между 3 узлами, на которых работает API NodeJS.
Экземпляр Nginx работает на node1, и каждый запрос выполняется на node1. У меня есть обзор запросов около 700 тыс. За 2 часа, и nginx настроен для переключения их циклическим образом между node1, node2 и node3. Здесь conf.d/deva.conf
:
upstream deva_api {
server 10.8.0.30:5555 fail_timeout=5s max_fails=3;
server 10.8.0.40:5555 fail_timeout=5s max_fails=3;
server localhost:5555;
keepalive 300;
}
server {
listen 8000;
location /log_pages {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Connection "";
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PATCH, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Origin,X-Auth-Token';
add_header 'Access-Control-Allow-Credentials' 'true';
if ($request_method = OPTIONS ) {
return 200;
}
proxy_pass http://deva_api;
proxy_set_header Connection "Keep-Alive";
proxy_set_header Proxy-Connection "Keep-Alive";
auth_basic "Restricted"; #For Basic Auth
auth_basic_user_file /etc/nginx/.htpasswd; #For Basic Auth
}
}
и здесь nginx.conf
конфигурация:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
worker_rlimit_nofile 65535;
events {
worker_connections 65535;
use epoll;
multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 120;
send_timeout 120;
types_hash_max_size 2048;
server_tokens off;
client_max_body_size 100m;
client_body_buffer_size 5m;
client_header_buffer_size 5m;
large_client_header_buffers 4 1m;
open_file_cache max=200000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
reset_timedout_connection on;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Проблема в том, что с этой конфигурацией я получаю сотни ошибок в error.log, например:
upstream prematurely closed connection while reading response header from upstream
но только на node2 и node3. Я уже пробовал следующие тесты:
Ничто не улучшает результат. В этих тестах я заметил, что ошибки были только на 2 удаленных узлах (node2 и node3), поэтому я попытался удалить их из уравнения. В результате я больше не получаю подобных ошибок, но у меня стали появляться две разные ошибки:
recv() failed (104: Connection reset by peer) while reading response header from upstream
и
writev() failed (32: Broken pipe) while sending request to upstream
Кажется, проблема была связана с отсутствием API на node1, API, вероятно, не могут ответить на весь входящий трафик до тайм-аута клиента (это было, я думаю). Сказал, что я увеличил количество параллельных API на node1, и результат был лучше, чем у предыдущих, но я продолжаю получать последние 2 ошибки, и я больше не могу увеличивать количество одновременных API на node1.
Итак, вопрос в том, почему я не могу использовать nginx в качестве балансировщика нагрузки со всеми моими узлами? Я делаю ошибки в конфигурации nginx? Есть ли другие проблемы, которых я не заметил?
РЕДАКТИРОВАТЬ: Я провожу несколько сетевых тестов между 3 узлами. Узлы общаются друг с другом через Openvpn:
ПИНГ:
node1->node2
PING 10.8.0.40 (10.8.0.40) 56(84) bytes of data.
64 bytes from 10.8.0.40: icmp_seq=1 ttl=64 time=2.85 ms
64 bytes from 10.8.0.40: icmp_seq=2 ttl=64 time=1.85 ms
64 bytes from 10.8.0.40: icmp_seq=3 ttl=64 time=3.17 ms
64 bytes from 10.8.0.40: icmp_seq=4 ttl=64 time=3.21 ms
64 bytes from 10.8.0.40: icmp_seq=5 ttl=64 time=2.68 ms
node1->node2
PING 10.8.0.30 (10.8.0.30) 56(84) bytes of data.
64 bytes from 10.8.0.30: icmp_seq=1 ttl=64 time=2.16 ms
64 bytes from 10.8.0.30: icmp_seq=2 ttl=64 time=3.08 ms
64 bytes from 10.8.0.30: icmp_seq=3 ttl=64 time=10.9 ms
64 bytes from 10.8.0.30: icmp_seq=4 ttl=64 time=3.11 ms
64 bytes from 10.8.0.30: icmp_seq=5 ttl=64 time=3.25 ms
node2->node1
PING 10.8.0.12 (10.8.0.12) 56(84) bytes of data.
64 bytes from 10.8.0.12: icmp_seq=1 ttl=64 time=2.30 ms
64 bytes from 10.8.0.12: icmp_seq=2 ttl=64 time=8.30 ms
64 bytes from 10.8.0.12: icmp_seq=3 ttl=64 time=2.37 ms
64 bytes from 10.8.0.12: icmp_seq=4 ttl=64 time=2.42 ms
64 bytes from 10.8.0.12: icmp_seq=5 ttl=64 time=3.37 ms
node2->node3
PING 10.8.0.40 (10.8.0.40) 56(84) bytes of data.
64 bytes from 10.8.0.40: icmp_seq=1 ttl=64 time=2.86 ms
64 bytes from 10.8.0.40: icmp_seq=2 ttl=64 time=4.01 ms
64 bytes from 10.8.0.40: icmp_seq=3 ttl=64 time=5.37 ms
64 bytes from 10.8.0.40: icmp_seq=4 ttl=64 time=2.78 ms
64 bytes from 10.8.0.40: icmp_seq=5 ttl=64 time=2.87 ms
node3->node1
PING 10.8.0.12 (10.8.0.12) 56(84) bytes of data.
64 bytes from 10.8.0.12: icmp_seq=1 ttl=64 time=8.24 ms
64 bytes from 10.8.0.12: icmp_seq=2 ttl=64 time=2.72 ms
64 bytes from 10.8.0.12: icmp_seq=3 ttl=64 time=2.63 ms
64 bytes from 10.8.0.12: icmp_seq=4 ttl=64 time=2.91 ms
64 bytes from 10.8.0.12: icmp_seq=5 ttl=64 time=3.14 ms
node3->node2
PING 10.8.0.30 (10.8.0.30) 56(84) bytes of data.
64 bytes from 10.8.0.30: icmp_seq=1 ttl=64 time=2.73 ms
64 bytes from 10.8.0.30: icmp_seq=2 ttl=64 time=2.38 ms
64 bytes from 10.8.0.30: icmp_seq=3 ttl=64 time=3.22 ms
64 bytes from 10.8.0.30: icmp_seq=4 ttl=64 time=2.76 ms
64 bytes from 10.8.0.30: icmp_seq=5 ttl=64 time=2.97 ms
Проверка пропускной способности через IPerf:
node1 -> node2
[ ID] Interval Transfer Bandwidth
[ 4] 0.0-10.0 sec 229 MBytes 192 Mbits/sec
node2->node1
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-10.0 sec 182 MBytes 152 Mbits/sec
node3->node1
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-10.0 sec 160 MBytes 134 Mbits/sec
node3->node2
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-10.0 sec 260 MBytes 218 Mbits/sec
node2->node3
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-10.0 sec 241 MBytes 202 Mbits/sec
node1->node3
[ ID] Interval Transfer Bandwidth
[ 4] 0.0-10.0 sec 187 MBytes 156 Mbits/sec
Кажется, что в туннеле OpenVPN есть узкое место, потому что тот же тест через eth
составляет около 1 Гбит. Сказал, что я следил за этим руководством community.openvpn.net но я получил только удвоенную пропускную способность, измеренную ранее.
Я хотел бы оставить OpenVPN включенным, поэтому есть ли какие-либо другие настройки, которые нужно сделать, чтобы увеличить пропускную способность сети или какие-либо другие изменения в конфигурации nginx, чтобы он работал должным образом?
Проблемы были вызваны медлительностью сети OpenVPN. Маршрутизируя запросы в Интернете после добавления аутентификации на каждом отдельном сервере, мы сократили количество ошибок до 1-2 в день и, вероятно, теперь вызваны некоторыми другими проблемами.