RabbitMq集成SpirngBoot

7 篇文章 0 订阅
4 篇文章 0 订阅
rabbitmq不会创建队列
rabbitmq是懒加载 必须配置监听者才能 创建队列

延迟队列配置

在这里插入图片描述

配置

1.引入依赖

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

2.配置yml

spring.rabbitmq.host=**.**.**.**你的主机地址
spring.rabbitmq.port=5672

在这里插入图片描述

队列配置

package com.cunk.blog.rabbitMq;


import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class TtlQueueConfig  {

    //普通交换机
    public static final String DEADLATER_EXCHANEG = "X_E" ;
    //死信交换机
    public static final String NORMOLL_EXCHANEG = "Y_E" ;
    //普通队列1
    public static final String NORMOLL_Q1 = "N_Q1" ;

    //普通队列2
    public static final String NORMOLL_Q2 = "N_Q2" ;

    //死信队列
    public static final String DEADLATER_Q = "T_Q" ;

    @Bean(NORMOLL_EXCHANEG)
    public DirectExchange xExchage(){
        return new DirectExchange(NORMOLL_EXCHANEG) ;
    }

   //死信交换机
    @Bean(DEADLATER_EXCHANEG)
    public DirectExchange yExchage(){
        return new DirectExchange(DEADLATER_EXCHANEG) ;
    }

   //声明普通队列TTL 为 10 s q1
    @Bean(NORMOLL_Q1)
    public Queue queueA(){
        HashMap<String, Object> arguments = new HashMap<>();
        arguments.put("x-dead-letter-exchange", DEADLATER_EXCHANEG);// 死信路由
        arguments.put("x-dead-letter-routing-key", "YD");// 死信路由键
        arguments.put("x-message-ttl", 10000); // 消息过期时间 10s
        return new Queue(NORMOLL_Q1, true, false, false, arguments);
    }

    //声明普通队列TTL 为 10 s q2
    @Bean(NORMOLL_Q2)
    public Queue queueB(){
        HashMap<String, Object> arguments = new HashMap<>();
        arguments.put("x-dead-letter-exchange", DEADLATER_EXCHANEG);// 死信路由
        arguments.put("x-dead-letter-routing-key", "YD");// 死信路由键
        arguments.put("x-message-ttl", 20000); // 消息过期时间 10s

        return new Queue(NORMOLL_Q2, true, false, false, arguments);
    }

    //死信队列
    @Bean(DEADLATER_Q)
    public Queue queueD(){
        return QueueBuilder.durable(DEADLATER_Q).build();
    }

    /====绑定======///

    //q1 q2 绑定

    @Bean
    public Binding bindingEmail(@Qualifier(NORMOLL_Q1) Queue queue,
                                @Qualifier(NORMOLL_EXCHANEG) Exchange exchange){
        return BindingBuilder.bind(queue).to(exchange).with("XA").noargs();
    }


    @Bean
    public Binding q2BingExchange(@Qualifier(NORMOLL_Q2) Queue q2
            , @Qualifier(NORMOLL_EXCHANEG) Exchange e1){
        return BindingBuilder.bind(q2).to(e1).with("XB").noargs();
    }

    @Bean
    public Binding qdBingExchange(@Qualifier(DEADLATER_Q) Queue qd
            , @Qualifier(DEADLATER_EXCHANEG) Exchange e1){
        return BindingBuilder.bind(qd).to(e1).with("YD").noargs();
    }

}

生产者

   @GetMapping("/sendMsg/{msg}")
    public void sendMsg(@PathVariable("msg") String msg){
        System.out.println("发送当前时间"+new Date().toString()+msg);

        //发送消息
        rabbitTemplate.convertAndSend(NORMOLL_EXCHANEG,"XA","消息来自10sttl队列"+msg);

        rabbitTemplate.convertAndSend(NORMOLL_EXCHANEG,"XB","消息来自20sttl队列"+msg);

    }

消费者

    @GetMapping("/getMsg")
    @RabbitListener(queues ={DEADLATER_Q})
    public void  getMsg(Message message, Channel channel)throws Exception{
        String msg = new String(message.getBody());
        System.out.println("当前时间"+new Date().toString()+"收到的死信队列消息是"+msg);

    }

结果

在这里插入图片描述

在这里插入图片描述

延迟队列优化( 消息设置超时,队列不设置超时时间)

生成者根据需求对消息进行超时进入死信队列

 //声明普通队列 , 不设置过期时间
    @Bean(NORMOLL_Q3)
    public Queue queueC(){
        HashMap<String, Object> arguments = new HashMap<>();
        arguments.put("x-dead-letter-exchange", DEADLATER_EXCHANEG);// 死信路由
        arguments.put("x-dead-letter-routing-key", "YD");// 死信路由键
     //   arguments.put("x-message-ttl", 20000); // 消息过期时间 10s
        return new Queue(NORMOLL_Q3, true, false, false, arguments);
    }

消息设置过期时间

        rabbitTemplate.convertAndSend(NORMOLL_EXCHANEG, "XC", "消息来自自定义消息时间的队列" + msg
                , new MessagePostProcessor() {
                    @Override
                    public Message postProcessMessage(Message message) throws AmqpException {
                        message.getMessageProperties().setExpiration({**过期时间**});
                     return message ;
                    }
                });

⚠ 如果过期时间是10s 的先进队列 ,过期时间5s 的后进队列 (5s过期的消息进入阻塞,先等10s的发完)
出队顺序是 10s的先出 5s 的反而后出 (队列有先进先出的规定!!)
在这里插入图片描述

延迟问题的解决

下载延迟插件以及安装步骤
链接: link
基于插件和基于队列的延迟不一样

