Processos em segundo plano em Node.js

96

Qual é uma boa abordagem para lidar com processos em segundo plano em um aplicativo NodeJS?

Cenário : depois que um usuário posta algo em um aplicativo, eu quero processar os dados, solicitar dados adicionais de recursos externos etc. Tudo isso consome muito tempo, então eu quero sair do loop req / res. O ideal seria apenas ter uma fila de trabalhos onde você pode rapidamente despejar um trabalho e um daemon ou executor de tarefas sempre pegará o mais antigo e o processará.

No RoR, eu teria feito isso com algo como Delayed Job. Qual é o Node equivalente a esta API?

Ole Spaarmann
fonte
4
A questão é uma recomendação de software como está formulada agora, que acabará sendo encerrada. Se você substituísse a última frase por "Qual é o NodeJS equivalente a esta API?" torna-se mais no tópico. Eu gostaria de ver isso respondido em vez de encerrado, pois preciso fazer algo semelhante.
ssube
Obrigado, reformulou a frase.
Ole Spaarmann
2
Boas sugestões abaixo. Há também a ChildProcessAPI que pode ser útil. nodejs.org/api/child_process.html
lispHK01
stackoverflow.com/users/69349/ole-spaarmann - Gostaria de saber o que você finalmente escolheu e se você pudesse fornecer um exemplo muito simples de como integrou sua decisão com o NodeJS - obrigado!
MLissCetrus
@MLissCetrus Eu escolhi aprender Elixir e não usar mais NodeJS :)
Ole Spaarmann

Respostas:

114

Se você quer algo leve, que rode no mesmo processo do servidor, eu recomendo fortemente a Bull . Tem uma API simples que permite um controle refinado sobre suas filas.

Se você estiver procurando por algo que funcione como um processo de trabalho autônomo, talvez dê uma olhada em Kue . Ele pode ser executado como um servidor RESTful API e até mesmo tem vários aplicativos de front-end escritos para ele.

Se você estiver familiarizado com o Resque de Ruby, há uma implementação de nó chamada Node-resque

Bull, Kue e Node-resque são todos apoiados pelo Redis , que é onipresente entre as filas de trabalho do Node.js. Todos os 3 seriam capazes de fazer o que RoR's DelayedJob faz, é uma questão de recursos específicos que você deseja e suas preferências de API.

Yuri Zarubin
fonte
3
Esta é uma resposta muito boa, mas mencionar a API ChildProcess e o módulo de threads de trabalho da web pode torná-la ótima. ;)
ssube
@ssube eu discordo de você. A menos que você queira criar um fork que olhe para uma fila para executar algum comando, você está certo. +1 de mim. Child_process é o que estou usando e meu problema é que eu poderia abrir um grande conjunto de processos, mas se eu tivesse uma maneira de gerenciar as tarefas a serem executadas em uma fila, ficaria feliz que o CP seja uma boa solução. Isso pode ser feito, mas o objetivo é não fazer todo o trabalho sozinho, mas reutilizar o código que é testado em batalha (neste caso, algo como Kue que faz toda a mágica que você precisa e permite integrações de API).
dewwwald
A Bull trabalha com clustering PM2? Ou você precisa criar seus próprios clusters manualmente, conforme mostrado em sua documentação?
Shayan Nahrvar
31

As tarefas em segundo plano não estão diretamente relacionadas ao seu trabalho de serviço da web, portanto, não devem estar no mesmo processo. Conforme você aumenta, o uso de memória das tarefas em segundo plano afetará o desempenho do serviço da web. Mas você pode colocá-los no mesmo repositório de código se quiser, o que fizer mais sentido.

Uma boa escolha para troca de mensagens entre os dois processos seria redis , se soltar uma mensagem de vez em quando está OK. Se você quiser "nenhuma mensagem deixada para trás", você precisará de um corretor mais pesado como o Rabbit . Seu processo de serviço da web pode ser publicado e seu processo de trabalho em segundo plano pode ser assinado.

Não é necessário que os dois processos sejam co-hospedados, eles podem estar em VMs, contêineres Docker separados, o que quer que você use. Isso permite que você dimensione sem muitos problemas.

wberry
fonte
3
Realmente a única resposta que mencionou Rabbit? Esta é a resposta corporativa. +1
Augie Gardner
11

Se você estiver usando o MongoDB, recomendo Agenda . Dessa forma, instâncias separadas do Redis não estão em execução e recursos como agendamento, enfileiramento e IU da Web estão todos presentes. A IU da Agenda é opcional e pode ser executada separadamente, é claro.

Também recomendaria configurar uma abstração fracamente acoplada entre a lógica do aplicativo e o sistema de enfileiramento / agendamento, de forma que todo o sistema de processamento em segundo plano possa ser trocado, se necessário. Em outras palavras, mantenha o máximo de lógica de aplicativo / processamento longe de suas definições de trabalho da Agenda para mantê-las leves.

sean2078
fonte
3

Eu gostaria de sugerir o uso do Redis para agendar trabalhos. Ele tem muitas estruturas de dados diferentes, você sempre pode escolher uma que se adapte melhor ao seu caso de uso.

Você mencionou RoR e DJ, então presumo que você esteja familiarizado com o sidekiq. Você pode usar node-sidekiq para agendamento de trabalho se quiser, mas é subótimo, já que seu objetivo principal é integrar nodejs com RoR.

Para a daemonização do trabalhador, eu recomendo o uso do PM2 . É amplamente utilizado e com manutenção ativa. Ele resolve muitos problemas (por exemplo, implantação, monitoramento, clustering), portanto, certifique-se de que não será um exagero para você.

stefkin
fonte
1

Tentei Bee-queue & Bull e escolhi Bull no final. Eu primeiro escolhi bee-queue porque é bastante simples, seus exemplos são fáceis de entender, enquanto os exemplos de touros são um pouco complicados. wiki de bee A Origem da Bee Queue também ressoou comigo. Mas o problema com o bee é <1> que o tempo de resolução do problema é muito lento, a última atualização foi há 10 meses. <2> Não consigo encontrar uma maneira fácil de pausar / cancelar o trabalho.

A Bull, por outro lado, atualiza frequentemente seus códigos, em resposta aos problemas. A avaliação da fila de tarefas do Node.js disse que o ponto fraco do touro é o "tempo de resolução de problemas lento", mas minha experiência é o oposto!

Mas de qualquer forma, sua API é semelhante, por isso é muito fácil alternar de uma para outra.

Qiulang
fonte
-6

Eu sugiro usar uma estrutura Node.js adequada para construir seu aplicativo.

Acho que o mais poderoso e fácil de usar é o Sails.js .

É um framework MVC, então se você está acostumado a desenvolver em ROR, vai achar que é muito, muito fácil!

Se você usá-lo, ele já apresenta um poderoso (em termos de javascript) gerenciador de tarefas.

new sails.cronJobs('0 01 01 * * 0', function () {
   sails.log.warn("START ListJob");
}, null, true, "Europe/Dublin");

Se precisar de mais informações não hesite em contactar-me!

Zio Mak Sò
fonte
5
Estou procurando um gerenciador de processos em segundo plano para o Node. Por definição, isso deve ser separado do seu aplicativo da web. E não importa se você usa Sails, Express, Hapi ou o que quiser.
Ole Spaarmann
Ok, você pode tentar Bull ou Webworker-Threads ... boa sorte com Node.js :)
Zio Mak Sò
Parece que sails.js é muito grande e faz muito mais do que cronJobs. Eu encontrei node-cron ( github.com/kelektiv/node-cron ) que eu aposto que é o que sails.js usa.
pbatey