1 votes

Nginx load balancing mauvaise configuration ou mauvais comportement ?

J'utilise actuellement Nginx comme répartiteur de charge afin d'équilibrer le trafic réseau entre 3 nœuds sur lesquels tourne une API NodeJS.

L'instance Nginx fonctionne sur le nœud 1 et chaque requête est adressée au nœud 1. J'ai un pic de requêtes d'environ 700k en 2 heures et nginx est configuré pour les basculer, de manière circulaire, entre node1, node2 et node3. Ici le 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
        }
}

et ici le nginx.conf configuration :

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/*;
}

Le problème est qu'avec cette configuration, j'obtiens des centaines d'erreurs dans le fichier error.log, comme celles qui suivent :

upstream prematurely closed connection while reading response header from upstream

mais seulement sur les nœuds 2 et 3. J'ai déjà effectué les tests suivants :

  1. augmenter le nombre d'API concurrentes dans chaque nœud (en fait, j'utilise PM2 comme équilibreur intra-nœud)
  2. supprimer un nœud afin de faciliter le travail de nginx
  3. poids appliqués à nginx

Rien n'améliore le résultat. Dans ces tests, j'ai remarqué qu'il y avait des erreurs uniquement sur les 2 nœuds distants (node2 et node3), j'ai donc essayé de les supprimer de l'équation. Le résultat est que je n'ai plus d'erreurs comme celle-là mais j'ai commencé à avoir 2 erreurs différentes :

recv() failed (104: Connection reset by peer) while reading response header from upstream

et

writev() failed (32: Broken pipe) while sending request to upstream

Il semble que le problème soit dû à l'absence d'API sur node1, les API ne peuvent probablement pas répondre à tout le trafic entrant avant le timeout du client (c'était, c'est, mon hypothèse). Cela dit, j'ai augmenté le nombre d'API concurrentes sur node1 et le résultat était meilleur que les précédents, mais je continue à obtenir les 2 dernières erreurs et je ne peux plus augmenter le nombre d'API concurrentes sur node1.

La question est donc de savoir pourquoi je ne peux pas utiliser nginx comme équilibreur de charge avec tous mes nœuds ? Est-ce que je fais des erreurs dans la configuration de nginx ? Y a-t-il d'autres problèmes que je n'ai pas remarqués ?

EDIT : J'effectue des tests de réseau entre 3 nœuds. Les nœuds communiquent entre eux via Openvpn :

PING :

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

Vérification de la bande passante, via 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

Il semble qu'il y ait un goulot d'étranglement dans le tunnel OpenVPN car le même test via eth est d'environ 1Gbits. Cela dit, j'ai suivi ce guide community.openvpn.net mais je n'ai obtenu que le double de la bande passante mesurée auparavant.

J'aimerais conserver OpenVPN, y a-t-il d'autres réglages à faire pour augmenter la bande passante du réseau ou d'autres ajustements à la configuration de nginx pour qu'il fonctionne correctement ?

1voto

Dege Points 126

Les problèmes étaient dus à la lenteur du réseau OpenVPN. En acheminant les demandes sur l'internet après l'ajout des authentifications sur chaque serveur différent, nous avons réduit les erreurs à 1 ou 2 par jour et elles sont probablement dues à d'autres problèmes maintenant.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X