RabbitMQ延时队列

RabbitMQ延时队列

1). 前提条件首先要具备已经安装**rabbitmq+erlang**,版本可以参考https://www.rabbitmq.com/which-erlang.html#compatibility-matrix

2).https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases中下载和自己rabbitmq相对应的版本,我的rabbitmq版本为 3.10.0 和erlang版本是23.2,rabbitmq-delayed-message-exchange的版本为rabbitmq_delayed_message_exchange-3.10.0.ez

3). 下载到了之后放到rabbitmq的plugins目录下

4). 检测rabbitmq_delayed_message_exchange是否有效,在rabbitmq的可视化界面中新建交换机在这里插入图片描述

5).rabbitmq的配置 [ 重试机制是为了做滞后处理 ]

spring:
    rabbitmq:
	    host: localhost
	    port: 5672
	    username: guest
	    password: guest
	    virtual-host: /
	    publisher-returns: true  # 开启回退模式,然后设置rabbitTemplate.setMandatory(true);
	    publisher-confirm-type: correlated #开启 publisher-confirm 设置同步类型 simple:同步等待confirm结果,直到超时 correlated:异步回调,次你故意ConfirmCallback,MQ返回结果时会回调这个ComfirmCallback
	    template:
	      mandatory: true # 开启消息路由失败时的策略.turn,则调用ReturnCallback; false:直接丢弃数据
	    listener:
	      simple:
	        # 表示消息确认方式,其有三种配置方式,分别是none、manual和auto;默认auto
	        acknowledge-mode: auto
	        # 最小的消费者数量
	        concurrency: 5
	        # 最大的消费者数量
	        max-concurrency: 10
	        # 指定一个请求能处理多少个消息,如果有事务的话,必须大于等于transaction数量.
	        prefetch: 3
	        # 重试机制: (最大重试次数包含初次消费)
	        # 初次消費
	        # 第1次:1秒
	        # 第2次:1*2=2秒
	        # 第3次:2*2=4秒
	        # 第4次:4*2=8秒
	        # 第5次:8*2=16秒
	        # 第6次:16*2=32秒
	        # 第7次:32*2=64秒 (由于设置最大间隔时间,因此这里为50秒 )
	        retry:
	          enabled: true # 是否开启重试
	          max-attempts: 8 # 最大重试次数
	          max-interval: 50000 # 重试最大间隔时间
	          initial-interval: 1000 # 重试间隔(单位:毫秒)
	          multiplier: 2 # 间隔时间乘子,间隔时间*乘子=下一次的间隔时间,最大不能超过设置的最大间隔时间

6).rabbitmq的依赖

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

7). 之后我们就可以申明队列和交换机// 订单未支付-自动取消-延时队列

String ORDER_UN_PAY_AUTO_CLOSE_ROUTING_KEY = "order_un_pay_auto_close_key";
String ORDER_UN_PAY_AUTO_CLOSE_QUEUE = "order_un_pay_auto_close_queue";

String ORDER_UN_PAY_AUTO_CLOSE_EXCHANGE = "order_un_pay_auto_close_exchange";

 ----------- 订单30分钟未支付,自动取消订单 -------------

/**
 * 延时队列
 */
@Bean
public Queue orderNoPayDelayQueue() {
    return new Queue(ManualRabbitConstant.ORDER_UN_PAY_AUTO_CLOSE_QUEUE, true);
}

/**
 * 延时交换机
 */
@Bean
public CustomExchange orderNoPayDelayExchange() {
    Map<String, Object> map = new HashMap<>();
    map.put("x-delayed-type", "direct");
    // 交换机名称 交换机类型 是否持久化 是否自动删除 配置参数
    return new CustomExchange(ManualRabbitConstant.ORDER_UN_PAY_AUTO_CLOSE_EXCHANGE,"x-delayed-message",true,false,map);
}

/**
 * 延时队列和交换机绑定
 */
@Bean
public Binding orderUnPayAutoCloseBinding() {
    return BindingBuilder.bind(this.orderNoPayDelayQueue())
            .to(this.orderNoPayDelayExchange())
            .with(ManualRabbitConstant.ORDER_UN_PAY_AUTO_CLOSE_ROUTING_KEY)
            .noargs();
}

8).配置消费者信息

@Component
@RequiredArgsConstructor
public class ManualNormalConsumer implements ChannelAwareMessageListener {

private final ManualAllOrderService orderService;

/**
 * 延时队列消费者  1分钟未支付则取消订单
 * @param message
 * @param channel
 */
@RabbitHandler
@RabbitListener(queues = { ManualRabbitConstant.ORDER_UN_PAY_AUTO_CLOSE_QUEUE })
public void onDelayMessage(Message message, Channel channel) throws IOException {

    long messageDeliveryTag = message.getMessageProperties().getDeliveryTag();
    System.out.println("进入延时队列中"+messageDeliveryTag);
    ManualAllOrderEntity orderEntity = JSON.parseObject(message.getBody(), ManualAllOrderEntity.class);
    try{
        // 因为配置为自动,auto,只有有异常的时候
        orderService.cancelOrder(orderEntity);
    }catch (Exception e){
        e.printStackTrace();
    }
  }

}

9).在业务中触发rabbitmq 我这边默认1分钟做测试的

private void rabbitSendMessage(ManualAllOrderEntity order){

    this.rabbitTemplate.convertAndSend(ManualRabbitConstant.ORDER_UN_PAY_AUTO_CLOSE_EXCHANGE,
            ManualRabbitConstant.ORDER_UN_PAY_AUTO_CLOSE_ROUTING_KEY,
            JSON.toJSONString(order),
            message -> {
                // 配置消息延时时间
                message.getMessageProperties().setHeader("x-delay", 60000);
                return message;
            });

}

10). 这边用支付宝沙箱做测试 下订单

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述没打断点,rabbitmq中没记录到
在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值