Eu tenho lutado com essa questão há semanas e estou ficando sem ideias. Eu corro HAProxy para solicitações de proxy entre 3 backends com base no caminho / cabeçalho dos pedidos.
Meus backends são:
- Um bucket do Amazon S3
- Um aplicativo Node.js (2 servidores)
- Um serviço chamado prerender.io
O último backend (prerender.io) parece ter zero problemas (embora tenha muito pouco tráfego). Os outros dois retornam erros 504 para o cliente aleatoriamente (a cada minuto, de acordo com os logs, mas sem padrão claro).
Aqui está minha configuração (sanitizada):
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 ^([^\ ]*)\ /(.*)$ \ /https://app.wwoof.fr/
Eu mesmo experimentei esses 504 visitando o site. Tudo o que preciso fazer é atualizar a página e ela funciona de novo imediatamente. Eu não tenho que esperar 120s (tempo limite do servidor) antes de obter os 504, eles aparecem imediatamente mediante solicitação.
Erros de amostra (higienizados) do log:
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"
Eu tenho logs semelhantes para o backend do s3. Eu olhei nos documentos para entender o que significa sR
. O primeiro caractere é um código que informa o primeiro evento que causou a finalização da sessão:
s : the server-side timeout expired while waiting for the server to send or receive data.
O segundo caractere indica o estado da sessão TCP ou HTTP quando foi fechado:
R : the proxy was waiting for a complete, valid REQUEST from the client (HTTP mode only). Nothing was sent to any server.
Esta combinação sR
não faz sentido para mim. Como o tempo limite do servidor pode expirar desde que esteja definido como 120s? E por que a segunda carta está se referindo ao cliente? Essas letras parecem contraditórias.
A parte 0/0/1/-1/1
representa os tempos. Longa história curta indica que não esperamos 120 segundos, falha imediatamente.
Ambos os backends s3 e Node.js têm exatamente o mesmo problema. Eu costumava liderar a coisa toda com o Nginx e estava funcionando bem, então estou confiante de que esse problema não tem nada a ver com a minha configuração. Algum conselho ou sugestão para depurar isso?