共计 2739 个字符,预计需要花费 7 分钟才能阅读完成。
Work Queues
In the first tutorial we wrote programs to send and receive messages from a named queue. In this one we’ll create a Work Queue that will be used to distribute time-consuming tasks among multiple workers.
在第一个教程中,咱们编写了从命名队列发送和接管音讯的程序。在这个示例中,咱们将创立一个工作队列,用于在多个 worker 之间调配耗时的工作。
The main idea behind Work Queues (aka: Task Queues) is to avoid doing a resource-intensive task immediately and having to wait for it to complete. Instead we schedule the task to be done later. We encapsulate a task as a message and send it to a queue. A worker process running in the background will pop the tasks and eventually execute the job. When you run many workers the tasks will be shared between them.
工作队列 (又名: 工作队列) 背地的次要思维是防止立刻执行一个资源密集型工作并不得不期待它实现。相同,咱们把工作安顿在稍后实现。咱们将工作封装为音讯并将其发送到队列。在后盾运行的工作过程将弹出工作并最终执行工作。当您运行许多 worker 时,工作将在它们之间共享。
This concept is especially useful in web applications where it’s impossible to handle a complex task during a short HTTP request window.
这个概念在 web 应用程序中特地有用,在 web 应用程序中不可能在短 HTTP 申请窗口期间解决简单的工作。
Preparation 筹备
In the previous part of this tutorial we sent a message containing “Hello World!”. Now we’ll be sending strings that stand for complex tasks. We don’t have a real-world task, like images to be resized or pdf files to be rendered, so let’s fake it by just pretending we’re busy – by using the Thread.sleep() function. We’ll take the number of dots in the string as its complexity; every dot will account for one second of “work”. For example, a fake task described by Hello… will take three seconds.
在本教程的前一部分中,咱们发送了一个蕴含“Hello World!”的音讯。当初咱们会发送代表简单工作的字符串。咱们没有理论的工作,比方要调整大小的图像或要渲染的 pdf 文件,所以让咱们伪装很忙来模仿它——通过应用 Thread.sleep()函数。咱们将字符串中点的数量作为它的复杂度; 每个点将占一秒的“工作”。例如,Hello…形容的一个假工作。只须要三秒钟。
Fair dispatch 调度
You might have noticed that the dispatching still doesn’t work exactly as we want. For example in a situation with two workers, when all odd messages are heavy and even messages are light, one worker will be constantly busy and the other one will do hardly any work. Well, RabbitMQ doesn’t know anything about that and will still dispatch messages evenly.
您可能曾经留神到分派依然不能齐全依照咱们的要求工作。例如,如果有两个员工,当所有奇怪的音讯都很重,甚至音讯都很轻时,一个员工会始终很忙,而另一个人简直什么工作都不做。好吧,RabbitMQ 对此无所不知,它依然会平均地分派音讯。
This happens because RabbitMQ just dispatches a message when the message enters the queue. It doesn’t look at the number of unacknowledged messages for a consumer. It just blindly dispatches every n-th message to the n-th consumer.
这是因为 RabbitMQ 只在音讯进入队列时发送音讯。它不查看用户未确认音讯的数量。它只是自觉地将每条第 n 个音讯分派给第 n 个消费者。
.webp)
In order to defeat that we can use the basicQos method with the prefetchCount = 1 setting. This tells RabbitMQ not to give more than one message to a worker at a time. Or, in other words, don’t dispatch a new message to a worker until it has processed and acknowledged the previous one. Instead, it will dispatch it to the next worker that is not still busy.
为了克服这个问题,咱们能够应用设置为 prefetchCount = 1 的 basicQos 办法。这通知 RabbitMQ 一次不要给一个 worker 发送一条以上的音讯。或者,换句话说,在 worker 解决并确认前一个音讯之前,不要向它发送新音讯。相同,它将把它分派到下一个不忙碌的 worker。
Note about queue size