赞
踩
在上面两种场景中,如果我们使用下面3种传统解决方案无疑大大降低了系统的整体性能和吞吐量:
redis
给订单设置过期时间,最后通过判断 redis
中是否还有该订单来决定订单是否已经完成。这种解决方案相较于消息的延迟推送性能较低,因为我们知道 redis
都是存储于内存中,我们遇到恶意下单或者刷单的将会给内存带来巨大压力。jvm
原生的 DelayQueue
,也是大量占用内存,而且没有持久化策略,系统宕机或者重启都会丢失订单信息。在 RabbitMQ 3.6.x
之前我们一般采用死信队列+TTL过期时间来实现延迟队列。这里不做介绍。
在 RabbitMQ 3.6.x
开始,RabbitMQ
官方提供了延迟队列的插件rabbitmq-delayed-message-exchange
。
rabbitmq-delayed-message-exchange
插件官方下载地址:github.com/rabbitmq/ra…https://link.juejin.cn?target=https%3A%2F%2Fgithub.com%2Frabbitmq%2Frabbitmq-delayed-message-exchange%2Freleases
选择对应版本下载(要和安装的RabbitMQ server
版本匹配)。
找到RabbitMQ
的安装路径,将下载的插件放到plugins
目录中。比如:
- -rw-r--r-- 1 root root 43377 9月 20 22:54 rabbitmq_delayed_message_exchange-3.8.0.ez
- [root@libai plugins]# pwd
- /usr/lib/rabbitmq/lib/rabbitmq_server-3.7.14/plugins
启用插件 使用rabbitmq-plugins enable rabbitmq_delayed_message_exchange
命令启用插件。
- [root@libai plugins]# rabbitmq-plugins enable rabbitmq_delayed_message_exchange
- Enabling plugins on node rabbit@libai:
- rabbitmq_delayed_message_exchange
- The following plugins have been configured:
- rabbitmq_delayed_message_exchange
- rabbitmq_management
- rabbitmq_management_agent
- rabbitmq_web_dispatch
- Applying plugin configuration to rabbit@libai...
- The following plugins have been enabled:
- rabbitmq_delayed_message_exchange
- started 1 plugins.
查看管理界面
查看交换机Type
是否有x-delayed-message
下拉选项,如果有则表示插件安装已经生效了。
配置和依赖这里就不贴出了,可以参考以往Springboot
整合RabbitMQ
的文章。
- @Configuration
- public class DelayedMessageRabbitConfig {
- @Bean
- public Queue delayQueue() {
- return new Queue("delayQueue", true, false, false);
- }
-
- @Bean
- public CustomExchange delayExchange() {
- Map<String, Object> args = new HashMap<>();
- args.put("x-delayed-type", "direct");
- return new CustomExchange("delayedExchange", "x-delayed-message", true, false, args);
- }
-
- @Bean
- public Binding bindingDelay() {
- return BindingBuilder.bind(delayQueue()).to(delayExchange()).with("delayRouting").noargs();
- }
- }
交换机类型为CustomExchange
自定义类型,这里指定为x-delayed-message
。
- @RestController
- @Slf4j
- public class DelayMessageController {
- @Autowired
- private RabbitTemplate rabbitTemplate;
-
- @PostMapping("/sendDelayedMessage")
- public String sendDelayedMessage() {
- log.info(DateUtil.now());
- rabbitTemplate.convertAndSend("delayedExchange", "delayRouting", "订单取消", message -> {
- message.getMessageProperties().setDelay(5000);
- return message;
- });
- return "ok";
- }
- }
这里指定延迟5秒推送消息。
- @Component
- @RabbitListener(queues = "delayQueue")
- @Slf4j
- public class DelayReceiver {
- @RabbitHandler
- public void process(String delayMessage) {
- log.info(DateUtil.now());
- log.info("延迟收到消息:{}", delayMessage);
- }
- }
-
- 2020-09-21 21:35:44
- ------------------
- 2020-09-21 21:35:49
- 延迟收到消息:订单取消
如果开启了消息确认机制,比如确认消息是否发到了交换机(publisher-confirms
为true),则可能出现312、NO_ROUTE
的提示,忽略即可。
另外这里的消息延迟主要发生在交换机延迟推送消息到队列中,而非队列延迟推送到消费者。
作者:CodeSculptor
链接:https://juejin.cn/post/7250398488713822265
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。