Configuración HAProxy: ¿estoy haciendo algo mal?

Configuración HAProxy: ¿estoy haciendo algo mal?

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 httpen 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.

información relacionada