Sidekiq tem muitos erros e trabalhos em fila

Tivemos alguns avisos no console de administração sobre nossos trabalhos em fila do Sidekiq - temos quase 200.000 trabalhos enfileirados e não temos certeza de como resolver o problema. Estamos executando a versão 3.2.0.

Todos os trabalhos estão na fila ultra_low e parecem ser o trabalho Jobs::ProcessPost. Todos parecem ser semelhantes a isto:

	[{"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"}

Como podemos fazer esses trabalhos serem processados e como fazemos isso de uma forma que garanta que eles não impactem significativamente o desempenho (ou isso é inevitável)?

2 curtidas

Há dois dias, era cerca de 195 mil; agora está em 211 mil. Poderia realmente usar alguns conselhos sobre o que verificar e como resolver este problema.

Notamos 5 trabalhos inativos que se parecem com isto (endereços IP ofuscados):

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)

O endereço é de um servidor que está na infraestrutura, mas não é usado pelos fóruns (é um servidor de repositório de código-fonte). Não vejo em nenhum lugar na configuração onde este host é referenciado, então não tenho certeza por que ele acha que precisa se conectar a esse host. Mas me pergunto se isso está relacionado ao número crescente de trabalhos enfileirados na fila ultra_low.

2 curtidas

Mais 7.000 empregos adicionados à fila nas últimas ~23 horas.

Isso também está atrasando algumas alterações de implementação - fechamento automático e adição do plugin de soluções (apenas não quero fazer alterações que podem ou não ser afetadas por isso, ou quando isso pode ser agravado pela alteração de algo tão significativo na configuração do sistema).

Os 7.000 empregos adicionados não se alinham com quantos novos posts tivemos no último dia, então não tenho certeza do que está impulsionando isso.

Que outras informações seriam úteis para resolver esse problema?

2 curtidas

Não posso ajudar, exceto sugerindo que mais respostas e mais curtidas nas postagens neste tópico podem trazer a atenção que ele parece merecer!

Editar: Também mencionei este problema no tópico sobre a ordem padrão por popularidade, que, acho eu, está ocultando este tópico de forma muito eficaz e muito inútil.

2 curtidas

Você pode compartilhar o backtrace completo? Presumo que isso venha do nosso código onebox, mas gostaria de ter certeza.

3 curtidas

Presumo que tenhamos que fazer isso pelo console - terei que pedir a alguém com acesso para fazer isso; você pode me dizer de onde puxar para que eu possa passar para a pessoa com acesso?

Obrigado!

Não, não, o backtrace é exibido em uma aba na página /logs quando você seleciona o erro.

1 curtida

Ah, obrigado pela dica. Aqui está o que ele mostra (endereço IP ofuscado):

Mensagem (10 cópias relatadas)

Exceção do trabalho: Falha ao abrir conexão TCP para x.x.x.x:443 (Rede inacessível - connect(2) para "x.x.x.x" porta 443)


Backtrace

/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'

Notei que isso é diferente da saída na aba “backtrace”, mas essa saída não parece um backtrace, enquanto o que está aqui como uma cópia (usando o botão de cópia) parece. Me diga se outras informações são necessárias para esta.

Também verei se consigo obter mais informações sobre as mais de 220 mil tarefas enfileiradas dessa forma também - eu não sabia sobre o endpoint /logs.

Não há linhas extras na parte inferior do backtrace?

Isso foi tudo o que o botão Copiar pegou - aqui está a saída completa da guia 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'
/srv/www/vhosts/discourse/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'

Desculpe por não ter capturado a saída inteira. Achei estranho que o botão Copiar não tenha capturado mais, mas fiz uma suposição errada de que ele capturou o que era necessário.

Ah, isso é muito melhor!

Isso significa que há um ou mais links inline com um URL que resolve para o endereço IP do seu servidor. Se esse servidor não puder ser alcançado, registramos o erro, mas o processo de “cozimento” do markdown deve prosseguir sem fazer a “embelezamento de link” que o onebox inline acionaria.

