Actualmente estoy configurando una máquina HAproxy para que actúe como proxy inverso para un par de sitios web. Como las diferentes máquinas no están conectadas físicamente, estoy usando OpenVPN para crear una VPN entre las máquinas.
Técnicamente, todo está funcionando. Sin embargo, mi problema es que las solicitudes que canalizo a través del proxy son extremadamente lentas. Eventualmente obtengo las respuestas completas, pero me lleva hasta 5 minutos recibir algo así como un panel de Jenkins.
Probé una página HTML estática simple servida a través de NGINX, así como alguna API REST implementada en go; el resultado es siempre el mismo: eventualmente obtengo los datos, pero lleva una cantidad de tiempo ridícula.
Aquí está mi configuración de 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
Información adicional:
- Todas las máquinas involucradas están ubicadas en centros de datos y cuentan con una conexión a Internet 1G/1G.
- Todas las máquinas ejecutan FreeBSD 11 de 64 bits.
- OpenVPN versión 2.4.4 en todas las máquinas
- HAproxy versión 1.7.9
- OpenVPN se ejecuta en modo TCP
- La configuración del backend de HAproxy para Jenkins se toma tal como se proporciona en eldocumentación de Jenkinspero como se mencionó, el mismo problema existe con un servidor web de contenido HTML estático y un servicio web REST API.
Y aquí hay un registro de HAproxy al acceder al sitio de 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"
No veo nada más en los archivos de registro. Sin errores o similares.
¿Puede esto deberse a OpenVPN?
Edición 1:Mientras tanto, probé esto sin OpenVPN usando directamente la dirección IP pública del servidor web en la configuración de HAproxy. El resultado es exactamente el mismo.
Respuesta1
Su registro no incluye suficiente información para explicar la espera de 5 minutos (dura menos de 2 segundos), pero esto es lo que salta a la vista:
option http-server-close
Esto no es apropiado con un servidor en el otro lado de un enlace WAN. Si realmente necesita esta función, debe estar en un HAProxy con una latencia extremadamente baja (por ejemplo, local) para el servidor back-end.
Tenga en cuenta la gran cantidad de fluctuación en Tc
los valores de su temporizador. Este es el tercer valor en el campo de registro que se ve así:
Tq/Tw/Tc/Tr/Tt
Entonces, en la primera entrada, 0/0/13/134/161
el Tc
valor es 13 ms. Tc
es el tiempo necesario para establecer la conexión con el back-end, por lo que lo que vemos aquí es que su fluctuación de ida y vuelta está prácticamente fuera de control, saltando en un caso a casi tres veces este valor. Suponiendo que esto no se deba a recursos insuficientes en el servidor back-end, es probable que sea una consecuencia del uso de OpenVPN en modo TCP, lo que posiblemente, pero no necesariamente, indique alguna pérdida de paquetes.
Estás haciendo un túnel TCP (HTTP) dentro de TCP (OpenVPN), lo que generalmente está bien para aplicaciones no interactivas y aplicaciones donde la fluctuación no es importante, pero no de otra manera. (Ver, por ejemplo,Por qué TCP sobre TCP es una mala ideapara discutir uno de los posibles escenarios de colapso, aunque no es razón suficiente para evitar esta configuración por completo en una red limpia). A través de lo que supongo que no es culpa de OpenVPN, los túneles TCP no tienen la misma latencia consistente que los túneles UDP. Haga ping a través del túnel y debería ver esta fluctuación impartida a los tiempos de respuesta del ping.
Cambie el túnel a UDP y el problema debería desaparecer... pero tenga en cuenta que la importancia y el impacto en el rendimiento de esta fluctuación (asumiendo que estoy en lo cierto en que es un efecto secundario del uso de un túnel TCP) probablemente se exagere al usar option http-server-close
, que Requiere que cada solicitud establezca una nueva conexión entre HAProxy y el back-end.
Si sus túneles OpenVPN están comprimidos usando comp-lzo
, considere deshabilitarlo también, ya que los posibles ahorros de costos en transporte pueden verse superados por los gastos generales.
Respuesta2
Esto resultó ser un problema con la configuración del firewall/NAT.
Sin embargo, si alguien se encuentra con este problema, hay más ayuda en la comunidad HAproxy:https://discourse.haproxy.org/t/reverse-proxy-very-slow-page-load/2172