Mise à jour en temps réel des sujets bloquée en cas de forte activité

Note : Je ne suis pas certain qu’il s’agisse d’un bug dans Discourse. J’ai tenté de rassembler les éléments de preuve nécessaires et, jusqu’à présent, je n’ai rien trouvé qui pointe vers notre infrastructure ou notre configuration. Notre configuration est aussi standard que possible sur Tappara.co.

Phénomène observé :

  • Les sujets de discussion rapides de type chat cessent de se mettre à jour automatiquement. Après un délai de 30 à 180 secondes, la mise à jour reprend généralement, révélant les messages publiés pendant le gel.

Ce que nous savons jusqu’à présent

  • Nous n’avons pas observé ce problème lors de la saison précédente, le dernier match ayant eu lieu en mars.
  • Nous utilisons la branche stable et avons effectué la dernière mise à jour majeure en août.
  • Le problème a été signalé immédiatement lors des premiers matchs d’exposition, avec un trafic/une activité modérés.
  • Cela affecte iOS et Chrome sur Android, mais est beaucoup moins fréquent sur Chromebook.
    • Au moment où j’écris ces lignes, je constate des gels sur mon téléphone Android, tandis que la discussion se déroule normalement sur mon Chromebook. Deux appareils différents sur le même réseau.
  • L’expérience varie selon l’utilisateur/le client. Différents utilisateurs signalent des gels à des moments différents. Dans l’ensemble, nous avons enregistré environ 300 messages en 30 minutes, et les utilisateurs ont signalé des dizaines de gels. La plupart du temps, les gels semblent corrélés à des événements dans le jeu (buts, pénalités).

Actions entreprises pour écarter certaines causes

  • CloudFlare : nous avons joué un match sans mise en cache CF, et le problème a persisté.
  • Surcharge du processeur : l’utilisation du CPU reste bien dans les limites, généralement autour de 20-30 %.
  • Épuisement du disque : les opérations d’E/S disque semblent bien dans les limites. Nous utilisons des SSD MaxIOPS d’UpCloud.

Autres informations

  • J’avais l’inspecteur Chrome en cours d’exécution pendant le match et certains codes 429 ont été enregistrés, mais pour moi, ils ne semblaient pas corrélés aux gels.
  • Les utilisateurs finaux ne reçoivent pas les notifications concernant les erreurs 429 (ralentissement) ou la charge extrême. La mise à jour se fige simplement, puis reprend. Le limiteur de débit a-t-il changé récemment ? J’ai l’impression que les limites de débit devraient déclencher un message dans l’interface utilisateur.

Un problème vraiment pénible qui nuit considérablement aux chats de match en temps réel. Nous organisons ces sessions depuis des années, et je n’ai jamais rien vu de tel auparavant.

Eh bien, ce n’est pas un bug, mais une fonctionnalité :sweat_smile:.

Lorsque vos web workers commencent à être submergés par les requêtes, nous introduisons des délais dans la connexion persistante qui met automatiquement à jour le sujet lorsque de nouveaux messages arrivent.

Si vous observez ce comportement et une utilisation faible du CPU comme indiqué, veuillez augmenter le nombre de workers unicorn, cela devrait résoudre ce problème.

Nous sommes déjà à 11 licornes, sur un VPS à 6 cœurs. Comme mentionné, cela ne s’est jamais produit lors de la saison précédente, la dernière en mars. Cela se produit maintenant même avec un trafic modéré. De plus, cela se produit beaucoup plus souvent sur un appareil mobile, en particulier Chrome sur Android, que sur un ordinateur de bureau.

Nous avons également réussi à saturer notre CPU auparavant (à la date limite des transferts commerciaux).

J’ai manqué un match en surveillant et en manipulant le serveur. Nous avons doublé les paramètres web.ratelimited, mais cela n’a pas résolu le problème.

L’inspecteur détecte un certain nombre de réponses 429 :

1. URL de la requête :

https://tappara.co/message-bus/3ed86765a67f4c31ba4053a0352ecaf5/poll

2. Méthode de la requête :

POST

3. Code d'état :

429

Le prochain match est demain, donc je peux essayer les licornes. Jusqu’où pouvons-nous aller ? Cela a-t-il changé avec la dernière mise à jour majeure ?

Édition :

J’ai examiné les statistiques, et notre activité jusqu’à présent est inférieure à celle observée au printemps (vues de pages, utilisateurs). Le nombre de publications par chat de match est identique (environ 900 à 1000 toutes les 3 heures).

Donc, pour une raison inconnue, nous ne sommes actuellement pas en mesure de servir le même public que celui que nous avions en mars.

Je travaille sur l’analyse de ce problème au cours des deux prochaines semaines ; cela prendra du temps pour l’améliorer.

