Tenho enfrentado problemas em meu aplicativo sob carga e depois de executar alguns testes de carga, percebi que quando carrego diretamente o teste do servidor de aplicativo http
em port 8080
, o servidor de aplicativo responde rapidamente.
Quando carrego o teste batendo no nome do domínio e usando https
, ou seja, o endoint que bati é https://load.api.example.in
, o tempo de resposta aumenta cerca de 5x.
Isso me leva à conclusão de que o haproxy intermediário é um gargalo.
Aumentei o tamanho do servidor para haproxy e, sob carga pesada, a utilização da CPU aumenta, mas por causa do servidor maior é de apenas cerca de 50%. (conforme monitoramento da AWS)
O que preciso alterar na configuração do haproxy (ou em qualquer outro lugar) para corrigir esse problema?
Minha configuração atual do 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
Tempos de resposta
- Com haproxy: média de mais de 3 segundos
- sem haproxy: média entre 500-600 ms
Atualizar:
Durante o teste, atualizei minha configuração do haproxy para encaminhar http para os mesmos back-ends que já estão configurados em https. Com essa mudança, meu teste de carga (via haproxy no http) foi executado assim como o teste de carga onde enviei todas as solicitações diretamente para o servidor.
Portanto, tenho quase certeza de que o problema (ou o maior problema de vários problemas) é a configuração SSL no haproxy. Alguma sugestão sobre o que devo tentar mudar para melhorar o desempenho?
Responder1
Como você já está usando AWS, use ELB+AWS Certificate Manager para fazer SSL para você. Execute o Haproxy no modo http e ignore o problema.
Ou comece a brincar com as seguintes opções do Haproxy:
tune.ssl.cachesize
tune.ssl.lifetime
ciphers
defer-accept
force-tlsv12
Tente também usar uma página estática no backend, de preferência no mesmo host. Para limitar o impacto dos aplicativos durante os testes.