Existe uma maneira de enviar notificações por e-mail mais rapidamente?

Temos uma categoria #Announcements na qual todos os nossos membros são automaticamente inscritos para acompanhar a primeira postagem.

Isso nos permite agendar a publicação de posts nessa categoria em horários/datas definidos.

Por sua vez, o anúncio é enviado por e-mail para cerca de 25 mil membros.

O problema que enfrentamos é que os e-mails levam mais de uma hora para serem enviados, o que não é ideal para anúncios críticos em termos de tempo.

Se eu observar o Sidekiq, posso ver o contador “Scheduled” acumulando todos os e-mails individuais, um por um. Quando chega a cerca de 20.000, ele os move para a aba “Enqueued” e, eventualmente, eles começam a ser enviados.

Posso acelerar esse processo de alguma forma? :thinking:

Para e-mails críticos em termos de tempo, seria bom enviá-los cerca de 100 vezes mais rápido do que atualmente :blush:

Esta discussão pode ajudá-lo, pois explica como definir DISCOURSE_MAX_DIGESTS_ENQUEUED_PER_30_MINS_PER_SITE, que define o limite global para resumos.

2 curtidas

Eu cronometrei esta noite.

Agendei uma postagem para ser publicada na categoria #Announcements às 18:30.


Às 18:40, havia 15.000 e-mails na fila Scheduled.


Às 18:45, ou seja, 15 minutos após a postagem, havia 22.000 e-mails na fila Scheduled.


Às 18:48, esses e-mails começaram a se mover gradualmente para a fila Enqueued:


Às 18:51, eles ainda estavam se movendo:


Às 19:03, os e-mails estavam a caminho:


Às 19:10, restavam apenas 10.000 e-mails:


Às 19:27, restavam apenas 569 e-mails:


E às 19:29, todos os e-mails haviam sido enviados:


Então aí está, uma hora completa para enviar 22.000 notificações por e-mail.

Alguém pode me ajudar a identificar o gargalo aqui?

Eu gostaria muito de poder enviar esses e-mails mais rápido do que a taxa atual de 22.000 por hora.

Chutando,
É possível que seja um problema de carga na infraestrutura?

1 curtida

Talvez?

Eu realmente não sei :person_shrugging:
A CPU disparou para cerca de 44% no servidor:

E eu uso AWS SES para o SMTP.

Há duas coisas acontecendo aqui:

  • atraso enquanto os trabalhos de e-mail são enfileirados
  • tempo de processamento para o envio do e-mail real

Para o primeiro, não tenho 100% de certeza sobre isso, mas acho que diminuir email_time_window_mins significa que as notificações são enfileiradas mais cedo.

Uma vez que os trabalhos de e-mail são agendados, seus workers do sidekiq estão trabalhando neles um de cada vez. Aumentar os workers do sidekiq (definir DISCOURSE_SIDEKIQ_WORKERS de 5 para 10, 15 ou 20, dependendo da capacidade do servidor) significa que mais trabalhos são processados ao mesmo tempo, então a fila é esvaziada 2x/3x/4x mais rápido.

4 curtidas

Não sei como o backend funciona em todos os detalhes, mas o email_time_window_mins é apenas uma configuração de atraso antes que o primeiro e-mail seja enviado. Durante esse tempo, qualquer usuário definido para receber o e-mail pode “desistir” do e-mail se estiver ativo dentro da janela de período (terminologia oficial: e-mail pulado; motivo do pulo: Usuário foi visto recentemente).

O atraso padrão é de 10 minutos, o que significa que a postagem deve estar ativa por 10 minutos, e só então os e-mails serão enviados.

O problema de Richie é a diferença de tempo entre o primeiro e-mail e o último e-mail… um atraso de uma hora. Isso provavelmente se deve à grande quantidade de e-mails que precisam ser enviados, embora eu também não possa ter certeza.

Alterar a configuração acima apenas aceleraria o envio do primeiro e-mail, mas não resolveria a duração de conclusão do lote inteiro de 22.000 e-mails.


Qual seria a configuração recomendada, obviamente dependente da capacidade da infraestrutura?

Uma configuração alta poderia resultar em problemas de servidor em termos de carga ou outros?

