2. Workqueues Task Force column mode:
On the previous blog we completed a simple send and receive message program for the claims queue. Below we will create a work queue to distribute time-consuming tasks to multiple workers (consumer).
Today we look at the Work queue (aka: Task queue). The main purpose is to avoid the immediate task of being a resource-intensive but waiting to be completed. Instead, we do task scheduling: encapsulate the task as a message and send it to the queue. The worker running in the background (consumer) takes it out and executes it eventually. When you run multiple workers (consumer), the tasks in the queue are worked on for shared execution.
The message distribution mechanism for the task queue is divided into two types: polling distribution (round-robin) and fair distribution (Fair Dispatch).
Get ready
Use the Thread.Sleep () method to simulate time-consuming.
2.1 Poll Distribution
One of the advantages of using task queues is that you can easily work in parallel. If we have a lot of work backlog, we can solve this problem by increasing the number of workers (consumers), making the system easier to scale. By default, RABBITMQ will send messages one at a time to the next consumer in the sequence (regardless of the duration of each task, and so on, and is allocated in advance, not an allocation). Average per consumer Gets the same number of messages. This way of distributing the message mechanism is called round-robin (polling).
Message production-side code:
Package cn.rabbitmq.work;
Import Cn.rabbitmq.util.ConnectionUtil;
Import Com.rabbitmq.client.Channel;
Import com.rabbitmq.client.Connection; /** * Work Queue mode producer * * @author Administrator * */public class Worksend {private final static String queue_name =
"Hellowork"; public static void Main (string[] argv) throws Exception {//Get to Connection and MQ channel Connection Connection = Connectio
Nutil.getconnection ();
Channel channel = Connection.createchannel (); <span style= "White-space:pre" > </span>//at the same time the server will only send a message to the consumer //Channel.basicqos
(1);
Declaration Queue Channel.queuedeclare (Queue_name, False, False, false, NULL);
for (int i = 0; i < i++) {//message content String message = "" + I;
Channel.basicpublish ("", queue_name, NULL, message.getbytes ());
System.out.println ("[X] Sent '" + Message + "'");
Thread.Sleep (i * 10); } channel.close ();
Connection.close (); }
}
Message Consumer code (copy two copies are started):
Package cn.rabbitmq.work;
Import Cn.rabbitmq.util.ConnectionUtil;
Import Com.rabbitmq.client.Channel;
Import com.rabbitmq.client.Connection;
Import Com.rabbitmq.client.QueueingConsumer; /** * Working queue mode Consumer 2 * * @author Administrator * */public class WorkRecv2 {private final static String queue_name
= "Hellowork"; public static void Main (string[] argv) throws Exception {//Get to Connection and MQ channel Connection Connection = Connecti
Onutil.getconnection ();
Channel channel = Connection.createchannel ();
Declaration Queue Channel.queuedeclare (Queue_name, False, False, false, NULL);
Define the queue's consumer queueingconsumer consumer = new Queueingconsumer (channel);
Listen queue, manually return to completion status Channel.basicconsume (Queue_name, false, consumer);
Gets the message while (true) {Queueingconsumer.delivery Delivery = Consumer.nextdelivery ();
String message = new String (Delivery.getbody ()); System.out.println ("[x] Received ' "+ Message +" ' ");
Sleep 1 seconds thread.sleep (1000);
Channel.basicack (Delivery.getenvelope (). Getdeliverytag (), false);
}
}
}
The result is that no matter who is busy or idle, will not give one more task or less a task, the task is always you one of my assignment.
2.1 Fair Distribution
Although the above method of allocation is also OK, but there is a problem: for example: Now there are 2 consumers, all the odd messages are busy, and the even is easy. By polling, the odd task was handed to the first consumer, so he kept busy. An even-numbered task is handed to another consumer, and the task is completed immediately, and then idle. And RABBITMQ is not aware of this. This is because when the message enters the queue, RABBITMQ dispatches the message. It does not look at the number of consumers as a response, but blindly sends the message to the designated consumer for polling.
To solve this problem, we use the Basicqos (Prefetchcount = 1) method to limit the message to the same consumer that the RABBITMQ only sends no more than 1 messages. After the message has been processed, there is feedback before it is sent for the second time.
Comment out the following line of code in the production code of the above message to release the comment and execute again.
Channel.basicqos (1);
Note: If all the workers are busy, your queue may be filled in. You may observe the usage of the queue, then increase the worker, or use any other strategy.
It is also important to note that with fair distribution, automatic replies must be turned off and manually answered instead. The content will be described later.
http://blog.csdn.net/xiaoxian8023/article/details/48681987