springboot项目中RabbitMq的使用

springboot项目中RabbitMq的使用

本文结合springboot项目,给出了几种队列的使用。spring版本是2.0.4.RELEASE。
首先需要的在pom中引入如下代码

   <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>

通用设置

  1. 配置文件 ;需要在application.yml配置文件中添加Mq的连接信息
    
     spring:
      rabbitmq:
        addresses: 134.***.**.121:5672
        username: admin
        password: 123456
        virtual-host: /
        connection-timeout: 15000
        listener:
          simple:
            acknowledge-mode: manual
            concurrency: 1
            max-concurrency: 1
    

简单队列

  1. 消费者代码

    public class MqListener {
        //1. 手动创建,需在RabbitMQ中手动创建myQueue1 队列,否则报错
        @RabbitListener(queues = "SimpleQueue")
        //@RabbitHandler   @RabbitListener 可以标注在类上面,需配合 @RabbitHandler 注解一起使用
        public void process1(String message){
            System.out.println("SimpleQueue:"+ message);
        }
        
        //2. 自动创建队列
        @RabbitListener(queuesToDeclare = @Queue("myQueue1"))
        //@RabbitHandler
        public void process2(String message){
            
            System.out.println("process2:"+ message);
        }
      }
    
  2. 生产者代码

    junit单元测试

    @Autowired
    private AmqpTemplate rabbitTemplate;
    
    @Test
    public void send() {
        String sendMsg = "hello1 simple queue " + new Date();
        System.out.println("Sender1 : " + sendMsg);
        this.rabbitTemplate.convertAndSend("SimpleQueue", sendMsg);
    }
    

单生产者多消费者(work)

一个生产者、2个消费者。
一个消息只能被一个消费者获取。

  • 消费者代码

    	@RabbitListener(queuesToDeclare  = @Queue(value = "MyWorkQueue", durable = "true"))
        //@RabbitHandler
        public void processWork(Message message, Channel channel){
    
            Map<String, Object> headers=message.getHeaders();
            String title=headers.get("title")==null?"":headers.get("title").toString();
    
    
            try {
                long deliveryTag = (long) headers.get(AmqpHeaders.DELIVERY_TAG);
    
                //当消息处理完毕,执行ACK
                channel.basicQos(0, 1, false);
                channel.basicAck(deliveryTag, false);
            } catch (IOException e) {
    
            }
            System.out.println("process2:"+ title);
        }
    
        //2. 自动创建队列
        @RabbitListener(queuesToDeclare  = @Queue(value = "MyWorkQueue", durable = "true"))
        //@RabbitHandler
        public void processWork2(Message message, Channel channel){
    
            Map<String, Object> headers=message.getHeaders();
            String title=headers.get("title")==null?"":headers.get("title").toString();
    
    
            try {
                long deliveryTag = (long) headers.get(AmqpHeaders.DELIVERY_TAG);
    
                //当消息处理完毕,执行ACK
                channel.basicQos(0, 1, false);
                channel.basicAck(deliveryTag, false);
            } catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println("process2:"+ title);
        }
    
  • 生产者代码

        @Test
        public void sendWork() {
            for(int i=0;i<100;i++){
                String message="这是RabbitMq发来的消息:  ";
                Map<String, Object> headers = new HashMap<>();
                headers.put("name", "zhangsan");
                headers.put("age", "18");
                headers.put("title", "苹果"+i);
                MessageHeaders messageHeaders = new MessageHeaders(headers);
                Message<Object> msg = MessageBuilder.createMessage(message, messageHeaders);
                this.rabbitTemplate.convertAndSend("MyWorkQueue",msg);
            }
        }
    

多生产者、多消费者同理。

订阅模式

订阅模式图例

  • 一个生产者对应多个消费者

  • 每一个消费者都有自己的队列,这些队列绑定到交换机上。

  • 生产者先将消息发送到交换机。

  • 生产者发送的消息,经过交换机,到达队列,实现,一个消息被多个消费者获取的目的

  • 消费者代码

    //消费队列1
    @RabbitListener(bindings = @QueueBinding(value = @Queue(value = "subQueue1", durable = "true"),
                exchange = @Exchange(value = "sub.Exchange", durable = "true", type = "fanout", ignoreDeclarationExceptions = "true")))
        @RabbitHandler
        public void subMessage(Message message, Channel channel) {
            System.out.println("message:" + message.getPayload());
            Map<String, Object> headers=message.getHeaders();
            String title=headers.get("title")==null?"":headers.get("title").toString();
            try {
                long deliveryTag = (long) message.getHeaders().get(AmqpHeaders.DELIVERY_TAG);
                System.out.println("deliveryTag: " + deliveryTag);
                //当消息处理完毕,执行ACK
                channel.basicQos(0, 1, false);
                channel.basicAck(deliveryTag, false);
            } catch (IOException e) {
    
            }
    
            System.out.println("订阅模式队列1");
        }
    
    //消费队列2
        @RabbitListener(bindings = @QueueBinding(value = @Queue(value = "subQueue2", durable = "true"),
                exchange = @Exchange(value = "sub.Exchange", durable = "true", type = "fanout", ignoreDeclarationExceptions = "true")))
        @RabbitHandler
        public void subMessage2(Message message, Channel channel) {
            System.out.println("message:" + message.getPayload());
            Map<String, Object> headers=message.getHeaders();
            String title=headers.get("title")==null?"":headers.get("title").toString();
            try {
                long deliveryTag = (long)headers.get(AmqpHeaders.DELIVERY_TAG);
                System.out.println("deliveryTag: " + deliveryTag);
                //当消息处理完毕,执行ACK
                channel.basicQos(0, 1, false);
                channel.basicAck(deliveryTag, false);
            } catch (IOException e) {
    
            }
    
            System.out.println("订阅模式队列2");
        }
    
    
  • 生产者代码

     @Test
        public void sendExchange() {
            String message="这是RabbitMq发来的消息:  ";
            Map<String, Object> headers = new HashMap<>();
            headers.put("name", "北京出版社");
            headers.put("title", "杂志订阅");
            MessageHeaders messageHeaders = new MessageHeaders(headers);
            Message<Object> msg = MessageBuilder.createMessage(message, messageHeaders);
            rabbitTemplate.convertAndSend("sub.Exchange","fanout",msg);//订阅模式
        }
    

