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.。  实现均衡消费

posted @ 2021-03-24 20:16  余生请多指教ANT  阅读(0)  评论(0编辑  收藏  举报