Rabbitmq là gì? tìm hiểu và sử dụng rabbitmq

*

Menu
*

*

Prerequisites

This tutorial assumes neftekumsk.com is installed và running on localhost on the standard port (5672). In case you use a different host, port or credentials, connections settings would require adjusting.

Where khổng lồ get help

If you"re having trouble going through this tutorial you can contact us through the mailing các mục or neftekumsk.com community Slaông chồng.


*

digraph bgcolor=transparent; truecolor=true; rankdir=LR; node ; // P1 ; Q.1 ; C1 , fillcolor="#33ccff">; C2 , fillcolor="#33ccff">; // P1 -> Q.1 -> C1; Q1 -> C2;

In the first tutorial wewrote programs khổng lồ send and receive sầu messages from a named queue. In thisone we"ll create a Work Queue that will be used to distributetime-consuming tasks among muốn multiple workers.

Bạn đang xem: Rabbitmq là gì? tìm hiểu và sử dụng rabbitmq

The main idea behind Work Queues (aka: Task Queues) is lớn avoiddoing a resource-intensive sầu task immediately và having lớn wait forit to complete. Instead we schedule the task to be done later. We encapsulate atask as a message & send it to a queue. A worker process runningin the background will pop the tasks and eventually exexinh đẹp thejob. When you run many workers the tasks will be shared between them.

This concept is especially useful in web applications where it"simpossible to handle a complex task during a short HTTP. requestwindow.

Preparation

In the previous part of this tutorial we sent a message containing"Hello World!". Now we"ll be sending strings that st& for complextasks. We don"t have sầu a real-world task, lượt thích images khổng lồ be resized orpdf files lớn be rendered, so let"s nhái it by just pretending we"rebusy - by using the setTimeout method. We"ll take the number of dotsin the string as its complexity; every dot will tài khoản for one secondof "work". For example, a fake task described by Hello...will take three seconds.

We will slightly modify the skết thúc.js code from our previous example,lớn allow arbitrary messages lớn be sent from the command line. Thisprogram will schedule tasks to our work queue, so let"s name itnew_task.js:

var queue = "task_queue";var msg = process.argv.slice(2).join(" ") || "Hello World!";channel.assertQueue(queue, durable: true);channel.sendToQueue(queue, Buffer.from(msg), persistent: true);console.log(" Sent "%s"", msg);Our old receive.js script also requires some changes: it needs tonhái a second of work for every dot in the message body toàn thân. It will popmessages from the queue & perform the task, so let"s Call it worker.js:

var queue = "task_queue";// This makes sure the queue is declared before attempting to lớn consume from itchannel.assertQueue(queue, durable: true);channel.consume(queue, function(msg) var secs = msg.nội dung.toString().split(".").length - 1; console.log(" Received %s", msg.content.toString()); setTimeout(function() console.log(" Done"); , secs * 1000);, // automatic acknowledgment mode, // see https://www.neftekumsk.com/confirms.html for details noAck: true);chú ý that our nhái task simulates execution time.

Run them as in tutorial one:

# shell 1./worker.js# shell 2./new_task.js

Round-robin dispatching

One of the advantages of using a Task Queue is the ability khổng lồ easilyparallelise work. If we are building up a backlog of work, we can justadd more workers và that way, scale easily.

First, let"s try lớn run two worker.js scripts at the same time. Theywill both get messages from the queue, but how exactly? Let"s see.

You need three consoles open. Two will run the worker.jsscript. These consoles will be our two consumers - C1 & C2.

# shell 1./worker.js# => <*> Waiting for messages. To exit press CTRL+C# shell 2./worker.js# => <*> Waiting for messages. To exit press CTRL+CIn the third one we"ll publish new tasks. Once you"ve startedthe consumers you can publish a few messages:

# shell 3./new_task.js First message../new_task.js Second message.../new_task.js Third message..../new_task.js Fourth message...../new_task.js Fifth message.....Let"s see what is delivered to lớn our workers:

# shell 1./worker.js# => <*> Waiting for messages. To exit press CTRL+C# => Received "First message."# => Received "Third message..."# => Received "Fifth message....."# shell 2./worker.js# => <*> Waiting for messages. To exit press CTRL+C# => Received "Second message.."# => Received "Fourth message...."By mặc định, neftekumsk.com will send each message khổng lồ the next consumer,in sequence. On average every consumer will get the same number ofmessages. This way of distributing messages is called round-robin. Trythis out with three or more workers.

Message acknowledgment

Doing a task can take a few seconds. You may wonder what happens ifone of the consumers starts a long task và dies with it only partly done.With our current code, once neftekumsk.com delivers a message khổng lồ the consumer itimmediately marks it for deletion. In this case, if you kill a workerwe will thua trận the message it was just processing. We"ll also thua kém allthe messages that were dispatched to this particular worker but were notyet handled.