1 curtida

“O máximo que o servidor puder suportar”.

Depende 100% da capacidade do servidor do OP - muitos e isso vai desacelerar, poucos e levará mais tempo para processar.

Dado que o gráfico da CPU atingiu 40% (isso é de uma única CPU ou da capacidade total?), eu provavelmente começaria aumentando 2x (conservador) ou 3x (agressivo) e veria o que acontece, dependendo da tolerância ao risco de lentidão.

1 curtida

Ótima observação, obrigado :slight_smile:

Esse DISCOURSE_SIDEKIQ_WORKERS tem que ser um múltiplo de 5? Posso defini-lo como 7, por exemplo?

Eu não tenho essa configuração de parâmetro no meu app.yml, então vou assumir que está em um padrão de 5 em algum lugar.

Posso simplesmente criar essa configuração sob a configuração existente de workers do unicorn, e então reconstruir?

Ex:

expose:
  - "443:443"

env:
  UNICORN_WORKERS: 8
  DISCOURSE_SIDEKIQ_WORKERS: 7

É tão simples quanto isso? :thinking:

Alguém é capaz de confirmar se esta é a alteração correta a ser feita no meu app.yml quando o parâmetro DISCOURSE_SIDEKIQ_WORKERS não existe atualmente?

1 curtida

Eu acredito que sim, dada uma breve consulta ao bot de IA.

1 curtida

Obrigado @TempAccount

Curiosamente, DISCOURSE_SIDEKIQ_WORKERS aparece apenas onze vezes em todo o meta:

https://meta.discourse.org/search?q=%22DISCOURSE_SIDEKIQ_WORKERS%22%20order%3Alatest_topic

…e uma dessas vezes é neste tópico :flushed_face:

Sim, isso está correto.

Qualquer (a maioria?) configuração pode ser substituída dessa maneira. O valor padrão vem de discourse_defaults.conf.

2 curtidas

Obrigado @supermathie

Meu app.yml agora lê:

env:
  LANG: en_US.UTF-8
  # DISCOURSE_DEFAULT_LOCALE: en

  ## Quantas requisições web concorrentes são suportadas? Depende da memória e dos núcleos da CPU.
  ## será definido automaticamente pelo bootstrap com base nas CPUs detectadas, ou você pode substituir
  UNICORN_WORKERS: 8

  ## Adicionada esta linha em 04/10/25
  ## REF: https://meta.discourse.org/t/is-there-a-way-i-can-send-email-notifications-faster/383103/12
  DISCOURSE_SIDEKIQ_WORKERS: 7

Vou reconstruir mais tarde esta semana e cronometrar o envio de e-mails :smiley:

Só para eu saber que minha alteração teve efeito, estou pensando corretamente que este valor Threads deve aumentar de 5 para 7?

2 curtidas

Sim, confirmado:

2 curtidas

@Richie você conseguiu resolver seu problema?

Obrigado por acompanhar.

Não, infelizmente não.

Aumentei as threads de 5 para 8, mas os e-mails ainda levam quase uma hora para serem enviados do início ao fim.

Eu esperaria talvez um aumento de 40% na produção total.

Quando os trabalhos são enfileirados, você vê utilização 7/7?

Além disso, observe a carga do servidor ao processá-los e, se puder aumentá-la ainda mais, recomendo que o faça.

Ohhhhhh espere um minuto. O Discourse está se limitando de alguma forma?

Perdi alguma configuração que esteja restringindo o uso de CPU? :scream:

Ele não se limita por si só, mas cada worker do sidekiq processará um trabalho por vez, então se você tiver 22.000 e-mails esperando para serem enviados, sete deles serão processados ao mesmo tempo.

Do lado ridículo das coisas, o servidor provavelmente não conseguirá acompanhar se você definir o número para 1.000 workers paralelos. Portanto, trata-se de encontrar um número que atenda a todas as suas necessidades:

  • processar o máximo de trabalhos possível ao mesmo tempo para concluir os 22.000 e-mails mais rapidamente
  • mas não consumir TODOS os recursos do servidor, o que não deixaria nenhum para os usuários do site
2 curtidas