Super ! Pourriez-vous confirmer s’il y a eu un changement ou une régression récente (6 derniers mois) à l’origine de ce problème ?

En attendant, je pense que je vais booster les licornes pour le match de ce soir et voir ce qui se passe. Si nous pouvons vous aider d’une quelconque manière, faites-le-moi savoir.

@falco Le nombre de licornes n’est absolument pas la clé. Je les ai portées à 15 pour la soirée de ce soir. Le sujet de la partie était calme, avec seulement 700 messages, mais des gels constants ont été observés. La charge du processeur était modérée, entre 5 et 25 %.

Plus j’enquête là-dessus, plus il semble probable qu’il s’agisse d’un problème et d’une régression, mais mes compétences ne sont pas suffisantes pour identifier l’origine du problème.

Je pense qu’il y a un bug dans le client qui l’empêche essentiellement de se mettre à jour après avoir rencontré une erreur. Je soupçonne que vous rencontrez ce problème parce que vos utilisateurs sont soumis à une limitation de débit.

Je vais enquêter cette semaine sur la possibilité de rendre le client plus robuste. Comme je l’ai dit plus tôt, il s’agit d’un code délicat qui prendra du temps.

Super. En attendant, je vais tester si la désactivation du limiteur global constitue une solution de contournement. Nous saurons cela mercredi.

Le débogage de ce problème m’a amené à réfléchir à l’expérience utilisateur (UX) d’une discussion en temps quasi réel en général. De nombreuses communautés traitent d’événements de la vie réelle, qui « poussent » naturellement la discussion vers une conversation rapide de type chat. Cela peut concerner la bourse, le lancement majeur d’un produit ou un jeu (eSport ou physique)… vous nommez-le.

Mais dans ce type de culture de discussion de type chat, la qualité des publications varie considérablement. D’un autre côté, les publications ont tendance naturelle à se produire exactement au même moment. Imaginons qu’un grand match de hockey se déroule et qu’un but soit marqué.

  • Une grande partie des publications ne sont que des réactions émotionnelles, des cris de joie ou des lamentations.
    • « Goooool !!! Yeah baby »
  • Certaines sont informatives :
    • « Crosby marque, 1-0 pour les Penguins »
  • Une petite minorité prend la peine de fournir une analyse :
    • « Crosby marque sur une échappée, après un effort de pressing avant négligent de la part des Capitals, mais cela ressemblait beaucoup à un hors-jeu. L’entraîneur des Capitals devrait contester cela. »

Maintenant, Discourse étant une plateforme rapide (temps quasi réel), cela signifie que même lorsque tout se déroule sans encombre, vous obtiendrez quelques dizaines de publications virtuellement au même moment exact. Pour le lecteur, en particulier celui qui ne regarde pas le match mais le suit dans le sujet de chat, cela pose un défi UX : il est difficile de repérer les publications informatives au milieu des cris de joie et des lamentations. Sur nos discussions de jeu du forum, on nous pose souvent la question « Quel est le score ? », car les personnes qui regardent le match oublient de poster l’évidence, ou l’information se perd dans la marée de messages.

Je ne sais pas comment cela fonctionnerait dans la vie réelle, mais il serait intéressant de tester si les administrateurs pourraient définir le rythme de la discussion. Par exemple, une publication par seconde. Toutes les publications seraient mises en file d’attente, mais publiées sur le site à un rythme défini. Si un but génère 20 publications de réaction, elles n’apparaîtraient pas dans le sujet en même temps, mais sur une fenêtre de temps de 20 secondes. Cela pourrait-il être plus facile à suivre et à capter les informations pertinentes ?

Cela pourrait bien sûr entraîner d’autres problèmes : si le rythme des nouveaux messages dépassait constamment le rythme de publication, il y aurait une file d’attente de plus en plus longue et le chat commencerait à prendre du retard par rapport au monde réel.

Je ne suis pas sûr que vous ayez saisi l’idée, et même moi je ne suis pas certain que cette idée soit bonne. En résumé, l’UX du chat en temps réel est un sujet de discussion intéressant et pourrait avoir un potentiel pour un développement ultérieur. Je comprends que l’objectif principal de Discourse n’est pas de créer une plateforme de chat — il existe d’autres logiciels pour cela. Mais ces situations se produisent naturellement.

J’aime bien cette idée, mais il faudrait une sorte de bannissement à l’envers pour que les gens voient toujours leurs propres publications immédiatement. Sinon, ils risquent de poster deux ou même trois fois, pensant que le forum ne fonctionne pas.

Je viens de fusionner ceci :

https://review.discourse.org/t/perf-backoff-background-requests-when-overloaded-10888/16227

