Erros 504 intermitentes com HAProxy

1

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?

    
por Pedro 28.09.2017 / 21:50

2 respostas

3

Acho que finalmente descobri. A solução consistia em aumentar os valores de timeout :

timeout connect 20s
timeout client  10m
timeout server  10m

Não sei por que aumentar os tempos limite de cliente / servidor de 2 minutos para 10 minutos resolveu o problema. Acredito que tenha algo a ver com keep-alive e o fato de que o HAProxy mantém conexões abertas com o S3 / Node.

Espero que isso ajude!

    
por 29.09.2017 / 02:31
2

Também acertei esse problema e acabou sendo um bug na v1.7.10:

link

Atualizar para a v1.7.11 + corrige o problema.

    
por 19.06.2018 / 12:22