Atualização em tempo real de tópicos trava sob alta atividade

Nota: Não tenho certeza se isso é um bug no Discourse. Tentei reunir as evidências necessárias e, até agora, não encontrei nada que aponte para nossa infraestrutura/configuração. Nossa configuração é o mais próxima possível do padrão no Tappara.co.

Fenômeno observado:

  • Tópicos de discussão rápida, estilo chat, param de atualizar automaticamente. Após um atraso de 30 a 180 segundos, a atualização geralmente retoma, revelando as postagens feitas durante a congelamento.

O que sabemos até agora

  • Não observamos isso na temporada anterior; o último jogo foi em março.
  • Estamos na branch estável e fizemos a última atualização maior em agosto.
  • O problema foi relatado imediatamente nos primeiros jogos de exibição, com tráfego/atividade moderados.
  • Isso afeta o Chrome no iOS e Android, mas é muito menos frequente no Chromebook.
    • Enquanto escrevo isso, estou vendo congelamentos no meu celular Android, enquanto a discussão flui como esperado no meu Chromebook. Dois dispositivos diferentes na mesma rede.
  • A experiência varia por usuário/cliente. Diferentes usuários relatam os congelamentos em momentos distintos. No geral, registramos cerca de 300 mensagens em aproximadamente 30 minutos, e os usuários relataram dezenas de congelamentos. Na maioria das vezes, os congelamentos parecem estar correlacionados com eventos do jogo (gols, penalidades).

Coisas que tentei para descartar

  • CloudFlare – realizamos um jogo sem cache do CF, e o problema persistiu.
  • Sobrecarga de CPU – o uso da CPU está bem dentro dos limites, geralmente oscilando entre 20-30%.
  • Esgotamento do disco – a E/S do disco parece estar bem dentro dos limites. Temos SSDs MaxIOPS da UpCloud.

Outras informações

  • Tive o inspecionador do Chrome rodando durante o jogo e alguns erros 429 foram registrados, mas, para mim, eles não correlacionaram com os congelamentos.
  • Os usuários finais não estão recebendo notificações sobre os erros 429 (limitação de velocidade) ou carga extrema. A atualização simplesmente congela e depois retoma. O limitador de taxa mudou recentemente? Tenho a impressão de que os limites de taxa deveriam acionar um aviso na interface do usuário?

Um problema realmente desagradável, que prejudica bastante os chats de jogo em tempo real. Temos realizado esses chats há anos e nunca vi isso antes.

Bem, não é um bug, mas sim um recurso :sweat_smile:.

Quando seus web workers começam a ficar sobrecarregados por solicitações, introduzimos atrasos na conexão persistente que atualiza automaticamente o tópico quando novas mensagens chegam.

Se você está vendo isso e o uso de CPU relatado está baixo, por favor, aumente o número de workers do Unicorn e isso deve resolver o problema.

Já estamos com 11 Unicórnios em um VPS de 6 núcleos. Como dito, isso nunca ocorreu na temporada anterior, no máximo em março. Agora ocorre mesmo com tráfego moderado. Além disso, isso acontece muito mais em dispositivos móveis, especialmente no Chrome para Android, do que em desktops.

Também conseguimos esgotar nossa CPU antes (no prazo final de transferências no mercado).

Perdi uma partida monitorando e mexendo no servidor. Dobramos os parâmetros web.ratelimited, mas isso não resolveu o problema.

O Inspector captura vários erros 429:

1. URL da solicitação:

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

2. Método da solicitação:

POST

3. Código de status:

429

O próximo jogo é amanhã, então posso testar os Unicórnios. Até onde podemos ir? Isso mudou com a última atualização importante?

Edição:

Analisei as estatísticas e nossa atividade até agora foi menor do que a observada na primavera (visualizações de página, usuários). O número de posts por chat de jogo é idêntico (cerca de 900 a 1000 a cada 3 horas).

Portanto, por uma razão desconhecida, atualmente não conseguimos atender ao mesmo público que tínhamos em março.

Estou trabalhando na análise deste problema nas próximas duas semanas; levará tempo para melhorar.

Ótimo! Poderia confirmar se houve alguma mudança ou regressão recente (nos últimos 6 meses) que tenha causado isso?

