19.RabbitMQ 延迟消息实现

什么是延迟队列:

  延时队列,首先,它是一种队列,队列意味着内部的元素是有序的,元素出队和入队是有方向性的,元素从一端进入,从另一端取出。

  其次,延时队列,最重要的特性就体现在它的延时属性上,跟普通的队列不一样的是,普通队列中的元素总是等着希望被早点取出处理,而延时队列中的元素则是希望被在指定时间得到取出和处理,所以延时队列中的元素是都是带时间属性的,通常来说是需要被处理的消息或者任务。

  简单来说,延时队列就是用来存放需要在指定时间被处理的元素的队列。

延迟队列使用场景:

  那么什么时候需要用延时队列呢?考虑一下以下场景:

    订单在十分钟之内未支付则自动取消。

    新创建的店铺,如果在十天内都没有上传过商品,则自动发送消息提醒。

    账单在一周内未支付,则自动结算。

    用户注册成功后,如果三天内没有登陆则进行短信提醒。

    用户发起退款,如果三天内没有得到处理则通知相关运营人员。

    预定会议后,需要在预定的时间点前十分钟通知各个与会人员参加会议。

延迟队列的实现方式:

1、利用TTL+死信队列

  生产者生产一条延时消息,根据需要延时时间的不同,利用不同的routingkey将消息路由到不同的延时队列,每个队列都设置了不同的TTL属性,并绑定在同一个死信交换机中,消息过期后,根据routingkey的不同,又会被路由到不同的死信队列中,消费者只需要监听对应的死信队列进行处理即可。
在这里插入图片描述
  这种方式的弊端,无法做到通用性,每搞一个新的延迟任务,都要去实现一个实现的TTL+死信队列,比较麻烦;

2、利用RabbitMQ插件实现

  安装一个插件即可:https://www.rabbitmq.com/community-plugins.html ,下载rabbitmq_delayed_message_exchange插件,然后解压放置到RabbitMQ的插件目录。
在这里插入图片描述
  查看发布历史,下载3.8.0版本
在这里插入图片描述
3、RabbitMQ容器配置插件:

  3.1、进入容器查看,MQ的插件目录:plugins/

[root@VM-0-12-centos ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@VM-0-12-centos ~]# docker ps -a
CONTAINER ID        IMAGE                   COMMAND                  CREATED             STATUS                      PORTS               NAMES
74f929cfb3c9        rabbitmq:3-management   "docker-entrypoint..."   4 weeks ago         Exited (0) 18 minutes ago                       rabbitMQ
[root@VM-0-12-centos ~]# docker start 74f929cfb3c9
74f929cfb3c9
[root@VM-0-12-centos ~]# docker exec -it 74f929cfb3c9 bash
root@74f929cfb3c9:/# ls
bin  boot  dev  etc  home  lib  lib32  lib64  libx32  media  mnt  opt  plugins  proc  root  run  sbin  srv  sys  tmp  usr  var
root@74f929cfb3c9:/# cd plugins
root@74f929cfb3c9:/plugins# ls
README                            cuttlefish-3.0.0.ez        ra-1.1.8.ez                             rabbitmq_consistent_hash_exchange-3.8.18.ez  rabbitmq_peer_discovery_consul-3.8.18.ez    rabbitmq_stomp-3.8.18.ez               recon-2.5.1.ez
accept-0.3.5.ez                   eetcd-0.3.3.ez             rabbit-3.8.18.ez                        rabbitmq_event_exchange-3.8.18.ez            rabbitmq_peer_discovery_etcd-3.8.18.ez      rabbitmq_top-3.8.18.ez                 stdout_formatter-0.2.4.ez
amqp10_client-3.8.18.ez           gen_batch_server-0.8.4.ez  rabbit_common-3.8.18.ez                 rabbitmq_federation-3.8.18.ez                rabbitmq_peer_discovery_k8s-3.8.18.ez       rabbitmq_tracing-3.8.18.ez             syslog-3.4.5.ez
amqp10_common-3.8.18.ez           goldrush-0.1.9.ez          rabbitmq_amqp1_0-3.8.18.ez              rabbitmq_federation_management-3.8.18.ez     rabbitmq_prelaunch-3.8.18.ez                rabbitmq_trust_store-3.8.18.ez         sysmon_handler-1.3.0.ez
amqp_client-3.8.18.ez             gun-1.3.3.ez               rabbitmq_auth_backend_cache-3.8.18.ez   rabbitmq_jms_topic_exchange-3.8.18.ez        rabbitmq_prometheus-3.8.18.ez               rabbitmq_web_dispatch-3.8.18.ez
aten-0.5.5.ez                     jose-1.11.1.ez             rabbitmq_auth_backend_http-3.8.18.ez    rabbitmq_management-3.8.18.ez                rabbitmq_random_exchange-3.8.18.ez          rabbitmq_web_mqtt-3.8.18.ez
base64url-1.0.1.ez                jsx-3.1.0.ez               rabbitmq_auth_backend_ldap-3.8.18.ez    rabbitmq_management_agent-3.8.18.ez          rabbitmq_recent_history_exchange-3.8.18.ez  rabbitmq_web_mqtt_examples-3.8.18.ez
cowboy-2.8.0.ez                   lager-3.9.2.ez             rabbitmq_auth_backend_oauth2-3.8.18.ez  rabbitmq_mqtt-3.8.18.ez                      rabbitmq_sharding-3.8.18.ez                 rabbitmq_web_stomp-3.8.18.ez
cowlib-2.9.1.ez                   observer_cli-1.6.2.ez      rabbitmq_auth_mechanism_ssl-3.8.18.ez   rabbitmq_peer_discovery_aws-3.8.18.ez        rabbitmq_shovel-3.8.18.ez                   rabbitmq_web_stomp_examples-3.8.18.ez
credentials_obfuscation-2.4.0.ez  prometheus-4.6.0.ez        rabbitmq_aws-3.8.18.ez                  rabbitmq_peer_discovery_common-3.8.18.ez     rabbitmq_shovel_management-3.8.18.ez        ranch-2.0.0.ez
root@74f929cfb3c9:/plugins#

  3.2、将下载的rabbitmq_delayed_message_exchange插件放到服务器的/home/docker/rabbitmq/路径下
