Atualmente estou configurando uma máquina HAproxy para atuar como proxy reverso para alguns sites. Como as diferentes máquinas não estão conectadas fisicamente, estou usando o OpenVPN para criar uma VPN entre as máquinas.
Tecnicamente, tudo está funcionando. No entanto, meu problema é que as solicitações que canalizo pelo proxy são extremamente lentas. Eventualmente, recebo a(s) resposta(s) completa(s), mas leva até 5 minutos para receber algo como um painel do Jenkins.
Tentei uma página HTML estática simples servida via NGINX, bem como alguma API REST implementada em go - o resultado é sempre o mesmo: eventualmente obtenho os dados, mas leva um tempo ridículo.
Aqui está minha configuração do HAproxy:
global
log /var/run/log local0 info
log /var/run/log local0 notice
daemon
maxconn 8000
tune.ssl.default-dh-param 2048
user nobody
group nobody
defaults
log global
option httplog
option dontlognull
mode http
timeout connect 5s
timeout client 1min
timeout server 1min
option forwardfor
option http-server-close
errorfile 400 /usr/local/etc/haproxy/errorfiles/400.http
errorfile 403 /usr/local/etc/haproxy/errorfiles/403.http
errorfile 408 /usr/local/etc/haproxy/errorfiles/408.http
errorfile 500 /usr/local/etc/haproxy/errorfiles/500.http
errorfile 502 /usr/local/etc/haproxy/errorfiles/502.http
errorfile 503 /usr/local/etc/haproxy/errorfiles/503.http
errorfile 504 /usr/local/etc/haproxy/errorfiles/504.http
frontend http-in
bind *:80
bind *:443 ssl crt /usr/local/etc/haproxy/certs/foo.my.org.pem
mode http
use_backend jenkins if { hdr(host) -i foo.my.org }
use_backend test if { hdr(host) -i bar.my.org }
default_backend test
backend jenkins
server jenkins1 <vpn_ip>:8180
mode http
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
reqrep ^([^\ :]*)\ /(.*) \1\ /\2
acl response-is-redirect res.hdr(Location) -m found
rspirep ^Location:\ (http)://<vpn_ip>:8180/(.*) Location:\ https://foo.my.org:443/\2 if response-is-redirect
backend test
server web01 <vpn_ip>:80
Informações adicionais:
- Todas as máquinas envolvidas estão localizadas em data centers e possuem conexão de internet 1G/1G
- Todas as máquinas rodam FreeBSD 11 de 64 bits
- OpenVPN versão 2.4.4 em todas as máquinas
- HAproxy versão 1.7.9
- OpenVPN é executado em modo TCP
- A configuração de back-end do HAproxy para Jenkins é obtida conforme fornecido noDocumentação Jenkinsmas, como mencionado, o mesmo problema existe com um servidor web de conteúdo HTML estático e um serviço web REST API.
E aqui estão alguns logs do HAproxy ao acessar o site Jenkins:
Feb 27 01:32:24 hostname haproxy[5539]: 213.144.130.227:60243 [27/Feb/2018:01:32:24.093] http-in~ jenkins/jenkins1 0/0/13/134/161 302 153 - - ---- 5/5/0/0/0 0/0 "GET /jenkins HTTP/1.1"
Feb 27 01:32:24 hostname haproxy[5539]: 213.144.130.227:19404 [27/Feb/2018:01:32:24.255] http-in~ jenkins/jenkins1 0/0/25/174/212 200 4492 - - ---- 5/5/0/0/0 0/0 "GET /jenkins/ HTTP/1.1"
Feb 27 01:32:25 hostname haproxy[5539]: 213.144.130.227:16321 [27/Feb/2018:01:32:25.330] http-in~ jenkins/jenkins1 0/0/13/30/54 200 8560 - - ---- 6/6/4/4/0 0/0 "GET /jenkins/static/aeed77bb/scripts/yui/datasource/datasource-min.js HTTP/1.1"
Feb 27 01:32:25 hostname haproxy[5539]: 213.144.130.227:54637 [27/Feb/2018:01:32:25.330] http-in~ jenkins/jenkins1 0/0/27/29/58 200 7585 - - ---- 6/6/3/4/0 0/0 "GET /jenkins/static/aeed77bb/scripts/yui/autocomplete/autocomplete-min.js HTTP/1.1"Feb 27 01:32:25 hostname haproxy[5539]: 213.144.130.227:59247 [27/Feb/2018:01:32:25.361] http-in~ jenkins/jenkins1 0/0/25/16/51 200 9602 - - ---- 6/6/2/3/0 0/0 "GET /jenkins/static/aeed77bb/jsbundles/page-init.js HTTP/1.1"
Feb 27 01:32:25 hostname haproxy[5539]: 213.144.130.227:40637 [27/Feb/2018:01:32:25.332] http-in~ jenkins/jenkins1 0/0/38/18/81 200 16212 - - ---- 6/6/1/1/0 0/0 "GET /jenkins/static/aeed77bb/scripts/yui/menu/menu-min.js HTTP/1.1"
Feb 27 01:32:25 hostname haproxy[5539]: 213.144.130.227:10976 [27/Feb/2018:01:32:25.333] http-in~ jenkins/jenkins1 0/0/37/30/95 200 29110 - - ---- 6/6/0/0/0 0/0 "GET /jenkins/static/aeed77bb/scripts/hudson-behavior.js HTTP/1.1"
Não vejo mais nada nos arquivos de log. Sem erros ou similares.
Isso pode ser devido ao OpenVPN?
Editar 1:Enquanto isso, testei isso sem o OpenVPN, usando diretamente o endereço IP público do servidor web na configuração do HAproxy. O resultado é exatamente o mesmo.
Responder1
Seu log não inclui informações suficientes para explicar a espera de 5 minutos - ela dura menos de 2 segundos - mas aqui está o que chama a atenção:
option http-server-close
Isto não é apropriado com um back-end do outro lado de um link WAN. Se você realmente precisar desse recurso, ele precisará estar em um HAProxy com latência extremamente baixa (por exemplo, local) para o servidor back-end.
Observe a grande quantidade de instabilidade nos Tc
valores do temporizador. Este é o terceiro valor no campo de log que se parece com isto:
Tq/Tw/Tc/Tr/Tt
Portanto, na primeira entrada, 0/0/13/134/161
o Tc
valor é 13 ms. Tc
é o tempo necessário para estabelecer a conexão com o back-end, então o que vemos aqui é que seu jitter de ida e volta está praticamente fora de controle, saltando em um caso para quase três vezes esse valor. Supondo que isso não seja causado por recursos insuficientes no servidor back-end, é provável que seja uma consequência do uso do OpenVPN no modo TCP – possivelmente, mas não necessariamente, indicando alguma perda de pacotes.
Você está encapsulando TCP (HTTP) dentro de TCP (OpenVPN), o que geralmente é adequado para aplicativos não interativos e aplicativos onde o jitter não é importante, mas não de outra forma. (Veja, por exemplo,Por que TCP sobre TCP é uma má ideiapara discussão de um dos possíveis cenários de colapso, embora não seja motivo suficiente para evitar essa configuração inteiramente em uma rede limpa.) Pelo que presumo não ser culpa do OpenVPN, os túneis TCP não têm a mesma latência consistente que os túneis UDP. Faça ping através do túnel e você verá esse tremor transmitido aos tempos de resposta do ping.
Mude o túnel para UDP e o problema deverá desaparecer... mas observe que a importância e o impacto no desempenho desse tremor - assumindo que estou certo de que é um efeito colateral do uso de um túnel TCP - provavelmente é exagerado pelo uso de option http-server-close
, que requer que cada solicitação estabeleça uma nova conexão entre o HAProxy e o back-end.
Se seus túneis OpenVPN forem compactados usando comp-lzo
, considere desativá-lo também, pois a possível economia de custos no transporte pode ser compensada pela sobrecarga.
Responder2
Isso acabou sendo um problema com a configuração do firewall/NAT.
No entanto, se alguém se deparar com esse problema, há mais ajuda na comunidade HAproxy:https://discourse.haproxy.org/t/reverse-proxy-very-slow-page-load/2172