Enquanto isso, acho que vou aumentar a sorte dos unicórnios para o jogo de hoje à noite e ver o que acontece. Se pudermos ajudar de alguma forma, é só me avisar.

@falco O número de unicórnios definitivamente não é o fator chave. Aumentei para 15 para o jogo de hoje à noite. O tópico do jogo foi tranquilo, com apenas 700 mensagens, mas foram observadas congelamentos constantes. A carga da CPU foi leve, variando entre 5% e 25%.

Quanto mais investigo isso, mais parece ser um problema e uma regressão, mas minhas habilidades não são suficientes para identificar onde está o erro.

Acho que há um bug no cliente que faz com que ele basicamente pare de atualizar após receber um erro. Minha suspeita é de que você está enfrentando isso porque seus usuários estão sendo limitados em termos de taxa.

Vou investigar como tornar o cliente mais robusto esta semana. Como disse anteriormente, este é um código delicado e levará algum tempo.

Ótimo. Enquanto isso, vou testar se desativar o limitador global seria uma solução alternativa. Teremos uma resposta na quarta-feira.

Depurar essa questão me levou a refletir sobre a UX de discussões em tempo quase real em geral. Muitas comunidades lidam com eventos da vida real, que naturalmente “impulsionam” a discussão em direção a uma conversa rápida, estilo chat. Pode ser o mercado de ações, o lançamento de um grande produto ou um jogo (eSport ou físico)… o que você puder imaginar.

Mas, nesse tipo de cultura de discussão estilo chat, a qualidade das postagens varia muito. Por outro lado, as postagens têm uma tendência natural a ocorrer exatamente ao mesmo tempo. Vamos imaginar que há uma grande partida de hóquei em andamento e alguém marca um gol.

  • Uma grande parte das postagens são apenas reações emocionais, comemorações ou lamentações.
    • “Goooool!!! Yeah baby”
  • Algumas são informativas:
    • “Crosby marca, 1 a 0 para os Pens”
  • Uma pequena minoria se esforça para incluir alguma análise:
    • “Crosby marca um gol em contra-ataque, após uma tentativa descuidada de forecheck dos Caps, mas pareceu bastante um impedimento. O técnico dos Caps deveria contestar isso.”

Agora, como o Discourse é uma plataforma rápida (tempo quase real), isso significa que, mesmo quando tudo funciona bem, você verá algumas dezenas de postagens praticamente no mesmo instante. Para o leitor, especialmente para quem não está assistindo ao jogo, mas acompanha pelo tópico de chat, isso representa um desafio de UX — é difícil identificar as postagens informativas no meio das comemorações e lamentações. Nos chats de jogos do nosso fórum, frequentemente recebemos a pergunta “Qual é o placar?”, pois os participantes que assistem ao jogo esquecem de postar o óbvio, ou a informação se perde na enxurrada de mensagens.

Não sei como isso funcionaria na vida real, mas seria interessante testar se os administradores poderiam definir o ritmo da discussão. Digamos, por exemplo, uma postagem por segundo. Todas as postagens seriam enfileiradas, mas publicadas no site em um ritmo definido. Se um gol gerar 20 postagens de reação, elas não apareceriam no tópico ao mesmo tempo, mas distribuídas em uma janela de 20 segundos. Seria mais fácil acompanhar e captar as informações relevantes?

Isso, claro, poderia levar a outros problemas: se o ritmo das novas mensagens constantemente excedesse o ritmo de publicação, haveria uma fila cada vez maior e o chat começaria a ficar defasado em relação ao mundo real.

Não tenho certeza se você entendeu a ideia, e até eu não sei se ela é boa. O ponto principal é que a UX do chat em tempo real é um tópico interessante de discussão e pode ter potencial para desenvolvimento futuro? Entendo que o foco principal do Discourse não é criar uma plataforma de chat — existem outros softwares para isso. Mas esses casos ocorrem, naturalmente.

Gosto dessa ideia, mas seria necessário algum tipo de ‘shadow ban reverso’ para que as pessoas sempre vejam suas próprias postagens imediatamente. Caso contrário, elas podem acabar fazendo postagens duplas ou até triplas, achando que o fórum não está funcionando.

Acabei de fundir isso:

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

