《RabbitMQ Tutorial》译文 第 2 章 工作队列 (2)

使用任务队列的其中一项优势就是可以很容易地开展并行工作。如果(队列中)出现大量地工作积压,我们可以通过该途径增添更多的工作单元,所以扩展规模很方便。

First, let's try to run two Worker instances at the same time. They will both get messages from the queue, but how exactly? Let's see.

首先,让我们尝试同时运行两个工作实例。他们将同时从队列中获取消息,不过结果将会如何呢?一起拭目以待吧。

You need three consoles open. Two will run the Worker program. These consoles will be our two consumers - C1 and C2.

你需要开启 3 个控件台,其中两个将用来运行工作程序,它们将成为消费者 - C1 和 C2。

# shell 1 cd Worker dotnet run # => [*] Waiting for messages. To exit press CTRL+C # shell 2 cd Worker dotnet run # => [*] Waiting for messages. To exit press CTRL+C

In the third one we'll publish new tasks. Once you've started the consumers you can publish a few messages:

在第 3 个控制台,我们将发布一个新任务。你一旦启动消费者程序,新任务就可以发布一些信息了:

# shell 3 cd NewTask dotnet run "First message." dotnet run "Second message.." dotnet run "Third message..." dotnet run "Fourth message...." dotnet run "Fifth message....."

Let's see what is delivered to our workers:

让我们一起看看到底递送了什么消息给工作单元:

# shell 1 # => [*] Waiting for messages. To exit press CTRL+C # => [x] Received 'First message.' # => [x] Received 'Third message...' # => [x] Received 'Fifth message.....' # shell 2 # => [*] Waiting for messages. To exit press CTRL+C # => [x] Received 'Second message..' # => [x] Received 'Fourth message....'

By default, RabbitMQ will send each message to the next consumer, in sequence. On average every consumer will get the same number of messages. This way of distributing messages is called round-robin. Try this out with three or more workers.

默认情况下,RabbitMQ 会依次给下一个消费者逐个发送消息。平均算下来,每一个消费者将获得相同数量的消息,这种分发消息的方式就被称作循环。好了,试一试开启 3 个或更多的工作单元吧。

Message acknowledgment 消息确认

Doing a task can take a few seconds. You may wonder what happens if one of the consumers starts a long task and dies with it only partly done. With our current code, once RabbitMQ delivers a message to the customer it immediately marks it for deletion. In this case, if you kill a worker we will lose the message it was just processing. We'll also lose all the messages that were dispatched to this particular worker but were not yet handled.

执行一项任务会用去一些时间,如果其中一个消费者启动了一个长任务并且执行到一部分就中止,你可能想知道究竟发生了什么。鉴于我们当前的代码,一旦 RabbitMQ 递送消息给消费者,它会立即将消息标记为删除。这样的话,如果你中止一个工作单元你将会失去正在运行中的消息。同时,我们也会失去所有已分发到当前指定工作单元中而未处理的消息。

But we don't want to lose any tasks. If a worker dies, we'd like the task to be delivered to another worker.

但是,我们并不希望失去任何任务,如果一个工作单元中止了,我们希望这个任务会被递送给另一个工作单元。

In order to make sure a message is never lost, RabbitMQ supports message acknowledgments. An ack(nowledgement) is sent back by the consumer to tell RabbitMQ that a particular message has been received, processed and that RabbitMQ is free to delete it.

为了确保一个消息永远不会丢失,RabbitMQ 提供了消息确认。消费者将回发一个 ack 标识来告知 RabbitMQ 指定的消息已被接收和处理,然后就可以放心的删除它。

If a consumer dies (its channel is closed, connection is closed, or TCP connection is lost) without sending an ack, RabbitMQ will understand 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 it to another consumer. That way you can be sure that no message is lost, even if the workers occasionally die.

如果一个消费者中止了(信道被关闭、连接被关闭,或者是 TCP 连接丢失),导致没有发送 ack 标识,RabbitMQ 将领会到该消息没有被完全处理,随后将对其重新分配。如果有其他的消息者同时在线,RabbitMQ 会迅速的重新递送该任务给另一个消息者。通过该方式,你就可以确信没有消息会被遗漏,即使这些工作单元偶然地中止。

There aren't any message timeouts; RabbitMQ will redeliver the message when the consumer dies. It's fine even if processing a message takes a very, very long time.

没有任何消息会出现超时,RabbitMQ 会在消费者中止时重新递送消息。即使运行一个消息会花去非常非常长的时间,它仍然可以运行良好。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfsdw.html