Coda coda messaggi JS su Heroku

Devo spostare il mio server Node JS in esecuzione su Heroku su un’architettura di coda messaggi. Attualmente, il server riceve una richiesta HTTP, esegue alcune elaborazioni e risponde. Il problema è che l’elaborazione richiede un po ‘di tempo, soprattutto quando ci sono molte richieste. Questo lungo tempo di elaborazione causa il timeout, il sovraccarico e l’arresto anomalo del server! La mia lettura mi dice che è necessario un lavoratore in background per eseguire l’elaborazione.

Non ho esperienza con code di messaggi e operatori in background e sto cercando un esempio molto semplice per iniziare. Qualcuno può suggerire un modulo o un esempio semplice e comprensibile per iniziare?

Ho trovato alcuni esempi ma sono complessi e mi sto perdendo! Voglio un esempio barebone da cui posso build.

Vediamo come farlo con RabbitMQ. Innanzitutto, è necessario un server RabbitMQ con cui lavorare nel proprio ambiente di sviluppo. Se non lo hai già fatto (controlla “sudo service rabbitmq-server status”) puoi installare (su ubuntu o simili) come segue:

sudo su -c "echo 'deb http://www.rabbitmq.com/debian/ testing main' >> /etc/apt/sources.list" wget http://www.rabbitmq.com/rabbitmq-signing-key-public.asc sudo apt-key add rabbitmq-signing-key-public.asc sudo apt-get update sudo apt-get install rabbitmq-server rm rabbitmq-signing-key-public.asc 

Quindi, avviare il server con:

 sudo service rabbitmq-server start 

È inoltre necessario configurare un servizio RabbitMQ per la distribuzione di Heroku. Usiamo CloudAMPQ per questo esempio. Puoi aggiungere il suo piano gratuito alla tua app di Heroku con:

 heroku addons:create cloudamqp:lemur 

Ciò creerà una nuova variabile di ambiente CLOUDAMQP_URL nella tua app di Heroku.

Successivamente, avrai bisogno di un client RabbitMQ adatto per la tua app node.js. Ce ne sono alcuni là fuori, ma per questo esempio, usiamo ampqlib:

 npm install ampqlib --save 

Questo dovrebbe aggiungere qualcosa come la seguente riga nelle dipendenze di package.json:

 "amqplib": "^0.4.1", 

La prossima cosa è aggiungere un dyno “worker” in background alla tua app di Heroku. Presumo che al momento tu abbia un solo dyno Web nel tuo Procfile. Pertanto, è necessario aggiungere un’altra riga per creare un’istanza di un worker, ad esempio:

 worker: node myworker.js 

Infine, è necessario scrivere il codice che consentirà al tuo banco di prova di interagire con il tuo banco di lavoro tramite RabbitMQ.

Per il bene di questo esempio, supporrò che il tuo banco di prova “pubblicherà” i messaggi su una coda di messaggi RabbitMQ e il tuo addetto al lavoro “consumerà” questi messaggi.

Quindi, iniziamo con la scrittura del codice per la pubblicazione in una coda di messaggi. Questo codice deve essere eseguito da qualche parte nel tuo banco di prova:

 // Define ampq_url to point to CLOUDAMPQ_URL on Heroku, or local RabbitMQ server in dev environment var ampq_url = process.env.CLOUDAMQP_URL || "amqp://localhost"; var ampq_open = require('amqplib'); var publisherChnl; function createPublisherChannel() { // Create an AMPQ "connection" ampq_open.connect(ampq_url) .then(function(conn) { // You need to create at least one AMPQ "channel" on your connection var ok = conn.createChannel(); ok = ok.then(function(ch){ publisherChnl = ch; // Now create a queue for the actual messages to be sent to the worker dyno publisherChnl.assertQueue('my-worker-q'); }) }) } function publishMsg() { // Send the worker a message publisherChnl.sendToQueue('my-worker-q', new Buffer('Hello world from Web dyno')); } 

Dovrai chiamare createPublisherChannel () durante l’inizializzazione del tuo banco di prova. Quindi, chiama publishMsg () ogni volta che si desidera inviare un messaggio alla coda.

Infine, scriviamo il codice per il consumo del messaggio sopra nel banco prova operaio. Ad esempio, aggiungi qualcosa come il seguente in myworker.js:

 // Just like in Web dyno... var amqp_url = process.env.CLOUDAMQP_URL || "amqp://localhost"; var open_ampq = require('amqplib').connect(amqp_url); var consumerChnl; // Creates an AMPQ channel for consuming messages on 'my-worker-q' function createConsumerChannel() { open_ampq .then(function(conn) { conn.createChannel() .then(function(ch) { ch.assertQueue('my-worker-q'); consumerChnl = ch; }); }); } function startConsuming() { consumerChnl.consume('my-worker-q', function(msg){ if (msg !== null) { console.log(msg.content.toString()); // Tell RabbitMQ server we have consumed the message consumerChnl.ack(msg); } }) } createConsumerChnl().then(startConsuming); 

Infine, prova con “heroku local”. Dovresti vedere che ora hai 2 processi in esecuzione nella tua app, “Web” e “worker”. Ogni volta che chiami publishMsg () nel tuo dyno Web, dovresti vedere che il droke wroker sputa il contenuto del messaggio sulla tua console. Per vedere cosa succede nelle code di RabbitMQ, puoi usare:

 sudo rabbitmqctl list_queues 

Ho trovato un esempio molto semplice (seguito da esempi più profondi) qui: https://www.rabbitmq.com/tutorials/tutorial-one-javascript.html