But we don"t want lớn thua thảm any tasks. If a worker dies, we"d like thetask lớn be delivered lớn another worker.

In order to make sure a message is never lost, neftekumsk.com supportsmessage acknowledgments. An ack(nowledgement) is sent back by theconsumer khổng lồ tell neftekumsk.com that a particular message has been received,processed & that neftekumsk.com is miễn phí to lớn delete it.

If a consumer dies (its channel is closed, connection is closed, orTCP connection is lost) without sending an aông chồng, neftekumsk.com willunderst& that a message wasn"t processed fully and will re-queue it.If there are other consumers online at the same time, it will then quickly redeliver itlớn another consumer. That way you can be sure that no message is lost,even if the workers occasionally die.

Xem thêm: Thiết Kế Nhà Gỗ Đẹp - Những Mẫu Nhà Gỗ Đẹp Hiện Đại Cho Năm 2019

There aren"t any message timeouts; neftekumsk.com will redeliver the message whenthe consumer dies. It"s fine even if processing a message takes a very, verylong time.

Manual consumer acknowledgments have sầu been turned off in previous examples.It"s time to lớn turn them on using the noAck: false option và sover a proper acknowledgmentfrom the worker, once we"re done with a task.

channel.consume(queue, function(msg) var secs = msg.content.toString().split(".").length - 1; console.log(" Received %s", msg.content.toString()); setTimeout(function() console.log(" Done"); channel.ack(msg); , secs * 1000); , // manual acknowledgment mode, // see https://www.neftekumsk.com/confirms.html for details noAck: false );Using this code we can be sure that even if you kill a worker usingCTRL+C while it was processing a message, nothing will be lost. Soonafter the worker dies all unacknowledged messages will be redelivered.

Acknowledgement must be sent on the same channel that received thedelivery. Attempts khổng lồ acknowledge using a different channel will resultin a channel-cấp độ protocol exception. See the doc guide on confirmationskhổng lồ learn more.

Forgotten acknowledgment

It"s a common mistake khổng lồ miss the achồng. It"s an easy error,but the consequences are serious. Messages will be redeliveredwhen your client quits (which may look lượt thích random redelivery), butneftekumsk.com will eat more and more memory as it won"t be able lớn releaseany unacked messages.

In order khổng lồ debug this kind of mistake you can use neftekumsk.comctlto print the messages_unacknowledged field:

subởi neftekumsk.comctl list_queues name messages_ready messages_unacknowledged

On Windows, drop the sudo:neftekumsk.comctl.bat list_queues name messages_ready messages_unacknowledged

Message durability

We have sầu learned how khổng lồ make sure that even if the consumer dies, thetask isn"t lost. But our tasks will still be lost if neftekumsk.com server stops.

When neftekumsk.com quits or crashes it will forget the queues and messagesunless you tell it not to lớn. Two things are required lớn make sure thatmessages aren"t lost: we need to lớn mark both the queue and messages asdurable.

First, we need lớn make sure that the queue will survive a neftekumsk.com node restart.In order to do so, we need to lớn declare it as durable:

channel.assertQueue("hello", durable: true);Although this command is correct by itself, it won"t work in our presentcài đặt. That"s because we"ve already defined a queue called hellowhich is not durable. neftekumsk.com doesn"t allow you lớn redefine an existing queuewith different parameters & will return an error khổng lồ any programthat tries to vị that. But there is a quiông chồng workaround - let"s declarea queue with different name, for example task_queue:

channel.assertQueue("task_queue", durable: true);This durable option change needs lớn be applied lớn both the producervà consumer code.

At this point we"re sure that the task_queue queue won"t be losteven if neftekumsk.com restarts. Now we need to mark our messages as persistent- by using the persistent option Channel.sendToQueue takes.

channel.sendToQueue(queue, Buffer.from(msg), persistent: true);cảnh báo on message persistenceMarking messages as persistent doesn"t fully guarantee that a messagewon"t be lost. Although it tells neftekumsk.com khổng lồ save the message to lớn disk,there is still a short time window when neftekumsk.com has accepted a message andhasn"t saved it yet. Also, neftekumsk.com doesn"t vì fsync(2) for everymessage -- it may be just saved khổng lồ cabịt and not really written khổng lồ thedisk. The persistence guarantees aren"t svào, but it"s more than enoughfor our simple task queue. If you need a stronger guarantee then you can usepublisher confirms.

Fair dispatch

You might have sầu noticed that the dispatching still doesn"t work exactlyas we want. For example in a situation with two workers, when allodd messages are heavy & even messages are light, one worker will beconstantly busy và the other one will vày hardly any work. Well,neftekumsk.com doesn"t know anything about that and will still dispatchmessages evenly.

This happens because neftekumsk.com just dispatches a message when the messageenters the queue. It doesn"t look at the number of unacknowledgedmessages for a consumer. It just blindly dispatches every n-th messagekhổng lồ the n-th consumer.