Cela garantit que nous ne faisons pas tomber un serveur si 1 000 personnes consultent un même sujet et que des messages sont publiés.

Le client se comporte désormais beaucoup plus proprement dans ces cas.

Anticipant la question de @ljpp, je suis encore indécis quant au backporting : cela implique des modifications de l’API et constitue un changement assez important. Si nous procédons au backport, cela prendra probablement quelques semaines. Je dois observer cela en production sous charge, et comme nous avons très peu d’événements de ce type grâce à la marge dont nous disposons sur notre hébergement, il faudra du temps pour en capturer un.

Astuces Jedi :wink:

  • Nous allons essayer de voir si la désactivation du limiteur de débit est une solution de contournement viable.
  • Si oui : La prochaine version stable n’est pas trop loin, je suppose.
  • Si non, nous examinerons le canal Beta. Nous devrons vérifier que nos personnalisations de l’interface utilisateur ne sont pas compromises par la mise à jour.

Avez-vous d’autres communautés avec des discussions similaires de type chat et qui fonctionnent sur des branches edge ?

Je m’attends à une sortie d’ici la fin de l’année… donc je ne m’attendrais pas à ce que cela arrive très prochainement. Nous allons cependant publier une autre bêta cette semaine !

Tous nos services d’hébergement tournent sur la version bêta… donc oui, mais nous avons une capacité énorme.

Je comprends la logique selon laquelle cela pourrait ne pas être un candidat pour un backport. J’ai simplement désactivé notre ratelimiter et le prochain match aura lieu demain, nous aurons donc une idée assez précise de savoir si cela constitue une solution de contournement viable pour les instances qui ne souhaitent pas passer en version bêta.

Nous envisageons certainement de basculer sur la branche bêta pour les prochains mois. Cependant, il y a d’autres préoccupations : @rizka a souligné que la traduction FI est en retard (mais il pourrait peut-être y travailler plus tard cette semaine).

@sam

Malheureusement, désactiver le ratelimiter n’a absolument rien apporté. C’était un match ennuyeux et 83 utilisateurs n’ont posté que 580 messages. Plusieurs plantages ont été signalés pendant le match.

Y a-t-il des hacks ou des contournements potentiels à essayer en attendant la mise à niveau vers une version edge ?

Les « freezes » sont un bug côté client : il ne réagissait tout simplement pas correctement aux conditions d’erreur. Même une seule erreur de limite de débit et vous êtes fini sur la version stable.

Je ne vois pas de contournement possible, sauf passer à la version bêta (nous en sortons une nouvelle demain).

L’un de nos membres axé sur le développement a proposé d’ajuster la variable suivante. Qu’en pensez-vous ? Voyez-vous cela comme une solution de contournement potentielle ?

DISCOURSE_REJECT_MESSAGE_BUS_QUEUE_SECONDS : 0,2

Nous avons essayé le correctif :

DISCOURSE_REJECT_MESSAGE_BUS_QUEUE_SECONDS: 0.2

Cela a considérablement réduit le nombre de ralentissements observés, mais n’a pas résolu le problème. La charge CPU a augmenté, oscillant autour de 55 % lors des événements majeurs du jeu.

Des changements récents ont été apportés pour aider à résoudre les « gels » : le client reculera et attendra si le serveur est surchargé.

La solution ultime pourrait néanmoins consister à passer à un serveur plus puissant et à exécuter plus de processus Unicorn. Consultez le script discourse-setup pour nos recommandations concernant le rapport entre la capacité du serveur et le nombre de processus.

Je en doute… le problème sous une forte charge de réponses est qu’avant la nouvelle conception, nous pouvions provoquer une inondation déclenchant les limites de débit en raison de max_reqs_per_ip_per_10_seconds et autres. Il faudrait des ressources énormes pour gérer cette charge.

Réfléchissons.

  • 30 utilisateurs publient une réponse en 10 secondes
  • 100 personnes consultent le sujet.
  • Le serveur doit pouvoir gérer 3000 requêtes GET pour demander un seul message à la fois.
  • Si l’une quelconque de ces requêtes échoue pour une raison quelconque, l’interface utilisateur se figerait et semblerait cassée.

La nouvelle conception résout ce problème de manière très élégante : les requêtes reculent proprement, elles sont regroupées si nous avons un retard, l’interface ne se fige pas, etc.

Je ne vois pas comment l’ancienne conception pourrait passer à l’échelle avec 100 utilisateurs simultanés et 30 réponses en 10 secondes.

En revanche, je vois la conception actuelle révisée fonctionner parfaitement avec 1000 utilisateurs simultanés consultants un sujet avec 30 réponses en 10 secondes.