Ich hatte Probleme mit meiner App unter Last und nachdem ich einige Belastungstests ausgeführt hatte, stellte ich fest, dass der App-Server ziemlich schnell reagiert, wenn ich ihn direkt über http
Port einem Belastungstest unterziehe.8080
Wenn ich den Belastungstest durchführe, indem ich den Domänennamen eintreffe und verwende https
, d. h. der von mir getroffene Endint ist https://load.api.example.in
, erhöht sich die Reaktionszeit um etwa das Fünffache.
Dies führt mich zu dem Schluss, dass der dazwischen liegende Haproxy einen Engpass darstellt.
Ich habe die Servergröße für Haproxy erhöht und bei hoher Belastung kommt es zu Spitzenwerten bei der CPU-Auslastung, aber aufgrund des größeren Servers beträgt sie nur etwa 50 %. (gemäß AWS-Überwachung)
Was muss ich in der Haproxy-Konfiguration (oder anderswo) ändern, um dieses Problem zu beheben?
Meine aktuelle Haproxy-Konfiguration (anonymisiert)
global
ulimit-n 99999
maxconn 99999
maxpipes 99999
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
maxconn 4096
tune.ssl.default-dh-param 2048
chroot /var/lib/haproxy
user haproxy
group haproxy
daemon
defaults
log global
mode http
option httplog
option dontlognull
option forwardfor
option http-server-close
retries 3
option redispatch
maxconn 2000
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
frontend mqtt
bind *:1883
bind *:1884
mode tcp
option clitcpka # TCP Keep-alive
timeout client 3h
timeout server 3h
option tcplog
acl host_mqtt_staging hdr(host) -i staging.mqtt.example.in
acl host_mqtt_staging hdr(host) -i staging.mqtt.example.com
acl host_mqtt hdr(host) -i mqtt.example.in
acl host_mqtt hdr(host) -i mqtt.example.com
use_backend mqtt_staging if host_mqtt_staging
use_backend mqtt if host_mqtt
frontend http
bind *:80
mode http
reqadd X-Forwarded-Proto:\ http
redirect scheme https code 301 if !{ ssl_fc }
frontend https
bind *:443 ssl crt /etc/haproxy/certs/staging.myservice.example-2.com.pem
mode http
reqadd X-Forwarded-Proto:\ https
acl letsencrypt-acl path_beg /.well-known/acme-challenge/
acl host_myservice_staging hdr(host) -i staging.api.example.in
acl host_myservice_staging hdr(host) -i staging.api.example.com
acl host_myservice_load hdr(host) -i load.api.example.in
use_backend letsencrypt-backend if letsencrypt-acl
use_backend myservice_staging if host_myservice_staging
use_backend myservice_load if host_myservice_load
default_backend api
backend letsencrypt-backend
server letsencrypt 127.0.0.1:54321
backend api
balance roundrobin
option httpclose
option forwardfor
server web00 app00.staging.internal.example-2.com:8080 check
backend myservice_staging
balance roundrobin
option httpclose
option forwardfor
server myservice00 myservice00.staging.internal.example-2.com:8080 check weight 1
backend myservice_load
balance roundrobin
option httpclose
option forwardfor
server myserviceload00 load00.staging.internal.example-2.com:8080 check weight 1
backend mqtt_staging
balance leastconn
server mqttdev00 mqtt00.internal.example-2.com:1883 check
backend mqtt
balance leastconn
server prodmqttdev00 prodmqtt00.internal.example-2.com:1883 check
Reaktionszeit
- Mit Haproxy: Durchschnittlich über 3 Sekunden
- ohne Haproxy: Durchschnittlich zwischen 500 und 600 ms
Aktualisieren:
Während des Tests habe ich meine Haproxy-Konfiguration aktualisiert, um http an dieselben Backends weiterzuleiten, die bereits in https konfiguriert sind. Mit dieser Änderung wurde mein Belastungstest (über Haproxy auf http) genauso gut ausgeführt wie der Belastungstest, bei dem ich alle Anfragen direkt an den Server gesendet habe.
Daher bin ich ziemlich sicher, dass das Problem (oder das größte von mehreren Problemen) die SSL-Konfiguration in Haproxy ist. Irgendwelche Vorschläge, was ich versuchen sollte, zu ändern, um die Leistung zu verbessern?
Antwort1
Da Sie AWS bereits verwenden, nutzen Sie ELB+AWS Certificate Manager, um SSL für Sie durchzuführen. Führen Sie Haproxy im HTTP-Modus aus und ignorieren Sie das Problem.
Oder spielen Sie mit den folgenden Haproxy-Optionen:
tune.ssl.cachesize
tune.ssl.lifetime
ciphers
defer-accept
force-tlsv12
Versuchen Sie außerdem, eine statische Seite im Backend zu verwenden, vorzugsweise auf demselben Host. So begrenzen Sie die Auswirkungen auf die Anwendungen während des Tests.