基于延迟交换机的延迟队列

配置


import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;

//基于交换机的延迟队列
@Configuration
public class DelatedQueueConfig {
    //交换机
    public static final String DEADLATER_AUTO_EXCHANEG = "D_E" ;
    //延迟队列
    public static final String DELAYED_EXCHANGE_QUEUE ="D_Q" ;

    //key
    public static final String DELAYED_ROUNTING_KEY = "DelayRountKey" ;

    @Bean(DEADLATER_AUTO_EXCHANEG)
    public CustomExchange daleyExchange(){

        HashMap<String, Object> arguments = new HashMap<>();
      //设置延迟类型为直接类型
        arguments.put("x-delayed-type","direct");

        return new CustomExchange(DEADLATER_AUTO_EXCHANEG,"x-delayed-message"
                 ,true,false,arguments
                );
    }

    @Bean(DELAYED_EXCHANGE_QUEUE)
    public Queue queueB(){
        return new Queue(DELAYED_EXCHANGE_QUEUE, true, false, false);
    }

    @Bean
    public Binding bindingEmail(@Qualifier(DELAYED_EXCHANGE_QUEUE) Queue queue,
                                @Qualifier(DEADLATER_AUTO_EXCHANEG) Exchange exchange){
        return BindingBuilder.bind(queue).to(exchange).with(DELAYED_ROUNTING_KEY).noargs();
    }
}

生产者和消费者

   //交换机
    public static final String DEADLATER_AUTO_EXCHANEG = "D_E" ;
    //延迟队列
    public static final String DELAYED_EXCHANGE_QUEUE ="D_Q" ;

    //key
    public static final String DELAYED_ROUNTING_KEY = "DelayRountKey" ;


    //生产者
    @GetMapping("/sendExchangeMsg/{msg}/{ttl}")
    public void sendDelayExchange111(@PathVariable("msg") String msg,@PathVariable("ttl") Integer ttl){
        System.out.println("发送当前时间"+new Date().toString()+msg);
        rabbitTemplate.convertAndSend(DEADLATER_AUTO_EXCHANEG, DELAYED_ROUNTING_KEY, "消息来自自定义消息时间的队列" + msg
                ,message -> {
                    //设置过期时间
                        message.getMessageProperties().setDelay(ttl);
                        return message ;
                    }
              );
    }

    //消费者
    @GetMapping("/getMsg")
    @RabbitListener(queues ={DELAYED_EXCHANGE_QUEUE})
    public void  getMsg111(Message message, Channel channel)throws Exception{
        String msg = new String(message.getBody());
        System.out.println("当前时间"+new Date().toString()+"收到的基于插件的延迟消息消息是"+msg);

    }

运行结果

在这里插入图片描述

配置

在这里插入图片描述

    publisher-confirm-type: correlated
    # 开启发送端抵达队列确认,消息未被队列接收时触发回调【发送端确认机制+本地事务表】
    publisher-returns: true
    # 消息在没有被队列接收时是否强行退回
    template:
      mandatory: true
    # 消费者手动确认模式,关闭自动确认,否则会消息丢失
    listener:
      simple:
        acknowledge-mode: manual

回调配置

package com.cunk.blog.config;


import org.springframework.amqp.core.ReturnedMessage;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

//设置接口回调
@Configuration
public class RabbitMqConfig {

/*  这是 FastJson 的消息转换器
   @Bean
    public FastJsonHttpMessageConverter  messageConverter() {
        // 使用json序列化器来序列化消息,发送消息时,消息对象会被序列化成json格式
        return new FastJsonHttpMessageConverter();
    }
*/
    @Bean
    public MessageConverter messageConverter() {
        // 使用json序列化器来序列化消息,发送消息时,消息对象会被序列化成json格式
        return new Jackson2JsonMessageConverter();
    }

    @Bean
    public RabbitTemplate createRabbitTemplate(ConnectionFactory connectionFactory)
    {
        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        rabbitTemplate.setConnectionFactory(connectionFactory);
        //设置开启Mandatory,才能触发回调函数,无论消息推送结果怎么样都强制调用回调函数
        rabbitTemplate.setMandatory(true);
        
        //确认消息送到交换机(Exchange)回调
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback()
        {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause)
            {
                System.out.println("\n确认消息送到交换机(Exchange)结果:");
                System.out.println("相关数据:" + correlationData);
                System.out.println("是否成功:" + ack);
                System.out.println("错误原因:" + cause);
            }
        });

        //消息没有被队列接受的时候会触发回调
        //确认消息送到队列(Queue)回调
      
 /* 这里的代码在2022.8.3 月不能使用了      
   rabbitTemplate.setReturnsCallback(new RabbitTemplate.ReturnsCallback()
        {
            @Override
            public void returnedMessage(ReturnedMessage returnedMessage)
            {
                System.out.println("\n确认消息送到队列(Queue)结果:");
                System.out.println("发生消息:" + returnedMessage.getMessage());
                System.out.println("回应码:" + returnedMessage.getReplyCode());
                System.out.println("回应信息:" + returnedMessage.getReplyText());
                System.out.println("交换机:" + returnedMessage.getExchange());
                System.out.println("路由键:" + returnedMessage.getRoutingKey());
            }
        });*/
  //消息没有被队列接受的时候会触发回调
        //确认消息送到队列(Queue)回调
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback()
        {
            @Override
            public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey)
            {
                log.error("returnedMessage ===> replyCode={} ,replyText={} ,exchange={} ,routingKey={}", replyCode,
                        replyText, exchange, routingKey);
                  }
        });
        return rabbitTemplate;
    }
}



欣赏下雷神的代码~~
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值