路由模式

路由模式

  • 消费者代码
    //第一种规则 key 为red
     @RabbitListener(bindings = @QueueBinding(value = @Queue(value = "routeQueue1", durable = "true"),
            exchange = @Exchange(value = "route.Exchange", durable = "true", type = "direct", ignoreDeclarationExceptions = "true"),key = "red"))
    @RabbitHandler
    public void routeMessage1(Message message, Channel channel) {
        System.out.println("message:" + message.getPayload());
        Map<String, Object> headers=message.getHeaders();
        String title=headers.get("title")==null?"":headers.get("title").toString();
        try {
            long deliveryTag = (long)headers.get(AmqpHeaders.DELIVERY_TAG);
            System.out.println("deliveryTag: " + deliveryTag);
            //当消息处理完毕,执行ACK
            channel.basicQos(0, 1, false);
            channel.basicAck(deliveryTag, false);
        } catch (IOException e) {
    
        }
    
        System.out.println("路由模式1");
    }
    
    
    //第二种规则  有三种key
    @RabbitListener(bindings = @QueueBinding(value = @Queue(value = "routeQueue1", durable = "true"),
            exchange = @Exchange(value = "route.Exchange", durable = "true", type = "direct", ignoreDeclarationExceptions = "true"),key ={"blue","green","black"}))
    @RabbitHandler
    public void routeMessage2(Message message, Channel channel) {
        System.out.println("message:" + message.getPayload());
        Map<String, Object> headers=message.getHeaders();
        String title=headers.get("title")==null?"":headers.get("title").toString();
        try {
            long deliveryTag = (long)headers.get(AmqpHeaders.DELIVERY_TAG);
            System.out.println("deliveryTag: " + deliveryTag);
            //当消息处理完毕,执行ACK
            channel.basicQos(0, 1, false);
            channel.basicAck(deliveryTag, false);
        } catch (IOException e) {
    
        }
    
        System.out.println("路由模式2");
    }
    
  • 生产者代码
    @Test
        public void sendRouteExchange() {
            String message="这是RabbitMq发来的消息:  ";
            Map<String, Object> headers = new HashMap<>();
            headers.put("level", "等级一");
            headers.put("title", "红色");
            MessageHeaders messageHeaders = new MessageHeaders(headers);
            Message<Object> msg = MessageBuilder.createMessage(message, messageHeaders);
            rabbitTemplate.convertAndSend("route.Exchange","red",msg);//路由模式
    
            rabbitTemplate.convertAndSend("route.Exchange","blue",msg);//路由模式
            rabbitTemplate.convertAndSend("route.Exchange","black",msg);//路由模式
    
        }
    

主题模式

在这里插入图片描述

  • 消费者代码
    
    @RabbitListener(bindings = @QueueBinding(value = @Queue(value = "hd.toutiao.Queue", durable = "true"),
                exchange = @Exchange(value = "hd.toutiao.Exchange", durable = "true", type = "topic", ignoreDeclarationExceptions = "true"),
                key = "hd.toutiao.*"))
        @RabbitHandler
        public void onMessage(Message message, Channel channel) {
            System.out.println("message:" + message.getPayload());
            Map<String, Object> headers=message.getHeaders();
            String title=headers.get("title")==null?"":headers.get("title").toString();
            System.out.println(headers);
            System.out.println("channel:" + channel);
            try {
                long deliveryTag = (long) message.getHeaders().get(AmqpHeaders.DELIVERY_TAG);
                System.out.println("deliveryTag: " + deliveryTag);
                //当消息处理完毕,执行ACK
                logger.info("onMessage1:消息执行完毕准备ACK");
                channel.basicQos(0, 1, false);
                channel.basicAck(deliveryTag, false);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
  • 生产者代码
    public void send(Object message, Map<String, Object> properties) {
            MessageHeaders messageHeaders = new MessageHeaders(properties);
            Message<Object> msg = MessageBuilder.createMessage(message, messageHeaders);
          
    
            rabbitTemplate.convertAndSend("hd.toutiao.Exchange", "hd.toutiao.北京市", msg);
        }
    
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值