Erreurs 503 transitoires devant HAProxy

J’avais créé un forum de test avec deux conteneurs web_only, le conteneur mail-receiver, Postgres et Redis sur un réseau Docker. Les deux conteneurs web nginx étaient précédés par HAProxy. Ils fonctionnaient bien, mais j’ai constaté lors de la reconstruction de l’un des deux conteneurs web qu’il y avait toujours une courte période d’indisponibilité où un code 503 était retourné.

Heureusement, j’ai trouvé une solution palliative, mais rien de parfait ;


avant de reconstruire app1, exécutez

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

puis, une fois le processus de reconstruction de app1 terminé, exécutez

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

Inversement, pour reconstruire app2, exécutez

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

puis, une fois le processus de reconstruction de app2 terminé, exécutez

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

ceci est basé sur la correspondance de /etc/haproxy/haproxy.cfg concernant be_discourse, je ne collerai pas le fichier de configuration dans un bloc de code pour l’instant, mais si une masse critique le souhaite, je pourrais le faire.

ainsi, cela atténue le problème du 503 en indiquant à HAProxy de détourner le trafic avant qu’il ne sache qu’il y aurait un 503 du conteneur en panne.


vous pouvez alternativement créer une page d’erreur, mais je n’ai pas eu beaucoup de succès avec cela, et je pense que cela nécessite des recherches supplémentaires. Cependant, cela ne résout pas vraiment le problème de l’indisponibilité.

Pourquoi ne pas redistribuer vers le serveur suivant en cas de 503 ?

1 « J'aime »

Génial ! Ce serait bien. Avez-vous également des suggestions concernant Sidekiq ? Je ne vois pas du tout Sidekiq dans discourse_docker/samples at main · discourse/discourse_docker · GitHub, ce qui m’a amené à apporter les modifications suivantes à l’un ou l’autre fichier yml


app1.yml

## N'oubliez pas qu'il s'agit de la syntaxe YAML - vous ne pouvez avoir qu'un seul bloc portant un nom
run:
  - exec: echo "Début des commandes personnalisées"
+  - exec: rm -f /etc/service/sidekiq/down
  ## Si vous souhaitez configurer la connexion par mot de passe pour root, décommentez et modifiez :

app2.yml

## N'oubliez pas qu'il s'agit de la syntaxe YAML - vous ne pouvez avoir qu'un seul bloc portant un nom
run:
  - exec: echo "Début des commandes personnalisées"
+  - exec: bash -lc 'mkdir -p /etc/service/sidekiq && touch /etc/service/sidekiq/down'
  ## Si vous souhaitez configurer la connexion par mot de passe pour root, décommentez et modifiez :

Pour ceux qui exécutent plusieurs conteneurs web, un point supplémentaire à considérer est où Sidekiq s’exécute.

Les erreurs 503 n’affectent que les requêtes web, mais si Sidekiq est en panne, votre site cessera silencieusement de gérer les tâches d’arrière-plan (e-mails, résumés, badges, webhooks). Une façon élégante de gérer cela est de donner à Sidekiq son propre conteneur et de le désactiver sur les nœuds web.

Discourse utilise runit en interne : chaque service dans /etc/service/* démarre à moins qu’il n’y ait un fichier nommé down dans son répertoire. C’est tout le contrôle nécessaire.

Voici un exemple d’un worker Sidekiq dédié :

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

expose: []   # aucun port HTTP

env:
  DISCOURSE_DB_HOST: data
  DISCOURSE_REDIS_HOST: data
  DISCOURSE_HOSTNAME: "forum.example.com"
  # faire correspondre vos secrets existants / paramètres SMTP

hooks:
  after_code:
    - exec:
        cd: $home
        cmd:
          # désactiver les services web
          - mkdir -p /etc/service/puma  && touch /etc/service/puma/down
          - mkdir -p /etc/service/nginx && touch /etc/service/nginx/down
          # activer Sidekiq
          - rm -f /etc/service/sidekiq/down

run:
  - exec: echo "Démarrage du conteneur worker Sidekiq"

Sur les conteneurs web (app1/app2), il faut faire le contraire - garder Puma et Nginx activés, mais ajouter :

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

Avec cette configuration, HAProxy équilibre uniquement les conteneurs web, tandis que Sidekiq continue de s’exécuter dans le worker. De cette façon, les tâches d’arrière-plan ne sont pas interrompues lorsque vous reconstruisez ou faites pivoter vos nœuds web.

J’ai déplacé ceci dans Installation > Hosting car il semble s’agir d’une conversation ouverte. Évitons d’en créer dans Support.

1 « J'aime »