Isso garante que não derrubemos um servidor se 1000 pessoas estiverem visualizando um tópico e houver postagens sendo feitas.

O cliente agora se comporta de forma muito mais limpa nesses casos.

Antecipando a pergunta do @ljpp aqui, ainda estou indeciso sobre o backport, pois isso envolve alterações na API e é uma mudança bastante significativa. Se fizermos o backport… provavelmente levará algumas semanas. Preciso observar isso em produção sob carga e, como temos tão poucos eventos assim, já que nossa hospedagem tem muita folga, vai levar um tempo para captar.

Truques Jedi na mente :wink:

  • Vamos verificar se desativar o limitador de taxa é uma solução viável.
  • Se for: A próxima versão estável não deve demorar muito, presumo.
  • Se não for, daremos uma olhada no canal Beta. Teremos que verificar se nossa personalização da interface não será quebrada pela atualização.

Temos alguma outra comunidade com discussões semelhantes ao chat e que está rodando em ramos de borda?

Esperamos uma até o final do ano… então eu não esperaria que fosse muito em breve. No entanto, vamos lançar outra versão beta esta semana!

Toda a nossa hospedagem roda em beta… então, sim, mas temos muita capacidade.

Entendo o raciocínio de que isso pode não ser um candidato a backport. Acabei de desativar nosso ratelimiter e amanhã é o próximo jogo, então teremos uma ideia aproximada de se isso serve como uma solução viável para instâncias que não desejam entrar no beta.

Definitivamente estamos considerando migrar para a branch beta nos próximos meses. No entanto, há outras preocupações também — @rizka apontou que a tradução em FI está atrasada (mas ele pode conseguir trabalhar nisso mais tarde nesta semana).

@sam

Infelizmente, desativar o ratelimiter não ajudou em nada. Foi um jogo entediante e 83 usuários enviaram apenas 580 mensagens. Vários travamentos foram relatados durante o jogo.

Existem possíveis hacks ou soluções alternativas para tentar enquanto aguardamos a atualização para uma versão edge?

Os “congelamentos” são um bug do cliente; ele simplesmente não reagiu corretamente às condições de erro. Mesmo um único erro de limite de taxa e você está fora no canal estável.

Não consigo pensar em uma solução alternativa, a não ser atualizar para o beta (vamos lançar um novo amanhã).

Um de nossos membros focados em desenvolvimento propôs ajustar a seguinte variável. O que você acha - você vê isso como uma possível solução alternativa?

DISCOURSE_REJECT_MESSAGE_BUS_QUEUE_SECONDS: 0.2

Tentamos o truque:

DISCOURSE_REJECT_MESSAGE_BUS_QUEUE_SECONDS: 0.2

Isso reduziu significativamente o número de lentidões observadas, mas não resolveu o problema. A carga da CPU aumentou, oscilando em torno de ~55% nos momentos de grandes eventos no jogo.

Houve mudanças recentes para ajudar com os ‘congelamentos’: o cliente recuará e aguardará se o servidor estiver sobrecarregado.

No entanto, a solução definitiva pode ser obter um servidor maior e executar mais workers do Unicorn. Consulte o script discourse-setup para nossas recomendações sobre a relação entre capacidade do servidor e número de workers.

Duvido… o problema sob alta carga de respostas é que, antes do novo design, podíamos causar uma inundação que ativava limites de taxa devido a max_reqs_per_ip_per_10_seconds e afins. Seriam necessários recursos enormes para lidar com essa carga.

Considere:

  • 30 usuários postam uma resposta em 10 segundos
  • 100 pessoas estão visualizando o tópico
  • O servidor precisa ser capaz de lidar com 3000 requisições GET para buscar uma única postagem por vez
  • Se QUALQUER uma dessas requisições falhar por qualquer motivo, a interface congelaria e pareceria quebrada

O novo design resolve esse problema de forma muito limpa: as requisições recuam de maneira ordenada, são agrupadas se houver um acúmulo, a interface não congela e assim por diante.

Não consigo imaginar o design antigo escalando para 100 usuários simultâneos e 30 respostas em 10 segundos.

Já consigo ver o design atual revisado funcionando bem com 1000 usuários simultâneos visualizando um tópico com 30 respostas em 10 segundos.