Executando verificação de segurança...
2

RabbitMQ em um SaaS

Olá, tenho um SaaS baseado em um chat e preciso processar mensagens em filas.
Qual o melhor/correto método para separar essas filas?

No momento pensei em cada empresa ter sua fila, por exemplo:
Tenho uma fila pra salvar contatos, então seria MQ.sendToQueue(contatos_${ID_EMPRESA}, dados).

Essa seria a melhor prática (adicionando o id da empresa em cada fila)?

Agradeço

Carregando publicação patrocinada...
4

Fala meu amigo tudo bem?

Hoje trabalho num sistema de mensageria que usa amplamente o RabbitMQ e dado o seu cenário eu posso te dar aqui algumas orientações supondo que a sua aplicação funciona em multitenancy (umuma única aplicação para varios usuarios, enfim, um saas rs)

  1. fila única para os contatos
  2. multiplos consumers para melhorar o tps da sua aplicação
  3. um contato por mensagem
  4. configure uma fila DLQ (dead letter queue) que em caso de falha essa mensagem é direcionada para la
  5. utilize filas do tipo quorum, elas funcionam no formato FIFO (first in first out)
  6. use e abuse dos params da mensagem como correlation_id, message_id, etc
  7. se você precisar de algo realtime utilize websocket (socket.io por exemplo) para mandar as mensagens ao usuário e deixe o rabbitmq para processar os dados no backend (add no banco de dados, parsers, etc)
  8. se optar por filas individuais opte por filas que se auto deletam pq o rabbitmq fica extremamente lento quando há muitas filas

por fim tenha em mente que o rabbitmq é um message broker e a função dele é simplesmente entregar a mensagem que você posta nele a um consumidor que irá trabalhar os dados da mensagem de forma assincrona.

1

Muito obrigado pelas suas instruções, são de grande ajuda sem dúvidas. Então está me falando que seria apenas uma fila (por exemplo a de contatos) para todas empresas, isso?

Atualmente estou utilizando socket.io mesmo. Antes de enviar pra fila eu mando o contato via socket pro client e após isso é enviado pra fila.

2

exatamente!

assim você controla o fluxo de atualização no banco de dados a partir da quantidade de consumers e fica muito mais fácil a manutenção

1

Agradeço a resposta.
Sobre a questão do envio de mensagem, mantenho apenas uma fila pra todas empresas também?
E outra, nesse caso das mensagens, é normal utilizar fila tanto pra receber quanto pra enviar?

2

como funcionam seus consumers, será um (ou varios consumers) por fila? qual vantagem vc vê em separar por fila? quer ter um controle de contatos ainda na fila no nivel de empresa?

por fim, esse id da empresa esta tambem dentro da mensagem? como está estruturado seu DB?

1

Boa tarde,
Não tenho um conhecimento base do Rabbit (comecei utilizar agora) por isso a dúvida (pode ser que o exemplo que eu dei seja totalmente fora de curva).

Atualmente só possuo uma fila de contatos (vou criar mais algumas) onde a inserção de dados pra essa fila vai ser executada apenas uma vez na conexão da empresa ao sistema.

No momento, estou enviando um array de contatos pro consumer e dentro desse consumer eu faço um multiInsert no banco de dados (não sei se é a melhor prática enviar todos em um array único ou um por vez).

No array do contato, vai junto um tenant_id, então quando o consumer for inserir os dados no banco já vai ser salvo com a relação do tenant.

2

olá, a forma que abordou é interessante, mas visto ao seu outro comentário de ser um array com todos os contatos de uma vez que na conexão, talvez fosse interessante 1 contato por mensagem na fila, por ter a relação do tenant id, 1 consumer pode resolver para todas as empresas, já que não é algo que precisa de "imediato"

1

Fala Leandro, valeu pela resposta.
Entao, seguindo sua dica, eu enviaria um contato por vez na fila e existiria apenas a fila contatos para todas empresas, isso?

1
1

Entendi, mas se tiver 1000 empresas vão existir 1000 filas pra contatos, 1000 filas pra mensagens, etc... Isso não pode ser um problema? (desculpa a ignorancia)

1

pode ser um problema sim, mas pelo que tinha entendido, vc salva esses contatos na conexão, então depois não utilizaria mais a fila de tal empresa, certo?

1

Correto. Os contatos são processados pelo consumer e salvos em um banco de dados. Após salvo, não é necessário mais a utilização da fila para essa empresa.

1

então, visto esse cenário, mesmo com 1000 empresas, não teria problema considerável, visto que é praticamente 1 vez esse uso de fila para contatos por empresa

0
2

Começe pelo básico que resolve o problema, nesse caso o mais simples seria enviar uma mensagem por vez e no payload da mesma ter a mensagem, empresa/tenancy. Fica mais simples uma unica fila e vários consumers, você pode também poderá filtrar de acordo com os parametros do payload.

1

Fala danilo, valeu pela resposta.
Então, ja estou fazendo isso, enviando o id do tenant no payload junto com o restante das informações.

Atualmente tenho uma única fila sendo message:sent (que serão enviadas) e message:received (mensagens recebidas, pra tratar toda a logica de salvamento na db).

Porém tenho apenas um consume pra cada fila. Poderia me informar oque de fato iria impactar criando varios consumers?

Agradeço!

3

Não tem problema em ter vários consumers, o problema seria não ter o suficiente e acabar tendo muitas mensagens represadas, mas isso envolve problema de escalabilidade. Eu não criária uma fila para cada cliente apenas teria uma fila e trataria as mesengens e tivesse que fazer algum filtro/ação faria apenas pelo conteudo payload dentro.