簡體   English   中英

Heroku上的節點JS消息隊列

[英]Node JS message queue on Heroku

我需要將在Heroku上運行的Node JS服務器移動到消息隊列架構。 目前,服務器接收HTTP請求,進行一些處理並進行響應。 問題是處理需要一些時間,特別是當有大量請求時。 這個漫長的處理時間會導致服務器超時,過載和崩潰! 我的閱讀告訴我需要后台工作人員來處理。

我對消息隊列和后台工作者沒有經驗,我正在尋找一個非常簡單的示例來開始。 任何人都可以建議一個簡單,易懂的模塊或示例來開始?

我發現了一些例子,但它們很復雜,我迷路了! 我想要一個我可以構建的准系統示例。

讓我們看看如何使用RabbitMQ做到這一點。 首先,您需要一個RabbitMQ服務器才能在您的開發環境中使用。 如果你還沒有它(檢查“sudo service rabbitmq-server status”)你可以安裝(在ubuntu或類似的)如下:

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

然后,讓服務器運行:

sudo service rabbitmq-server start

您還需要為Heroku部署配置RabbitMQ服務。 我們在這個例子中使用CloudAMPQ。 您可以將其免費計划添加到您的Heroku應用程序中:

heroku addons:create cloudamqp:lemur 

這將在您的Heroku應用程序中創建一個新的CLOUDAMQP_URL環境變量。

接下來,您將需要一個適合您的node.js應用程序的RabbitMQ客戶端。 其中有一些,但對於這個例子,讓我們使用ampqlib:

npm install ampqlib --save

這應該在package.json依賴項中添加類似以下行的內容:

"amqplib": "^0.4.1",

接下來就是在你的Heroku應用程序中添加一個背景“worker”dyno。 我假設你的Procfile中目前只有一個Web dyno。 因此,您需要添加另一行來實例化工作程序,例如:

worker: node myworker.js

最后,您需要編寫代碼,使您的Web dyno能夠通過RabbitMQ與您的worker dyno進行交互。

為了這個例子,我假設您的Web dyno將“發布”消息到RabbitMQ消息隊列,並且您的worker dyno將“消費”這些消息。

所以,讓我們開始編寫用於發布到消息隊列的代碼。 此代碼需要在Web dyno中的某個位置運行:

// 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'));
}

在初始化Web dyno期間,您需要調用createPublisherChannel()。 然后,只要您想要將消息發送到隊列,就調用publishMsg()。

最后,讓我們編寫用於在worker dyno中使用上述消息的代碼。 因此,例如,在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); 

最后,用“heroku local”進行測試。 您應該會看到您現在在應用程序中運行了2個進程,“Web”和“worker”。 無論何時在Web dyno中調用publishMsg(),您都應該看到wroker dyno將消息內容吐出到您的控制台。 要查看RabbitMQ隊列中發生的情況,您可以使用:

sudo rabbitmqctl list_queues

我在這里找到了一個非常簡單的例子(后面是更深層的例子): https//www.rabbitmq.com/tutorials/tutorial-one-javascript.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM