503 transitorios cuando está respaldado por HAProxy

Había creado un foro de prueba con dos contenedores web_only, el contenedor mail-receiver, Postgres y Redis en una red Docker. Los dos contenedores web nginx estaban precedidos por HAProxy. Funcionaron bien, pero descubrí que al reconstruir uno de los dos contenedores web siempre había una pequeña cantidad de tiempo de inactividad donde se devolvía 503.

Afortunadamente, encontré una solución mitigadora, pero nada perfecta;


antes de reconstruir app1, ejecuta

echo \"disable server be_discourse/app1\" | socat stdio /run/haproxy/admin.sock

y luego, una vez finalizado el proceso de reconstrucción de app1, ejecuta

echo \"enable server be_discourse/app1\" | socat stdio /run/haproxy/admin.sock

Viceversa, para reconstruir app2 ejecuta

echo \"disable server be_discourse/app2\" | socat stdio /run/haproxy/admin.sock

y luego, una vez finalizado el proceso de reconstrucción de app2, ejecuta

echo \"enable server be_discourse/app1\" | socat stdio /run/haproxy/admin.sock

esto se basa en que /etc/haproxy/haproxy.cfg coincide con respecto a be_discourse, aún no pegaré el archivo de configuración en un bloque de código, pero si una masa crítica lo desea, podría hacerlo.

así que esto mitiga el 503 al decirle a HAProxy que desvíe el tráfico antes de que sepa que habría un 503 del contenedor que está caído.


alternativamente, puedes crear una página de error, pero no tuve mucha suerte con eso y siento que necesita más investigación. Sin embargo, esto realmente no soluciona el problema del tiempo de inactividad.

¿Por qué no redespachas al siguiente servidor en un 503?

1 me gusta

¡genial! eso estaría bien. Además, ¿tienes alguna sugerencia sobre sidekiq? No veo sidekiq en absoluto en discourse_docker/samples at main · discourse/discourse_docker · GitHub, lo que me llevó a hacer los siguientes cambios en yml


app1.yml

## Recuerda, esto es sintaxis YAML - solo puedes tener un bloque con un nombre
run:
  - exec: echo "Beginning of custom commands"
+  - exec: rm -f /etc/service/sidekiq/down
  ## Si quieres configurar el inicio de sesión con contraseña para root, descomenta y cambia:

app2.yml

## Recuerda, esto es sintaxis YAML - solo puedes tener un bloque con un nombre
run:
  - exec: echo "Beginning of custom commands"
+  - exec: bash -lc 'mkdir -p /etc/service/sidekiq && touch /etc/service/sidekiq/down'
  ## Si quieres configurar el inicio de sesión con contraseña para root, descomenta y cambia:

Para cualquiera que ejecute varios contenedores web, una consideración adicional es dónde se ejecuta Sidekiq.

Los errores 503 solo afectan a las solicitudes web, pero si Sidekiq deja de funcionar, tu sitio dejará de procesar trabajos en segundo plano de forma silenciosa (correos electrónicos, resúmenes, insignias, webhooks). Una forma elegante de manejar esto es darle a Sidekiq su propio contenedor y mantenerlo deshabilitado en los nodos web.

Discourse utiliza runit internamente: cada servicio en /etc/service/* se inicia a menos que haya un archivo llamado down dentro de su directorio. Ese es todo el control que se necesita.

Aquí tienes un ejemplo de un trabajador Sidekiq dedicado:

worker.yml — Solo Sidekiq
templates:
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/sshd.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"

expose: []   # sin puertos HTTP

env:
  DISCOURSE_DB_HOST: data
  DISCOURSE_REDIS_HOST: data
  DISCOURSE_HOSTNAME: "forum.example.com"
  # coincide con tus secretos existentes / configuraciones SMTP

hooks:
  after_code:
    - exec:
        cd: $home
        cmd:
          # deshabilitar servicios web
          - mkdir -p /etc/service/puma  && touch /etc/service/puma/down
          - mkdir -p /etc/service/nginx && touch /etc/service/nginx/down
          # habilitar Sidekiq
          - rm -f /etc/service/sidekiq/down

run:
  - exec: echo "Iniciando contenedor trabajador Sidekiq"

En los contenedores web (app1/app2), se debe hacer lo contrario: mantener Puma y Nginx habilitados, pero agregar:

hooks:
  after_code:
    - exec:
        cd: $home
        cmd:
          - mkdir -p /etc/service/sidekiq && touch /etc/service/sidekiq/down

Con esta configuración, HAProxy equilibra solo los contenedores web, mientras que Sidekiq sigue funcionando en el trabajador. De esa manera, los trabajos en segundo plano no se interrumpen cuando reconstruyes o rotas tus nodos web.

He movido esto a Installation > Hosting ya que parece ser una conversación abierta. Evitemos crear estas en Support.

1 me gusta