RabbitMq worker Round-Robin
RabbitMq的轮询模式不会因为机器的带宽不同而导致不对等消费 比如A 处理需要10ms,B处理需要1000ms ,两个消费者去消费20条会各消费10条
以下demo实现了均衡消费
package com.wangbiao.work.lunxun;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* TODO
*
* @author wangbiao
* @Title TODO
* @module TODO
* @description rout 路由
* @date 2021/3/22 21:54
*/
public class Producer {
public static void main(String[] args) throws IOException, TimeoutException {
//所有的中间件的技术都是基于tcp/ip协议 ,只不过rabbitmq遵循的是amqp
//1创建工程连接
ConnectionFactory connectionFactory=new ConnectionFactory();
connectionFactory.setHost("127.0.0.1");
connectionFactory.setPort(5672);
connectionFactory.setPassword("guest");
connectionFactory.setUsername("guest");
connectionFactory.setVirtualHost("/");
Connection connection=null;
Channel channel=null;
//2创建连接 基于channel处理的原因是长连接 高并发的场景下会创建多个通道性能很高 如果是基于连接就会产生3次挥手等行为 很消耗性能
try {
connection=connectionFactory.newConnection("生产者");
//3通过连接获取通道
channel=connection.createChannel();
for (int i = 0; i <=20 ; i++) {
String msg="我要变强:"+i;
channel.basicPublish("","queue1",null,msg.getBytes());//默认是rabbit-AMQP默认的direct直连路由
}
System.out.println("消息发送成功");
} catch (IOException e) {
e.printStackTrace();
System.out.println("消息发送异常");
} catch (TimeoutException e) {
e.printStackTrace();
}finally {
//7关闭连接
if(channel!=null&&channel.isOpen()){
channel.close();
}
//8关闭通道
if(connection!=null&&connection.isOpen()){
connection.close();
}
}
}
}
消费者1:
package com.wangbiao.work.lunxun;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.TimeoutException;
/**
* TODO
*
* @author wangbiao
* @Title TODO
* @module TODO
* @description TODO
* @date 2021/3/22 22:28
*/
public class Worker1 {
public static Runnable runable=new Runnable() {
@Override
public void run() {
//所有的中间件的技术都是基于tcp/ip协议 ,只不过rabbitmq遵循的是amqp
//1创建工程连接
ConnectionFactory connectionFactory=new ConnectionFactory();
connectionFactory.setHost("127.0.0.1");
connectionFactory.setPort(5672);
connectionFactory.setPassword("guest");
connectionFactory.setUsername("guest");
connectionFactory.setVirtualHost("/");
Connection connection=null;
Channel channel=null;
//获取队列名字
final String queueName=Thread.currentThread().getName();
//2创建连接工程
try {
connection=connectionFactory.newConnection("消费者-worker1");
//3通过连接获取通道
channel=connection.createChannel();
//4通过创建交换机,生命队列,绑定关系,路由key,发送消息,和接收消息
/**
* 队列的名字
* 是否要持久化 所谓是否持久化消息是否存盘,false 非持久化 true持久化?非持久化会存盘?会存盘但随着服务器重启会丢失
* 是否自动删除,最后一个消息完毕以后是否把队列自动删除
* 队列的参数
*/
channel.basicConsume(queueName, true,new DeliverCallback(){//实际业务中要改为false 因为如果设置为true一旦消息确认失败会造成死循环。
//为false就是要手动确认避免死信队列
public void handle(String consumerTag,Delivery message) throws UnsupportedEncodingException {
System.out.println(message.getEnvelope().getDeliveryTag());
System.out.println(queueName+"收到的消息是:"+new String(message.getBody(),"utf-8"));
}
},new CancelCallback(){
public void handle(String consumerTag) throws UnsupportedEncodingException {
System.out.println(queueName+"接收失败了");
}
});
System.in.read();
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}finally {
//7关闭连接
if(channel!=null&&channel.isOpen()){
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
//8关闭通道
if(connection!=null&&connection.isOpen()){
try {
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
};
public static void main(String[] args) throws IOException, TimeoutException {
new Thread(runable,"queue1").start();
}
}
消费者2:
package com.wangbiao.work.lunxun;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.TimeoutException;
/**
* TODO
*
* @author wangbiao
* @Title TODO
* @module TODO
* @description TODO
* @date 2021/3/22 22:28
*/
public class Worker2 {
public static Runnable runable=new Runnable() {
@Override
public void run() {
//所有的中间件的技术都是基于tcp/ip协议 ,只不过rabbitmq遵循的是amqp
//1创建工程连接
ConnectionFactory connectionFactory=new ConnectionFactory();
connectionFactory.setHost("127.0.0.1");
connectionFactory.setPort(5672);
connectionFactory.setPassword("guest");
connectionFactory.setUsername("guest");
connectionFactory.setVirtualHost("/");
Connection connection=null;
Channel channel=null;
//获取队列名字
final String queueName=Thread.currentThread().getName();
//2创建连接工程
try {
connection=connectionFactory.newConnection("消费者-worker1");
//3通过连接获取通道
channel=connection.createChannel();
//4通过创建交换机,生命队列,绑定关系,路由key,发送消息,和接收消息
/**
* 队列的名字
* 是否要持久化 所谓是否持久化消息是否存盘,false 非持久化 true持久化?非持久化会存盘?会存盘但随着服务器重启会丢失
* 是否自动删除,最后一个消息完毕以后是否把队列自动删除
* 队列的参数
*/
// channel.basicQos(1);
channel.basicConsume(queueName, true,new DeliverCallback(){
public void handle(String consumerTag,Delivery message) throws UnsupportedEncodingException {
System.out.println(message.getEnvelope().getDeliveryTag());
System.out.println(queueName+"收到的消息是:"+new String(message.getBody(),"utf-8"));
}
},new CancelCallback(){
public void handle(String consumerTag) throws UnsupportedEncodingException {
System.out.println(queueName+"接收失败了");
}
});
System.in.read();
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}finally {
//7关闭连接
if(channel!=null&&channel.isOpen()){
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
//8关闭通道
if(connection!=null&&connection.isOpen()){
try {
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
};
public static void main(String[] args) throws IOException, TimeoutException {
new Thread(runable,"queue1").start();
}
}


可以看到两个消费者依次消费:1,3,5,7.。。。。0,。和0,2,4,6,8.。 实现均衡消费
本文来自博客园,作者:余生请多指教ANT,转载请注明原文链接:https://www.cnblogs.com/wangbiaohistory/p/14574986.html

浙公网安备 33010602011771号