HAproxy простой обратный прокси очень медленный

HAproxy простой обратный прокси очень медленный

В настоящее время я настраиваю машину HAproxy, которая будет работать как обратный прокси для пары веб-сайтов. Поскольку разные машины физически не соединены, я использую OpenVPN для создания VPN между машинами.

Технически все работает. Однако моя проблема в том, что запросы, которые я передаю через прокси, чрезвычайно медленные. В конце концов я получаю полный ответ(ы), но требуется до 5 минут, чтобы получить что-то вроде панели мониторинга Jenkins.

Я пробовал простую статическую HTML-страницу, обслуживаемую через NGINX, а также некоторые REST API, реализованные в Go, — результат всегда один и тот же: в конечном итоге я получаю данные, но это занимает невероятно много времени.

Вот моя конфигурация 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

Дополнительная информация:

  • Все задействованные машины расположены в центрах обработки данных и имеют подключение к Интернету 1G/1G.
  • На всех машинах установлена ​​FreeBSD 11 64-Bit.
  • OpenVPN версии 2.4.4 на всех машинах
  • HAproxy версии 1.7.9
  • OpenVPN работает в режиме TCP
  • Конфигурация бэкэнда HAproxy для Jenkins взята изДокументация ДженкинсаНо, как уже упоминалось, та же проблема существует и с веб-сервером с чистым статическим HTML-контентом, и с веб-сервисом REST API.

А вот лог HAproxy при доступе к сайту 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"
Больше ничего в лог-файлах не вижу. Никаких ошибок или чего-то подобного.

Может ли это быть связано с OpenVPN?

Редактировать 1:В то же время я протестировал это без OpenVPN, напрямую используя публичный IP-адрес веб-сервера в конфигурации HAproxy. Результат точно такой же.

решение1

В вашем журнале недостаточно информации, чтобы объяснить 5-минутное ожидание — оно длится менее 2 секунд — но вот что бросается в глаза:

option http-server-close

Это не подходит для бэкенда на другой стороне WAN-соединения. Если вам действительно нужна эта функция, она должна быть на HAProxy с чрезвычайно низкой задержкой (например, локальной) для бэкенд-сервера.

Обратите внимание на большое количество колебаний в Tcзначениях таймера. Это третье значение в поле журнала, которое выглядит так:

Tq/Tw/Tc/Tr/Tt

Итак, в первой записи, 0/0/13/134/161значение Tcравно 13 мс. Tc— это время, необходимое для установления соединения с бэкендом, поэтому мы видим, что ваш джиттер круговой задержки практически вышел из-под контроля, подскочив в одном случае почти в три раза от этого значения. Если предположить, что это не вызвано недостатком ресурсов на бэкенд-сервере, то это, скорее всего, следствие использования OpenVPN в режиме TCP — возможно, но не обязательно, что указывает на некоторую потерю пакетов.

Вы туннелируете TCP (HTTP) внутри TCP (OpenVPN), что обычно подходит для неинтерактивных приложений и приложений, где джиттер не важен, но не в других случаях. (См., например,Почему TCP через TCP — плохая идеядля обсуждения одного из возможных сценариев сбоя, хотя это не достаточная причина, чтобы полностью избегать этой конфигурации в чистой сети.) По причине того, что, как я предполагаю, не является ошибкой OpenVPN, туннели TCP не имеют такой же постоянной задержки, как туннели UDP. Пингуйте через туннель, и вы должны увидеть этот джиттер, привнесенный во время ответа пинга.

Измените туннель на UDP, и проблема должна исчезнуть... но учтите, что значимость и влияние этого дрожания на производительность (если я прав, что это побочный эффект использования туннеля TCP) вероятно преувеличены из-за использования option http-server-close, которое требует, чтобы каждый запрос устанавливал новое соединение между HAProxy и бэкэндом.

Если ваши туннели OpenVPN сжимаются с помощью comp-lzo, то рассмотрите возможность отключения и этого, поскольку потенциальная экономия на транспорте может быть перевешена накладными расходами.

решение2

Оказалось, что проблема была в конфигурации брандмауэра/NAT.

Однако, если кто-то столкнется с этой проблемой, в сообществе HAproxy есть дополнительная помощь:https://discourse.haproxy.org/t/reverse-proxy-very-slow-page-load/2172

Связанный контент