在这里插入图片描述
  3.3、将rabbitmq_delayed_message_exchange插件拷贝到容器的plugins目录下,并确认

  命令:docker cp 本地文件路径 容器ID或全称:容器路径

[root@VM-0-12-centos /]# docker cp home/docker/rabbitmq/rabbitmq_delayed_message_exchange-3.8.0.ez 74f929cfb3c9:plugins/
[root@VM-0-12-centos /]# docker exec -it 74f929cfb3c9 bash
root@74f929cfb3c9:/# cd plugins
root@74f929cfb3c9:/plugins# ls
README                            cuttlefish-3.0.0.ez        ra-1.1.8.ez                             rabbitmq_consistent_hash_exchange-3.8.18.ez  rabbitmq_peer_discovery_common-3.8.18.ez    rabbitmq_shovel_management-3.8.18.ez   ranch-2.0.0.ez
accept-0.3.5.ez                   eetcd-0.3.3.ez             rabbit-3.8.18.ez                        rabbitmq_delayed_message_exchange-3.8.0.ez   rabbitmq_peer_discovery_consul-3.8.18.ez    rabbitmq_stomp-3.8.18.ez               recon-2.5.1.ez
amqp10_client-3.8.18.ez           gen_batch_server-0.8.4.ez  rabbit_common-3.8.18.ez                 rabbitmq_event_exchange-3.8.18.ez            rabbitmq_peer_discovery_etcd-3.8.18.ez      rabbitmq_top-3.8.18.ez                 stdout_formatter-0.2.4.ez
amqp10_common-3.8.18.ez           goldrush-0.1.9.ez          rabbitmq_amqp1_0-3.8.18.ez              rabbitmq_federation-3.8.18.ez                rabbitmq_peer_discovery_k8s-3.8.18.ez       rabbitmq_tracing-3.8.18.ez             syslog-3.4.5.ez
amqp_client-3.8.18.ez             gun-1.3.3.ez               rabbitmq_auth_backend_cache-3.8.18.ez   rabbitmq_federation_management-3.8.18.ez     rabbitmq_prelaunch-3.8.18.ez                rabbitmq_trust_store-3.8.18.ez         sysmon_handler-1.3.0.ez
aten-0.5.5.ez                     jose-1.11.1.ez             rabbitmq_auth_backend_http-3.8.18.ez    rabbitmq_jms_topic_exchange-3.8.18.ez        rabbitmq_prometheus-3.8.18.ez               rabbitmq_web_dispatch-3.8.18.ez
base64url-1.0.1.ez                jsx-3.1.0.ez               rabbitmq_auth_backend_ldap-3.8.18.ez    rabbitmq_management-3.8.18.ez                rabbitmq_random_exchange-3.8.18.ez          rabbitmq_web_mqtt-3.8.18.ez
cowboy-2.8.0.ez                   lager-3.9.2.ez             rabbitmq_auth_backend_oauth2-3.8.18.ez  rabbitmq_management_agent-3.8.18.ez          rabbitmq_recent_history_exchange-3.8.18.ez  rabbitmq_web_mqtt_examples-3.8.18.ez
cowlib-2.9.1.ez                   observer_cli-1.6.2.ez      rabbitmq_auth_mechanism_ssl-3.8.18.ez   rabbitmq_mqtt-3.8.18.ez                      rabbitmq_sharding-3.8.18.ez                 rabbitmq_web_stomp-3.8.18.ez
credentials_obfuscation-2.4.0.ez  prometheus-4.6.0.ez        rabbitmq_aws-3.8.18.ez                  rabbitmq_peer_discovery_aws-3.8.18.ez        rabbitmq_shovel-3.8.18.ez                   rabbitmq_web_stomp_examples-3.8.18.ez
root@74f929cfb3c9:/plugins#

  3.4、接下来,进入RabbitMQ的安装目录下的sbin目录,执行下面命令让该插件生效,然后重启RabbitMQ。

