Ich habe Probleme mit meinen Haproxy-Servern, die nach einem bestimmten Schwellenwert neue Verbindungen ablehnen (oder sie ablaufen lassen). Die Proxy-Server sind AWSc5.großEC2 mit 2 CPUs und 4 GB RAM. Die gleiche Konfiguration wird für beide Verbindungstypen auf unserer Site verwendet, wir haben eine für WebSocket-Verbindungen, die normalerweise zwischen2K bis 4Kgleichzeitige Verbindungen und eine Anfragerate von ca.10/s. Die andere ist für normalen Web-Verkehr mit nginx als Backend mit etwa400-500gleichzeitige Verbindungen und eine Anfragerate von ca.100-150/s. Die typische CPU-Auslastung für beide beträgt etwa3-5%auf dem Haproxy-Prozess, mit2-3%des für den WebSocket-Proxy verwendeten Speichers (40-60 MB) und1-3%des für den Webproxy verwendeten Speichers (30–40 MB).
Gemäß der angehängten Konfiguration werden die CPUs auf beide CPUs verteilt, wobei ein Prozess und zwei Threads ausgeführt werden. Beide Arten von Datenverkehr sind typischerweise zu 95 % (oder mehr) SSL-Datenverkehr. Ich habe die Proxy-Informationen mitwatch -n 1 'echo "Info anzeigen" | socat unix:/run/haproxy/admin.sock -'um zu sehen, ob ich an meine Grenzen stoße, was nicht der Fall zu sein scheint.
Zu Zeiten mit hohem Datenverkehr treten Probleme auf, wenn die Anzahl gleichzeitiger WebSocket-Verbindungen etwa5Kund die Web-Anforderungsrate steigt auf400 Anfragen/s. Ich erwähne beide Server hier, weil ich weiß, dass die Konfiguration die hohen gleichzeitigen Verbindungen und die hohe Anforderungsrate bewältigen kann, aber ich übersehe, dass ein anderes Ressourcenlimit erreicht wurde. Unter normalen Bedingungen funktioniert alles einwandfrei; die Probleme, die wir sehen, sind jedochERR_CONNECTION_TIMED_OUT(von Chrome) Typfehler. Ich sehe nie 502-Fehler. Auch sehe ich keinen anderen Prozess, der mehr CPU oder Speicher auf dem Server verwendet. Ich füge auch einige andere möglicherweise relevante Konfigurationen an, z. B. das Festlegen meiner Grenzwerte und Sysctl-Einstellungen.
Irgendwelche Ideen, was ich übersehen haben könnte? Lese ichSpitzeUndps aux | grep haproxyfalsch und sehe die falsche CPU-/Speicherauslastung? Übersehe ich ein TCP-Verbindungslimit? Die Backend-Server (nginx/websocket) werden bearbeitet, scheinen aber nie überlastet zu sein. Wir haben diese mit viel mehr Verbindungen und Verkehr einem Belastungstest unterzogen und werden durch den Proxy lange vor der Beschränkung der Backend-Server beschränkt.
Vielen Dank.
haproxy.cfg:
global
ulimit-n 300057
quiet
maxconn 150000
maxconnrate 1000
nbproc 1
nbthread 2
cpu-map auto:1/1-2 0-1
daemon
stats socket /run/haproxy/admin.sock mode 600 level admin
stats timeout 2m
log 127.0.0.1:514 local0
ca-base /etc/ssl/certs
crt-base /etc/ssl/private
ssl-default-bind-options no-sslv3 no-tlsv10
ssl-default-bind-ciphers kEECDH+aRSA+AES:kRSA+AES:+AES256:RC4-SHA:!kEDH:!LOW:!EXP:!MD5:!aNULL:!eNULL:!RC4
defaults
maxconn 150000
mode http
log global
option forwardfor
timeout client 30s
timeout server 120s
timeout connect 10s
timeout queue 60s
timeout http-request 20s
frontend default_proxy
option httplog
bind :80
bind :443 ssl crt /etc/haproxy/ssl.pem
... acl stuff which may route to a different backend
... acl for websocket traffic
use_backend websocket if websocket_acl
default_backend default_web
backend default_web
log global
option httpclose
option http-server-close
option checkcache
balance roundrobin
option httpchk HEAD /index.php HTTP/1.1\r\nHost:website.com
server web1 192.168.1.2:80 check inter 6000 weight 1
server web2 192.168.1.3:80 check inter 6000 weight 1
backend websocket
# no option checkcache
option httpclose
option http-server-close
balance roundrobin
server websocket-1 192.168.1.4:80 check inter 6000 weight 1
server websocket-2 192.168.1.5:80 check inter 6000 weight 1
Ausgabe vonhaproxy -vv:
HA-Proxy version 1.8.23-1ppa1~xenial 2019/11/26
Copyright 2000-2019 Willy Tarreau <[email protected]>
Build options :
TARGET = linux2628
CPU = generic
CC = gcc
CFLAGS = -O2 -g -O2 -fPIE -fstack-protector-strong -Wformat - Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -fno-strict-aliasing -Wdeclaration-after-statement -fwrapv -Wno-unused-label
OPTIONS = USE_GETADDRINFO=1 USE_ZLIB=1 USE_REGPARM=1 USE_OPENSSL=1 USE_LUA=1 USE_SYSTEMD=1 USE_PCRE2=1 USE_PCRE2_JIT=1 USE_NS=1
Default settings :
maxconn = 2000, bufsize = 16384, maxrewrite = 1024, maxpollevents = 200
Built with OpenSSL version : OpenSSL 1.0.2g 1 Mar 2016
Running on OpenSSL version : OpenSSL 1.0.2g 1 Mar 2016
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports : TLSv1.0 TLSv1.1 TLSv1.2
Built with Lua version : Lua 5.3.1
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
Encrypted password support via crypt(3): yes
Built with multi-threading support.
Built with PCRE2 version : 10.21 2016-01-12
PCRE2 library supports JIT : yes
Built with zlib version : 1.2.8
Running on zlib version : 1.2.8
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with network namespace support.
Available polling systems :
epoll : pref=300, test result OK
poll : pref=200, test result OK
select : pref=150, test result OK
Total: 3 (3 usable), will use epoll.
Available filters :
[SPOE] spoe
[COMP] compression
[TRACE] trace
Grenzen.conf:
* soft nofile 120000
* soft nproc 120000
sysctl.conf:
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_syncookies=1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.ip_local_port_range = 1024 65023
net.ipv4.tcp_max_syn_backlog = 50000
net.ipv4.tcp_max_tw_buckets = 400000
net.ipv4.tcp_max_orphans = 60000
net.ipv4.tcp_synack_retries = 3
net.core.somaxconn = 50000
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_no_metrics_save = 1
net.ipv4.tcp_moderate_rcvbuf = 1
net.core.netdev_max_backlog = 50000
fs.epoll.max_user_instances = 10000
Typisch bei Belastung mit 330 gleichzeitigen Verbindungen und 80 Anf./sps aux | grep haproxyAusgabe:
root 8122 4.5 1.2 159052 46200 ? Ssl Jan28 40:56 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -sf 29790
root 12893 0.0 0.3 49720 12832 ? Ss Jan21 0:00 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -sf 29790
und das Betriebssystem ist Ubuntu 16.04.
Antwort1
Es stellte sich heraus, dass die Antwort mir die ganze Zeit direkt ins Gesicht starrte. Ich hatte diemaxconnrateauf 1.000. AllerdingsZeige Infozeigte mir eine niedrigere Verbindungsrate zwischen 10 und 15 an, also dachte ich nicht, dass ich dieses Limit erreichen würde. Ich konnte nur maximal 500 Anfragen/s aufrechterhalten (bestätigt von meinen Backend-Servern), wobei jede Anfrage eine Verbindung zum Client und eine zweite zum Backend erforderte. Ich nutzte also 1.000 Verbindungen pro Sekunde.
Ich habe diese Beschränkung aufgehoben und konnte dadurch eine höhere Verbindungsrate aufrechterhalten.