SpringBoot整合RabbitMQ

导入依赖


    com.fasterxml.jackson.core
    jackson-databind
    2.10.2


    org.springframework.boot
    spring-boot-starter-amqp
    2.2.5.RELEASE

配置application.yml文件

 spring:
  jackson:
    date-format: yyyy-MM-dd
    time-zone: GMT+8
  rabbitmq:
    host: 192.168.31.14
    port: 5672
    username: hello
    password: 123456
    virtual-host: /myhost
    listener:
      simple:
        acknowledge-mode: manual  # 消费者手动签收消息
        prefetch: 10  #表示消费者一次从队列中处理10条数  (100-->10次)
    #消息发送到交换机确认机制,是否确认回调
    #如果没有本条配置信息,当消费者收到生产者发送的消息后,生产者无法收到确认成功的回调信息
    publisher-confirm-type: correlated

写配置类

@Configuration
public class RabbitMQConfig {

    RabbitTemplate.ReturnCallback returnCallback = new RabbitTemplate.ReturnCallback() {
        @Override
        public void returnedMessage(Message message, int i, String s, String s1, String s2) {
            System.out.println("返回的错误编码:"+i);
            System.out.println("返回的消息:"+s);
            System.out.println("交换机:"+s1);
            System.out.println("路由key:"+s2);
        }
    };

    RabbitTemplate.ConfirmCallback confirmCallback = new RabbitTemplate.ConfirmCallback() {
        @Override
        public void confirm(CorrelationData correlationData, boolean b, String s) {
            if(b){
                System.out.println("交换机成功收到消息");
            }
            if(!b){
                System.out.println("拒收的原因:"+s);
            }
        }
    };

    @Bean//配置模板对象
    public RabbitTemplate rabbitTemplate(ConnectionFactory factory){
        RabbitTemplate template = new RabbitTemplate();
        //配置消息转换器
        template.setMessageConverter(messageConverter());
        //配置连接工厂
        template.setConnectionFactory(factory);
        //配置队列监听
        template.setReturnCallback(returnCallback);
        //配置交换机监听
        template.setConfirmCallback(confirmCallback);
        //消息强制退回
        template.setMandatory(true);
        return template;
    }

	//配置队列消息发送格式
    public Jackson2JsonMessageConverter messageConverter(){
        return new Jackson2JsonMessageConverter();
    }

    @Bean//配置队列超时发送至死信交换机
    public Queue payOrderQueue(){
        //配置参数
        Map args = new HashMap<>();
        args.put("x-dead-letter-exchange","pay_order_dead_exchange");
        //配置路由key
        args.put("x-dead-letter-routing-key","pay.order.dead");
        //配置死亡时间30秒
        args.put("x-message-ttl",30000);
        return new Queue("pay_order_queue",true,false,false,args);
    }

    @Bean//配置交换机
    public TopicExchange payOrderExchange(){
        return new TopicExchange("pay_order_exchange");
    }

    @Bean//绑定交换机和队列
    public Binding bindPayOrderQueue(){
        return BindingBuilder.bind(payOrderQueue()).to(payOrderExchange()).with("pay.#");
    }

    @Bean//配置死信交换机
    public TopicExchange payOrderDeadExchange(){
        return new TopicExchange("pay_order_dead_exchange");
    }

    @Bean//配置死信队列
    public Queue payOrderDeadQueue(){
        return new Queue("pay_order_dead_queue",true,false,false);
    }

    @Bean//绑定死信队列和死信交换机并设置路由key
    public Binding bindPayOrderDeadQueue(){
        return BindingBuilder.bind(payOrderDeadQueue()).to(payOrderDeadExchange()).with("pay.order.dead");
    }

}

测试代码

@Component
public class StaticScheduler {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    //运行项目后,会每隔3秒向交换机发送一条信息
    @Scheduled(cron = "0/3 * * * * ?")
    public void doStatic(){
        Map map = new HashMap<>();
        map.put("id", 1001);
        map.put("orderNo", "testno");
        rabbitTemplate.convertAndSend("pay_order_exchange", "pay." + map.get("orderNo"), map);
    }
}

消费者

//该方法负责处理哪个队列中的数据
@RabbitListener(queues = "pay_order_dead_queue")
@RabbitHandler //告诉RabbitMQ这是一个用来处理消息的方法
//@Payload注解的含义就是:rabbitmq会将消息队列中的数据,传递给该注解所标记的参数。
public void processMsg(@Payload Map map, Channel channel, @Headers Map headers){
    System.out.println("消费者受到的消息:"+map.get("orderNo"));
    Long  id = (Long)headers.get(AmqpHeaders.DELIVERY_TAG);
    try {
        channel.basicAck(id,false);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

注:springboot初始化时会扫描配置类的注解@Configuration,会将里面的带有@Bean注解的方法运行得到我们配置的对象将其放入Spring容器,替代之前的Spring配置文件。这里我们配置的连接工厂、消息转换器、监听器等被注入到rabbitmq模板中,再将模板对象注入业务类中直接使用。通模板对象我们发送一条消息,先被消息转换器转换成我们设定的json字符串,然后发送至指定的交换机,通过路由key再从交换机发送至队列,如果未到达交换机会被返回,监听交换机的方法会内执行,如果路由key无法匹配,同样会被退回,会被监听队列的RabbitTemplate.ReturnCallback监听,执行其中的方法,到达队列后如果30秒未被消费掉,则会被发送到死信交换机,然后匹配至路由key符合条件的队列,等待被消费,如不匹配则会被丢掉。

你可能感兴趣的:(交换机,队列,rabbitmq,java,spring)