rabbitmq-plugins enable rabbitmq_delayed_message_exchange

root@74f929cfb3c9:/plugins# cd /sbin
root@74f929cfb3c9:/sbin# rabbitmq-plugins enable rabbitmq_delayed_message_exchange
Enabling plugins on node rabbit@74f929cfb3c9:
rabbitmq_delayed_message_exchange
The following plugins have been configured:
  rabbitmq_delayed_message_exchange
  rabbitmq_management
  rabbitmq_management_agent
  rabbitmq_prometheus
  rabbitmq_web_dispatch
Applying plugin configuration to rabbit@74f929cfb3c9...
The following plugins have been enabled:
  rabbitmq_delayed_message_exchange

started 1 plugins.
root@74f929cfb3c9:/sbin#

RabbitMqConfig配置:

1、配置延迟队列

/**
 * delayedDirect交换机名称
 */
public static final String DELAYED_DIRECT_EXCHANGE="delayedDirectExchange";

/**
 * delayedDirect队列名称
 */
public static final String DELAYED_DIRECT_QUEUE="delayedDirectQueue";

/**
 * delayedDirec交换机与delayedDirec队列绑定的key
 */
public static final String DELAYED_DIRECT_ROUTINGKEY="delayedDirectRouingkey";

/**
 * 定义一个delayedDirect交换机
 * 自定义交换机
 * @return
 */
@Bean
public CustomExchange delayedDirectExchange(){
    /**
     * CustomExchange(String name, String type, boolean durable, boolean autoDelete, Map<String, Object> arguments)
     * 构造参数说明:
     *  name:交换机名称 、 type:自定义类型(插件提供了一个类型叫x-delayed-message) 、durable 持久化 、autoDelete自动删除 、arguments 用来传递其他属性配置
     */
    Map<String, Object> args = new HashMap<>();

    args.put("x-delayed-type", "direct");

    return new CustomExchange(DELAYED_DIRECT_EXCHANGE,"x-delayed-message", true, false, args);
}

/**
 * 定义一个delayedDirect队列
 * @return
 */
@Bean
public Queue delayedDirectQueue(){
    return new Queue(DELAYED_DIRECT_QUEUE);
}

/**
 * 定义一个delayedDirect队列和delayedDirect交换机的绑定规则
 * @return
 */
@Bean
public Binding delayedDirectBinding(){
    return BindingBuilder.bind(delayedDirectQueue()).to(delayedDirectExchange()).with(DELAYED_DIRECT_ROUTINGKEY).noargs();
}

2、生产者发送消息方法

/**
 * 发送delayed延迟消息
 * @param message 消息
 * @param delayTime 延迟时间 单位毫秒
 */
@Override
public void sendDelayedMessage(String message, Integer delayTime) {
    rabbitTemplate.convertAndSend(RabbitMqConfig.DELAYED_DIRECT_EXCHANGE,RabbitMqConfig.DELAYED_DIRECT_ROUTINGKEY,message,messagePostProcessor->{
        messagePostProcessor.getMessageProperties().setDelay(delayTime);
        return messagePostProcessor;
    });
}

3、消费者接收消息的方法

@Override
@RabbitListener(queues = {RabbitMqConfig.DELAYED_DIRECT_QUEUE}) //监听队列
public void receiveMessage2(String message) {
    System.out.println("接收延迟消息:"+message +" :"+ new Date().toString());
}

4、发送消息测试,关闭掉手动ACK

package com.java996.producer;

import com.java996.producer.Service.RabbitMqService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class ProducerApp {
    public static void main(String[] args) {
     ConfigurableApplicationContext context = SpringApplication.run(ProducerApp.class,args);
        RabbitMqService rabbitMqService = (RabbitMqService) context.getBean("RabbitMqService");
        rabbitMqService.sendDelayedMessage("测试延迟消息:10秒",10000);
        rabbitMqService.sendDelayedMessage("测试延迟消息:20秒",20000);
    }
}

5、测试结果:两条消息消费的时间间隔10秒
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值