Прерывистые ошибки 504 с HAProxy
Я боролся с этой проблемой в течение нескольких недель, и у меня заканчиваются идеи. Я запускаю HAProxy для запросов прокси среди 3 бэкэндов, основываясь на пути / заголовках запросов.
Мои бэкэнды:
- Ведро Amazon S3
- Приложение Node.js (2 сервера)
- Сервис под названием prerender.io
Последний бэкенд (prerender.io), кажется, имеет ноль проблем (хотя у него очень мало трафика). Два других возвращают клиенту 504 ошибки случайным образом (примерно каждую минуту в соответствии с журналами, но без четкой схемы).
Вот мой (продезинфицированный) конфиг:
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5s
timeout client 120s
timeout server 120s
frontend foobar
mode http
bind *:80
bind *:443 ssl crt /etc/ssl/certs/foobar.com.pem
redirect scheme https code 301 if !{ ssl_fc }
default_backend s3
acl api path_beg -i /api/
use_backend node if api
acl user-agent-bot hdr_sub(User-Agent) -i baiduspider twitterbot facebookexternalhit
use_backend prerender if user-agent-bot
backend s3
mode http
http-request set-path /index.html
reqirep ^Host: Host:\ my-bucket.s3-website-us-east-1.amazonaws.com
reqidel ^Authorization:.*
rspidel ^x-amz-id-2:.*
rspidel ^x-amz-request-id:.*
server s3 my-bucket.s3-website-us-east-1.amazonaws.com:80 check inter 5000
backend node
mode http
balance roundrobin
option forwardfor
server api01 1.2.3.4:3333 check
server api02 5.6.7.8:3333 check
backend prerender
mode http
server prerender service.prerender.io:443 check inter 5000 ssl verify none
http-request set-header X-Prerender-Token my-secret-token
reqrep ^([^\ ]*)\ /(.*)$ \1\ /https://app.wwoof.fr/\2
Я сам испытал эти 504 посещения сайта. Все, что мне нужно сделать, это обновить страницу, и она снова работает немедленно. Мне не нужно ждать 120 секунд (тайм-аут сервера), чтобы получить эти 504, они появляются сразу по запросу.
Пример (санированные) ошибки из журнала:
Sep 28 14:27:13 node/api01 0/0/1/-1/1 504 195 - - sR-- 38/38/30/14/0 0/0 "GET /api/hosts/2266 HTTP/1.1"
Sep 28 14:34:15 node/api02 0/0/0/-1/0 504 195 - - sR-- 55/55/41/25/0 0/0 "GET /api/hosts/4719 HTTP/1.1"
Sep 28 14:34:15 node/api01 0/0/1/-1/1 504 195 - - sR-- 54/54/41/16/0 0/0 "GET /api/hosts/2989 HTTP/1.1"
Sep 28 14:38:41 node/api01 0/0/1/-1/1 504 195 - - sR-- 50/50/47/25/0 0/0 "POST /api/users HTTP/1.1"
Sep 28 14:42:13 node/api02 0/0/1/-1/1 504 195 - - sR-- 134/134/102/49/0 0/0 "POST /api/users HTTP/1.1"
Sep 28 14:42:29 node/api02 0/0/1/-1/1 504 195 - - sR-- 130/130/105/51/0 0/0 "GET /api/hosts/1634 HTTP/1.1"
У меня есть похожие журналы для бэкенда s3. Я посмотрел в документы, чтобы понять, что sR
средства. Первый символ - это код, сообщающий о первом событии, которое привело к завершению сеанса:
s: истекло время ожидания на стороне сервера в ожидании отправки или получения сервером данных.
Второй символ указывает состояние сеанса TCP или HTTP, когда он был закрыт:
R: прокси ожидал полного, действительного ЗАПРОСА от клиента (только в режиме HTTP). Ничего не было отправлено ни на один сервер.
Это сочетание sR
не имеет смысла для меня. Как может истечь время ожидания сервера, если оно установлено на 120 с? И почему второе письмо относится к клиенту? Эти письма кажутся противоречивыми.
0/0/1/-1/1
часть представляет времена. Короче говоря, это говорит о том, что мы не ждем 120 секунд, это сразу дает сбой.
Бэкэнды как s3, так и Node.js имеют такую же проблему. Я имел дело с Nginx, и он работал нормально, поэтому я уверен, что эта проблема не имеет ничего общего с моим конфигом. Любой совет или предложение для отладки этого?
2 ответа
Я думаю, я наконец понял это. Решение состояло в увеличении timeout
ценности:
timeout connect 20s
timeout client 10m
timeout server 10m
Я не уверен, почему увеличение времени ожидания клиента / сервера с 2 минут до 10 минут решило проблему. Я считаю, что это как-то связано с keep-alive
и тот факт, что HAProxy поддерживает открытые соединения с S3/Node.
Надеюсь это поможет!
Я также затронул эту проблему, и она оказалась ошибкой в v1.7.10:
https://discourse.haproxy.org/t/intermittent-504-errors-and-sr-after-upgrade-to-1-7-10/2029
Обновление до v1.7.11+ устраняет проблему.