Sidekiq a beaucoup d'erreurs et de tâches mises en file d'attente

Nous avons reçu des conseils dans la console d’administration concernant nos tâches mises en file d’attente Sidekiq - nous avons près de 200 000 tâches mises en file d’attente et nous ne savons pas comment résoudre le problème. Nous utilisons la version 3.2.0.

Les tâches sont toutes dans la file d’attente ultra_low et semblent être la tâche Jobs::ProcessPost. Elles ressemblent toutes à ceci :

	[{"bypass_bump"=true, "cooking_options"=nil, "new_post"=false, "post_id"=729508, "skip_pull_hotli... 
{"bypass_bump"=true, "cooking_options"=nil, "new_post"=false, "post_id"=729508, "skip_pull_hotlinked_images"=false, "current_site_id"="default"}

Comment pouvons-nous faire traiter ces tâches, et comment pouvons-nous le faire d’une manière qui garantisse qu’elles n’auront pas d’impact significatif sur les performances (ou est-ce inévitable) ?

2 « J'aime »

Il y a deux jours, c’était environ 195K ; maintenant, c’est jusqu’à 211K. J’aurais vraiment besoin de conseils sur ce qu’il faut examiner et comment résoudre ce problème.

Nous avons remarqué 5 jobs morts qui ressemblent à ceci (adresses IP obfusquées) :

Jobs::HandledExceptionWrapper: Wrapped Errno::ENETUNREACH: Failed to open TCP connection to x.x.x.x:443 (Network is unreachable - connect(2) for "x.x.x.x" port 443)

L’adresse correspond à un serveur qui fait partie de l’infrastructure mais qui n’est pas utilisé par les forums (c’est un serveur de dépôt de code source). Je ne vois nulle part dans la configuration où cet hôte est même référencé, donc je ne sais pas pourquoi il pense qu’il doit se connecter à cet hôte. Mais je me demande si cela est lié au nombre croissant de jobs mis en file d’attente dans la file d’attente ultra_low.

2 « J'aime »

7 000 emplois supplémentaires ont été ajoutés à la file d’attente au cours des dernières ~23 heures.

Cela retarde également quelques changements d’implémentation : fermeture automatique et ajout du plugin de solutions (je ne veux tout simplement pas apporter de modifications qui pourraient être affectées par cela, ou lorsque cela pourrait être aggravé par un changement aussi important dans la configuration du système).

Les 7 000 emplois ajoutés ne correspondent pas au nombre de nouveaux articles que nous avons eus au cours de la dernière journée, je ne suis donc pas sûr de ce qui motive cela.

Quelles autres informations seraient utiles pour résoudre ce problème ?

2 « J'aime »

Je ne peux qu’en suggérant que plus de réponses et plus de « j’aime » aux publications sur ce fil pourraient lui apporter l’attention qu’il mérite !

Modification : J’ai également mentionné ce problème dans le fil concernant le tri par défaut par « hotness », qui, je pense, cache ce fil très efficacement, et très inutilement.

2 « J'aime »

Pouvez-vous partager la trace complète ? Je suppose que cela provient de notre code onebox, mais j’aimerais en être sûr.

3 « J'aime »

Je suppose que nous devons le faire depuis la console - je devrai demander à quelqu’un qui y a accès de le faire ; pouvez-vous me dire d’où le récupérer afin que je puisse le transmettre à la personne qui y a accès ?

Merci !

Non, non, la trace de la pile s’affiche dans un onglet sur la page /logs lorsque vous sélectionnez l’erreur.

1 « J'aime »

Ah, merci pour l’indice. Voici ce qu’il montre (adresse IP obfusquée) :

Message (10 copies signalées)

Exception de tâche : Impossible d'ouvrir la connexion TCP à x.x.x.x:443 (Le réseau est inaccessible - connect(2) pour « x.x.x.x » port 443)


Trace

/usr/lib64/ruby/gems/3.2.0/gems/net-http-0.4.1/lib/net/http.rb:1603:in `initialize'
/usr/lib64/ruby/gems/3.2.0/gems/net-http-0.4.1/lib/net/http.rb:1603:in `open'
/usr/lib64/ruby/gems/3.2.0/gems/net-http-0.4.1/lib/net/http.rb:1603:in `block in connect'
/usr/lib64/ruby/gems/3.2.0/gems/timeout-0.4.1/lib/timeout.rb:186:in `block in timeout'
/usr/lib64/ruby/gems/3.2.0/gems/timeout-0.4.1/lib/timeout.rb:193:in `timeout'
/usr/lib64/ruby/gems/3.2.0/gems/net-http-0.4.1/lib/net/http.rb:1601:in `connect'
/srv/www/vhosts/discourse/lib/final_destination/http.rb:27:in `block in connect'
/srv/www/vhosts/discourse/lib/final_destination/http.rb:17:in `each'
/srv/www/vhosts/discourse/lib/final_destination/http.rb:17:in `each_with_index'
/srv/www/vhosts/discourse/lib/final_destination/http.rb:17:in `connect'

J’ai remarqué que c’est différent de la sortie de l’onglet « trace », mais cette sortie ne ressemble pas à une trace, alors que ce qui est ici en copie (en utilisant le bouton copier) en ressemble. Faites-moi savoir si d’autres informations sont nécessaires pour celle-ci.

Je vais également voir si je peux obtenir plus d’informations sur les plus de 220 000 tâches mises en file d’attente de cette manière également - j’ignorais l’existence du point de terminaison /logs.

Pas de lignes supplémentaires dans la partie inférieure de la trace d’appels ?

C’est tout ce que le bouton Copier a capturé - voici la sortie complète de l’onglet backtrace :

net-http-0.4.1/lib/net/http.rb:1603:in `initialize' 
net-http-0.4.1/lib/net/http.rb:1603:in `open' 
net-http-0.4.1/lib/net/http.rb:1603:in `block in connect' 
timeout-0.4.1/lib/timeout.rb:186:in `block in timeout' 
timeout-0.4.1/lib/timeout.rb:193:in `timeout' 
net-http-0.4.1/lib/net/http.rb:1601:in `connect' 
/srv/www/vhosts/discourse/lib/final_destination/http.rb:27:in `block in connect' 
/srv/www/vhosts/discourse/lib/final_destination/http.rb:17:in `each' 
/srv/www/vhosts/discourse/lib/final_destination/http.rb:17:in `each_with_index' 
/srv/www/vhosts/discourse/lib/final_destination/http.rb:17:in `connect' 
net-http-0.4.1/lib/net/http.rb:1580:in `do_start' 
net-http-0.4.1/lib/net/http.rb:1569:in `start' 
net-http-0.4.1/lib/net/http.rb:1029:in `start' 
/srv/www/vhosts/discourse/lib/final_destination.rb:551:in `safe_session' 
/srv/www/vhosts/discourse/lib/final_destination.rb:486:in `safe_get' 
/srv/www/vhosts/discourse/lib/final_destination.rb:170:in `get' 
/srv/www/vhosts/discourse/lib/retrieve_title.rb:90:in `fetch_title' 
/srv/www/vhosts/discourse/lib/retrieve_title.rb:12:in `crawl' 
/srv/www/vhosts/discourse/lib/inline_oneboxer.rb:76:in `lookup' 
/srv/www/vhosts/discourse/lib/cooked_processor_mixin.rb:310:in `process_inline_onebox' 
/srv/www/vhosts/discourse/lib/cooked_processor_mixin.rb:39:in `block in post_process_oneboxes' 
/srv/www/vhosts/discourse/lib/oneboxer.rb:214:in `block in apply' 
/srv/www/vhosts/discourse/lib/oneboxer.rb:162:in `block in each_onebox_link' 
nokogiri-1.16.0/lib/nokogiri/xml/node_set.rb:235:in `block in each' 
nokogiri-1.16.0/lib/nokogiri/xml/node_set.rb:234:in `upto' 
nokogiri-1.16.0/lib/nokogiri/xml/node_set.rb:234:in `each' 
/srv/www/vhosts/discourse/lib/oneboxer.rb:162:in `each_onebox_link' 
/srv/www/vhosts/discourse/lib/oneboxer.rb:213:in `apply' 
/srv/www/vhosts/discourse/lib/cooked_processor_mixin.rb:9:in `post_process_oneboxes' 
/srv/www/vhosts/discourse/lib/cooked_post_processor.rb:42:in `block in post_process' 
/srv/www/vhosts/discourse/lib/distributed_mutex.rb:53:in `block in synchronize' 
/srv/www/vhosts/discourse/lib/distributed_mutex.rb:49:in `synchronize' 
/srv/www/vhosts/discourse/lib/distributed_mutex.rb:49:in `synchronize' 
/srv/www/vhosts/discourse/lib/distributed_mutex.rb:34:in `synchronize' 
/srv/www/vhosts/discourse/lib/cooked_post_processor.rb:38:in `post_process' 
/srv/www/vhosts/discourse/app/jobs/regular/process_post.rb:28:in `block in execute' 
/srv/www/vhosts/discourse/lib/distributed_mutex.rb:53:in `block in synchronize' 
/srv/www/vhosts/discourse/lib/distributed_mutex.rb:49:in `synchronize' 
/srv/www/vhosts/discourse/lib/distributed_mutex.rb:49:in `synchronize' 
/srv/www/vhosts/discourse/lib/distributed_mutex.rb:34:in `synchronize' 
/srv/www/vhosts/discourse/app/jobs/regular/process_post.rb:8:in `execute' 
/srv/www/vhosts/discourse/app/jobs/base.rb:297:in `block (2 levels) in perform' 
rails_multisite-5.0.0/lib/rails_multisite/connection_management.rb:82:in `with_connection'
/srv/www/vhosts/discourse/app/jobs/base.rb:284:in `block in perform' 
/srv/www/vhosts/discourse/app/jobs/base.rb:280:in `each' 
/srv/www/vhosts/discourse/app/jobs/base.rb:280:in `perform' 
sidekiq-6.5.12/lib/sidekiq/processor.rb:202:in `execute_job' 
sidekiq-6.5.12/lib/sidekiq/processor.rb:170:in `block (2 levels) in process' 
sidekiq-6.5.12/lib/sidekiq/middleware/chain.rb:177:in `block in invoke' 
/srv/www/vhosts/discourse/lib/sidekiq/pausable.rb:132:in `call' 
sidekiq-6.5.12/lib/sidekiq/middleware/chain.rb:179:in `block in invoke' 
sidekiq-6.5.12/lib/sidekiq/middleware/chain.rb:182:in `invoke' 
sidekiq-6.5.12/lib/sidekiq/processor.rb:169:in `block in process' 
sidekiq-6.5.12/lib/sidekiq/processor.rb:136:in `block (6 levels) in dispatch' 
sidekiq-6.5.12/lib/sidekiq/job_retry.rb:113:in `local' 
sidekiq-6.5.12/lib/sidekiq/processor.rb:135:in `block (5 levels) in dispatch' 
sidekiq-6.5.12/lib/sidekiq/rails.rb:14:in `block in call' 
activesupport-7.0.8/lib/active_support/execution_wrapper.rb:92:in `wrap' 
activesupport-7.0.8/lib/active_support/reloader.rb:72:in `block in wrap' 
activesupport-7.0.8/lib/active_support/execution_wrapper.rb:92:in `wrap' 
activesupport-7.0.8/lib/active_support/reloader.rb:71:in `wrap' 
sidekiq-6.5.12/lib/sidekiq/rails.rb:13:in `call' 
sidekiq-6.5.12/lib/sidekiq/processor.rb:131:in `block (4 levels) in dispatch' 
sidekiq-6.5.12/lib/sidekiq/processor.rb:263:in `stats' 
sidekiq-6.5.12/lib/sidekiq/processor.rb:126:in `block (3 levels) in dispatch' 
sidekiq-6.5.12/lib/sidekiq/job_logger.rb:13:in `call' 
sidekiq-6.5.12/lib/sidekiq/processor.rb:125:in `block (2 levels) in dispatch' 
sidekiq-6.5.12/lib/sidekiq/job_retry.rb:80:in `global' 
sidekiq-6.5.12/lib/sidekiq/processor.rb:124:in `block in dispatch' 
sidekiq-6.5.12/lib/sidekiq/job_logger.rb:39:in `prepare' 
sidekiq-6.5.12/lib/sidekiq/processor.rb:123:in `dispatch' 
sidekiq-6.5.12/lib/sidekiq/processor.rb:168:in `process' 
sidekiq-6.5.12/lib/sidekiq/processor.rb:78:in `process_one' 
sidekiq-6.5.12/lib/sidekiq/processor.rb:68:in `run' 
sidekiq-6.5.12/lib/sidekiq/component.rb:8:in `watchdog' 
sidekiq-6.5.12/lib/sidekiq/component.rb:17:in `block in safe_thread' 

Désolé de ne pas avoir capturé la sortie complète. Je pensais qu’il était étrange que le bouton Copier n’ait pas capturé davantage, mais j’ai fait la mauvaise supposition qu’il avait capturé ce qui était nécessaire.

C’est beaucoup mieux !

Cela signifie qu’il y a un ou plusieurs liens inline avec une URL qui résout l’adresse IP de votre serveur. Si ce serveur ne peut pas être atteint, nous enregistrons l’erreur, mais le processus de traitement du markdown devrait se poursuivre sans effectuer la “mise en forme du lien” que le onebox inline déclencherait.

Une autre chose, comment avez-vous installé Discourse ? Cela ne ressemble pas à une installation qui a suivi notre guide d’installation officiel.

2 « J'aime »

Je n’ai pas effectué l’installation moi-même - je pense que notre équipe d’infrastructure l’a déployée à l’aide d’un pipeline CI/CD, mais je n’en connais pas les détails.

Il semble que les messages échoués ne soient pas un problème - le grand nombre de tâches mises en file d’attente dans la file d’attente ultra_low semble être le problème le plus important ici. Je ne trouve rien dans les journaux (ce qui est logique, en fait, car le travail n’a pas encore réellement été exécuté).

Si vous forcez manuellement quelques-unes à s’exécuter, que se passe-t-il ?

Je ne vois pas d’option pour les forcer à s’exécuter dans l’interface utilisateur Web - j’ai une option pour « tout afficher » les arguments, ou pour supprimer les tâches individuellement.

Hm. Nous n’en avons aucun en attente sur le forum que j’aide à gérer, je m’excuse donc d’avoir essayé de suggérer un bouton qui n’existe pas.

Référence de la page des nouvelles tentatives, pour ce que je pensais être sur la page en attente

Pas de souci - oui, ceux-ci apparaissent sur la page Enqueued (à /sidekiq/queues/ultra_low).

En regardant la page des files d’attente elle-même, je vois que la latence de la file d’attente ultra_low est d’environ un an. Donc, cela dure apparemment depuis un certain temps, et nous n’avons récemment reçu une alerte à ce sujet dans le tableau de bord.

1 « J'aime »

En approfondissant un peu ce que je vois dans les tâches Jobs::ProcessPost, il semble que les valeurs post_id décomptent. J’ai extrait les ID de publication des premières et dernières tâches de la file d’attente, et les dates correspondent à une publication de 2012 (avant la migration vers Discourse - mais avec un horodatage ‘updated_at’ de 2022, ce qui pourrait être notre date de migration - je devrai vérifier cela) et la plus récente date de janvier 2023.

Je vois des tâches occasionnelles pour générer des miniatures de sujets, mais elles sont assez rares. Avec plus de 8 800 pages de file d’attente, je ne peux pas tout vérifier, mais il semble que ce soit principalement des tâches Jobs::ProcessPost qui sont ajoutées, et elles remontent dans le temps à travers ce qui ressemble à chaque réponse et publication initiale d’un sujet (la plus ancienne était au milieu d’un fil, la plus récente était une publication racine dans un sujet).

1 « J'aime »

J’ai extrait une sauvegarde du système de production et l’ai chargée dans un environnement de test configuré localement. La file d’attente ne semble pas s’accumuler du tout - en fait, je ne vois pas Job::ProcessPost apparaître dans cette file d’attente lorsque je la surveille (je vais la configurer et laisser le système fonctionner tout seul tout en enregistrant l’écran de la file d’attente pour voir si je la manque).

Cela m’amène à deux questions :

  1. Qu’est-ce qui déclenche le job ProcessPost ?
  2. Qu’est-ce qui pourrait empêcher la file d’attente ultra_low d’être traitée ?

Je ne suis pas un expert des technologies utilisées dans Discourse (redis, sidekiq ou rails), mais je suis très à l’aise pour apprendre et essayer des choses dans mon environnement sandbox afin de comprendre ce que je dois faire examiner en production.

La bonne nouvelle est que ce problème ne semble pas causer de problèmes à nos utilisateurs (pour l’instant). Une troisième question serait de savoir si simplement purger cette file d’attente aiderait, ou si ne pas autoriser ces jobs à s’exécuter nuirait au système d’une manière ou d’une autre.

ETA : Je viens de voir un lot de jobs apparaître dans mon environnement de test, et ils sont en cours de traitement. Il semble donc que la file d’attente ne soit pas traitée sur le serveur de production pour une raison quelconque.

Il semble que nous ayons trouvé une solution. L’installation que nous utilisons provient du paquet conçu pour openSUSE (l’instance dont nous parlons est l’instance pour les forums openSUSE) - elle utilise donc essentiellement le processus d’installation « compilation à partir des sources ».

Nous avons un environnement de développement et de production, et la file d’attente ultra_low a été exclue par erreur de la configuration sidekiq de l’environnement de production. Cela a été corrigé, et il semble que la file d’attente se vide, et la latence est tombée de 1 an à 4 semaines.

Je pense que nous pouvons considérer cela comme résolu maintenant. J’apprécie les contributions des personnes qui en ont fourni - cela m’a aidé à trouver la bonne piste pour déterminer quel était le problème.

2 « J'aime »

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.