Outra coisa é como você instalou o Discourse? Isso não parece uma instalação que seguiu nosso guia de instalação oficial.

2 curtidas

Eu, na verdade, não realizei a instalação - acredito que nossa equipe de infraestrutura a implementou usando um pipeline CI/CD, mas não sei os detalhes.

Parece que as mensagens falhadas não são um problema - o grande número de tarefas enfileiradas na fila ultra_low parece ser o problema maior aqui. Não estou encontrando nada nos logs (faz sentido para mim, na verdade, porque o job ainda não foi executado).

Se você forçar manualmente algumas a serem executadas, o que acontece?

Não vejo uma opção para forçá-los a serem executados na interface do usuário da web - tenho uma opção para “mostrar todos” os argumentos ou para excluir as tarefas individualmente.

Hm. Não temos nenhum em fila no fórum que eu ajudo a administrar, então peço desculpas por tentar sugerir um botão que não está lá.

Referência da página de novas tentativas, para o que eu pensei que estivesse na página em fila

Sem problemas - sim, estes aparecem na página Enqueued (em /sidekiq/queues/ultra_low).

Olhando para a própria página de filas, vejo que a latência da fila ultra_low é de cerca de um ano. Portanto, aparentemente isso está acontecendo há um tempo, e só recentemente recebemos um alerta sobre isso no painel.

1 curtida

Aprofundando um pouco mais no que vejo nos jobs Jobs::ProcessPost, parece que os valores de post_id estão contando regressivamente - extraí os IDs de post dos primeiros e últimos jobs na fila, e as datas correspondem a um post de 2012 (antes da migração para o Discourse - mas com um timestamp ‘updated_at’ de 2022, que pode ter sido a nossa data de migração - terei que verificar isso) e o mais recente foi de janeiro de 2023.

Vejo jobs ocasionais para gerar miniaturas de tópicos, mas eles são bem raros. Com mais de 8.800 páginas de fila, não consigo verificar tudo, mas parece que é principalmente material do Jobs::ProcessPost que está sendo adicionado, e está voltando no tempo através do que parece ser cada resposta e post inicial de um tópico (o mais antigo foi no meio de uma thread, o mais recente foi um post raiz em um tópico).

1 curtida

Fiz um backup do sistema de produção e o carreguei em um ambiente de teste configurado localmente. A fila não parece estar sendo preenchida – na verdade, não vejo o Job::ProcessPost aparecer nessa fila enquanto a observo (vou configurá-la e deixar o sistema rodar sozinho enquanto gravo a tela da fila para ver se estou apenas perdendo a entrada).

Isso me leva a duas perguntas:

  1. O que causa o acionamento do job ProcessPost?
  2. O que causaria a fila ultra_low a não ser processada?

Não sou especialista em nenhuma das tecnologias usadas no Discourse (redis, sidekiq ou rails), mas estou muito à vontade para aprender e experimentar em meu ambiente isolado para entender o que preciso que alguém verifique na produção.

A boa notícia é que esse problema não parece estar causando problemas para nossos usuários (ainda). Uma terceira pergunta seria se apenas limpar essa fila ajudaria, ou se não permitir que esses jobs rodem prejudicaria o sistema de alguma forma.

ETA: Acabei de ver um lote de jobs aparecer em meu ambiente de teste, e eles estão sendo processados lá. Portanto, parece apenas que a fila não está sendo processada no servidor de produção por algum motivo.

Parece que chegamos a uma resolução. A instalação que estamos usando é do pacote criado para openSUSE (a instância sobre a qual estamos falando é a instância para os fóruns do openSUSE) - então, essencialmente, está usando o processo de instalação “build from source”.

Temos um ambiente de desenvolvimento e produção, e a fila ultra_low foi equivocadamente excluída da configuração do sidekiq do ambiente de produção. Isso foi corrigido, e parece que a fila está esvaziando e a latência caiu de 1 ano para 4 semanas.

Acho que podemos considerar isso resolvido agora. Agradeço a contribuição das pessoas que forneceram algumas informações - isso me ajudou a encontrar o caminho certo para descobrir qual era o problema.

2 curtidas

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