RabbitMq系列(三):工作队列

系列文章

RabbitMq系列(一):服务器搭建

RabbitMq系列(二):最简单的例子

RabbitMq系列(三):工作队列

RabbitMq系列(四):消息确认和持久性

RabbitMq系列(五):公平派遣

RabbitMq系列(六):交换类型以及例子

RabbitMq系列(七):直接交换Direct exchange

RabbitMq系列(八):扇出交换Fanout Exchange

RabbitMq系列(九):主题交换Topic Exchange

RabbitMq系列(十):标头交换Headers exchange

RabbitMq系列(十一):远程调用RPC

 

目录

前言

工作队列


前言

RabbitMq系列(二):最简单的例子编写了一个最简单的例子来进行消息通信的测试,其只有一个生产者和一个消费者。这里我们使用工作队列(Work Queue)来进行一个生产者多个消费者的测试。

工作队列(Work Queue)主要思想是避免执行密集性任务,将任务放在以后执行。在我们将消息放在队列中时,我们可以启用多个消费者进行消费,他们之间共享消息(一个消息仅被消费一次)

工作队列

工作队列不但能轻松并行化工作,还能够根据需求扩展,能满足大部分业务的处理速度和应用场景,在spring里面,还封装有相关的配置,例如:空闲消费者数和最大消费者数等等,下面运行两个消费者,代码都一样。

  • 消费者1

/**
 * 消费者1
 *
 * @Tag 工厂队列
 */
public class MQConsumerOne {

    public static void main(String[] args) {
        try {
            consumerMsg("work.queue");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 消费消息
     * @param queue
     */
    public static void consumerMsg(String queue) throws IOException, TimeoutException {
        //创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        //设置代理地址
        connectionFactory.setHost("192.168.239.128");
        //设置连接端口(默认配置)
        connectionFactory.setPort(5672);
        //设置连接用户(默认配置)
        connectionFactory.setUsername("guest");
        //设置连接密码(默认配置)
        connectionFactory.setPassword("guest");
        //设置连接虚拟机(默认配置)
        connectionFactory.setVirtualHost("/");
        //创建连接
        Connection  connection = connectionFactory.newConnection();
        //创建通道
        Channel  channel = connection.createChannel();
        //声明交换机
        channel.exchangeDeclare("work.exchange", BuiltinExchangeType.DIRECT,false,true,null);
        //声明队列
        channel.queueDeclare(queue,false,false,true,null);
        //绑定队列
        channel.queueBind(queue,"work.exchange","");
        //创建消费者
        channel.basicConsume(queue,true,(consumerTag,message)->{
            //打印消息
            try {
                Thread.sleep(Math.round(Math.random()*2000)+1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(new String(message.getBody(),"UTF-8"));
        },(consumerTag) -> {
            //打印用户标记
            System.out.println(consumerTag);
        });
        //关闭连接
       /* channel.close();
        connection.close();*/
    }
}

 

  • 消费者2
**
 * 消费者2
 *
 * @Tag 工厂队列
 */
public class MQConsumerTwo {

    public static void main(String[] args) {
        try {
            consumerMsg("work.queue");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 消费消息
     * @param queue
     */
    public static void consumerMsg(String queue) throws IOException, TimeoutException {
        //创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        //设置代理地址
        connectionFactory.setHost("192.168.239.128");
        //设置连接端口(默认配置)
        connectionFactory.setPort(5672);
        //设置连接用户(默认配置)
        connectionFactory.setUsername("guest");
        //设置连接密码(默认配置)
        connectionFactory.setPassword("guest");
        //设置连接虚拟机(默认配置)
        connectionFactory.setVirtualHost("/");
        //创建连接
        Connection  connection = connectionFactory.newConnection();
        //创建通道
        Channel  channel = connection.createChannel();
        //声明交换机
        channel.exchangeDeclare("work.exchange", BuiltinExchangeType.DIRECT,false,true,null);
        //声明队列
        channel.queueDeclare(queue,false,false,true,null);
        //绑定队列
        channel.queueBind(queue,"work.exchange","");
        //创建消费者
        channel.basicConsume(queue,true,(consumerTag,message)->{
            //打印消息
            try {
                Thread.sleep(Math.round(Math.random()*20000)+1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(new String(message.getBody(),"UTF-8"));
        },(consumerTag) -> {
            //打印用户标记
            System.out.println(consumerTag);
        });
        //关闭连接
        /* channel.close();
           connection.close();
        */
    }
}

 

      1)  exchange (交换机,类似家里面的路由器)

     2) queue (队列,消息缓存所在,下面是点进去的展示)

 

  • 生产者(部分配置有默认值,可以不写)
/**
 * 生产者
 *
 * @Tag 工厂队列
 */

public class MQProducer {

    public static void main(String[] args) {

        for (int count=0;count<10;count++)
        {
            try {
                produceMsg("work.queue","来啦,老弟!我是你老姐"+count);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static  void produceMsg(String queue,String msg) throws IOException, TimeoutException {
        //创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        //设置代理地址
        connectionFactory.setHost("192.168.239.128");
        //创建连接
        Connection connection = connectionFactory.newConnection();
        //创建通道
        Channel channel = connection.createChannel();
        //声明交换机
        channel.exchangeDeclare("work.exchange", BuiltinExchangeType.DIRECT,false,true,null);
        //创建生产者
        channel.basicPublish("work.exchange","",null, msg.getBytes());
        //关闭连接
        channel.close();
        connection.close();
    }
}

 生产者不关心自己的消息被谁使用,怎么样使用,所以不会绑定队列 

 

  • 为了方便测试写一个简单的循环发送消息

        for (int count=0;count<10;count++)
        {
            try {
                produceMsg("work.queue","来啦,老弟!我是你老姐"+count);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
  • 运行生产者,查看结果

可以很明显的看出来,消息是在两个消费者之间轮询消费的,简称循环调用(Round-robin dispatching),轮询模式是工作队列默认的模式,除此之外还有单一消费者模式,这个需要在声明队列的时候传参。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值