Work Queues
工作队列(又称任务队列)的主要思想是避免立即执行资源密集型任务,而不得不等待它完成。相反我们安排任务在之后执行。我们把任务封装为消息并将其发送到队列。在后台运行的工作进程将弹出任务并最终执行作业。 当有多个工作线程时,这些工作线程将一起处理这些任务。
一条消息只能被处理一次,不可以处理多次。
代码实现-轮询分发消息
在这个案例中我们会启动两个工作线程,一个消息发送线程,我们来看看他们两个工作线程是如何工作的。
抽取工具类
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class RabbitMqUtils {
//得到一个连接的 channel
public static Channel getChannel() throws Exception{
//创建一个连接工厂
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("192.168.235.128");
factory.setUsername("admin");
factory.setPassword("123456");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
return channel;
}
}
工作线程代码
/**
* 工作线程
*/
public class Worker01 {
// 消息队列名称
public static final String QUEUE_NAME = "hello";
public static void main(String[] args) throws Exception {
Channel channel = RabbitMqUtils.getChannel();
//消费者未成功消费的回调
DeliverCallback deliverCallback = (consumerTag, message) ->{
System.out.println(new String(message.getBody()));
};
//消费者取消消费的回调
CancelCallback cancelCallback = (consumerTag) ->{
System.out.println("消费消息中断。。。");
};
// 接收消息
/**
* 要消费的队列
* 消费后是否自动应答
* 消费者未成功消费的回调
* 消费者取消消费的回调
*/
System.out.println("Q1等待接收消息");
channel.basicConsume(QUEUE_NAME,true,deliverCallback,cancelCallback);
}
}
并在idea中设置允许并行运行
生产者代码
import com.rabbitmq.client.Channel;
import com.xiang.rabbitmq.util.RabbitMqUtils;
import java.util.Scanner;
/**
* 生产者
*/
public class Task01 {
private static final String QUEUE_NAME="hello";
public static void main(String[] args) throws Exception {
try(Channel channel= RabbitMqUtils.getChannel();) {
channel.queueDeclare(QUEUE_NAME,false,false,false,null);
//从控制台当中接收信息
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()){
String message = scanner.next();
channel.basicPublish("",QUEUE_NAME,null,message.getBytes());
System.out.println("发送消息完成:"+message);
}
}
}
}
启动
发送一条消息
Q1队列接收到消息
在此发送一条消息
发现是Q2接收到了消息
结论
通过程序执行发现生产者总共发送 4 个消息,消费者 1 和消费者 2 分别分得两个消息,并且是按照有序的一个接收一次消息。