He estado enfrentando problemas en mi aplicación bajo carga y después de ejecutar algunas pruebas de carga, me di cuenta de que cuando cargo directamente la prueba del servidor de aplicaciones http
en el puerto 8080
, el servidor de aplicaciones responde con bastante rapidez.
Cuando cargo la prueba presionando el nombre de dominio y usando https
, es decir, el endoint que presiono es https://load.api.example.in
, el tiempo de respuesta aumenta aproximadamente 5 veces.
Esto me lleva a la conclusión de que el haproxy intermedio es un cuello de botella.
Aumenté el tamaño del servidor para haproxy y, bajo carga pesada, la utilización de la CPU aumenta, pero debido al servidor más grande es solo alrededor del 50%. (según el monitoreo de AWS)
¿Qué necesito cambiar en la configuración de haproxy (o en cualquier otro lugar) para solucionar este problema?
Mi configuración actual de haproxy (anonimizada)
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
Tiempos de respuesta
- Con haproxy: promedio de más de 3 segundos
- sin haproxy: promedio de entre 500 y 600 ms
Actualizar:
Mientras realizaba las pruebas, actualicé mi configuración de haproxy para reenviar http a los mismos servidores que ya están configurados en https. Con este cambio, mi prueba de carga (a través de haproxy en http) funcionó tan bien como la prueba de carga donde envié todas las solicitudes directamente al servidor.
Por lo tanto, estoy bastante seguro de que el problema (o el mayor problema de varios problemas) es la configuración SSL en haproxy. ¿Alguna sugerencia sobre lo que debería intentar cambiar para mejorar el rendimiento?
Respuesta1
Como ya está utilizando AWS, utilice ELB+AWS Certificate Manager para realizar SSL por usted. Ejecute Haproxy en modo http e ignore el problema.
O empieza a jugar con las siguientes opciones de Haproxy:
tune.ssl.cachesize
tune.ssl.lifetime
ciphers
defer-accept
force-tlsv12
Intente también utilizar una página estática en el backend, preferiblemente en el mismo host. Limitar el impacto de las aplicaciones durante las pruebas.