Cyan Blog Cyan Blog
首页
  • Java (opens new window)
  • JUC (opens new window)
  • JVM (opens new window)
  • Redis

    • Redis安装 (opens new window)
    • Redis基础 (opens new window)
    • Redis实战 (opens new window)
    • Redis集群安装 (opens new window)
    • Redis分布式缓存 (opens new window)
    • Redis多级缓存 (opens new window)
    • Redis原理 (opens new window)
  • 管理工具

    • Maven (opens new window)
    • Git (opens new window)
  • SSM

    • Spring (opens new window)
    • SpringBoot (opens new window)
    • Mybatis (opens new window)
    • MybatisPlus (opens new window)
  • 微服务

    • Docker (opens new window)
    • RabbitMQ (opens new window)
    • SpringCloud (opens new window)
    • Dubbo (opens new window)
    • MongoDB (opens new window)
    • Zookeeper (opens new window)
  • Java面试题 (opens new window)
  • JUC面试题 (opens new window)
  • JVM面试题 (opens new window)
  • Linux面试题 (opens new window)
  • SQL面试题 (opens new window)
  • Maven面试题 (opens new window)
  • Redis面试题 (opens new window)
  • SSM面试题 (opens new window)
  • SpringCloud面试题 (opens new window)
  • Linux (opens new window)
  • C++ (opens new window)
  • 数据库

    • MySQL (opens new window)
    • NoSQL (opens new window)
  • 软件测试

    • 软件测试 (opens new window)
  • 加密解密 (opens new window)
  • bilibili字幕提取 (opens new window)
  • 道理 (opens new window)
  • 关于博主

    • Github (opens new window)
    • CSDN (opens new window)
  • 关于本站

    • 如何搭建博客网站 (opens new window)
首页
  • Java (opens new window)
  • JUC (opens new window)
  • JVM (opens new window)
  • Redis

    • Redis安装 (opens new window)
    • Redis基础 (opens new window)
    • Redis实战 (opens new window)
    • Redis集群安装 (opens new window)
    • Redis分布式缓存 (opens new window)
    • Redis多级缓存 (opens new window)
    • Redis原理 (opens new window)
  • 管理工具

    • Maven (opens new window)
    • Git (opens new window)
  • SSM

    • Spring (opens new window)
    • SpringBoot (opens new window)
    • Mybatis (opens new window)
    • MybatisPlus (opens new window)
  • 微服务

    • Docker (opens new window)
    • RabbitMQ (opens new window)
    • SpringCloud (opens new window)
    • Dubbo (opens new window)
    • MongoDB (opens new window)
    • Zookeeper (opens new window)
  • Java面试题 (opens new window)
  • JUC面试题 (opens new window)
  • JVM面试题 (opens new window)
  • Linux面试题 (opens new window)
  • SQL面试题 (opens new window)
  • Maven面试题 (opens new window)
  • Redis面试题 (opens new window)
  • SSM面试题 (opens new window)
  • SpringCloud面试题 (opens new window)
  • Linux (opens new window)
  • C++ (opens new window)
  • 数据库

    • MySQL (opens new window)
    • NoSQL (opens new window)
  • 软件测试

    • 软件测试 (opens new window)
  • 加密解密 (opens new window)
  • bilibili字幕提取 (opens new window)
  • 道理 (opens new window)
  • 关于博主

    • Github (opens new window)
    • CSDN (opens new window)
  • 关于本站

    • 如何搭建博客网站 (opens new window)
  • SSM

  • SpringBoot

    • big-event
    • 苍穹外卖

      • 苍穹外卖
      • Day02
      • Day03
      • Day04
      • Day05
      • Day06
      • Day07
      • Day08
      • Day09
      • Day10
      • Day11
      • Day12
      • 项目优化
        • 使用RabbitMQ处理超时订单
        • 下载插件
        • 定义常量
        • 配置MQ
        • 发送消息
        • 监听消息
    • Spring注解
    • 数据库设计文档
  • SpringCloud

  • Docker
  • Dubbo
  • MongoDB
  • Zookeeper
  • Spring生态
  • SpringBoot
  • 苍穹外卖
2025-05-06
0
0
目录

项目优化

# 使用RabbitMQ处理超时订单

# 下载插件

基于死信队列虽然可以实现延迟消息完成超时订单取消,但是太麻烦了。因此RabbitMQ社区提供了一个延迟消息插件来实现相同的效果。

插件下载地址:https://github.com/rabbitmq/rabbitmq-delayed-message-exchange

因为我们是基于Docker安装,所以需要先查看RabbitMQ的插件目录对应的数据卷。

docker volume inspect mq-plugins

结果如下:

[
    {
        "CreatedAt": "2024-06-19T09:22:59+08:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/mq-plugins/_data",
        "Name": "mq-plugins",
        "Options": null,
        "Scope": "local"
    }
]

插件目录被挂载到了/var/lib/docker/volumes/mq-plugins/_data这个目录,我们上传插件到该目录下。

接下来执行命令,安装插件:

docker exec -it mq rabbitmq-plugins enable rabbitmq_delayed_message_exchange

# 定义常量

无论是消息发送还是接收都是在交易服务完成,因此我们在constants中定义一个常量类,用于记录交换机、队列、RoutingKey等常量:

内容如下:

package com.hmall.trade.constants;

public interface MQConstants {
    String DELAY_EXCHANGE_NAME = "trade.delay.direct";
    String DELAY_ORDER_QUEUE_NAME = "trade.delay.order.queue";
    String DELAY_ORDER_KEY = "delay.order.query";
}

# 配置MQ

1)添加依赖:

<!--AMQP依赖,包含RabbitMQ-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

2)配置MQ地址:

spring:
  rabbitmq:
    host: 192.168.10.130 # 你的虚拟机IP
    port: 5672 # 端口
    virtual-host: /skytakeout # 虚拟主机
    username: cyan # 用户名
    password: 123456 # 密码

在Virtual Hosts 中创建一个项目专用的virtual host:/skytakeout

一般是配置为多环境模式

application.yaml

spring:
  rabbitmq:
    host: ${mq.host} # 你的虚拟机IP
    port: 5672 # 端口
    virtual-host: ${mq.virtual-host} # 虚拟主机
    username: ${mq.username} # 用户名
    password: ${mq.password} # 密码

application-dev.yaml

mq:
  host: 192.168.10.130 # 你的虚拟机IP
  virtual-host: /skytakeout # 虚拟主机
  username: cyan # 用户名
  password: 123456 # 密码

application-prod.yaml

mq:
  host: mq # docker网络别名
  virtual-host: /skytakeout # 虚拟主机
  username: cyan # 用户名
  password: 123456 # 密码

# 发送消息

//5,发送延迟消息,检测订单支付状态
rabbitTemplate.convertAndSend(
	MQConstants.DELAY_EXCHANGE_NAME,
    MQConstants.DELAY_ORDER_KEY,
    order.getId(),
    message ->{
    	message.getMessageProperties().setDelay(10000);
    	return message;
	});

# 监听消息

package com.sky.listener;

import com.sky.constant.MQConstant;
import com.sky.entity.Orders;
import com.sky.mapper.OrderMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

@Component
@RequiredArgsConstructor
public class OrderDelayMessageListener {

    private final OrderMapper orderMapper;
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = MQConstant.DELAY_ORDER_QUEUE_NAME),
            exchange = @Exchange(name = MQConstant.DELAY_EXCHANGE_NAME, delayed = "true"),
            key = MQConstant.DELAY_ORDER_KEY
    ))
    public void listenOrderDelayMessage(Long orderId) {
        // 根据id查询订单
        Orders order = orderMapper.getById(orderId);

        // 2.检测订单状态,判断是否已支付
        if(order == null || order.getStatus() != Orders.PENDING_PAYMENT){
            // 订单不存在或者已经支付
            return;
        }

        order.setStatus(Orders.CANCELLED);
        order.setCancelReason("支付超时,自动取消");
        order.setCancelTime(LocalDateTime.now());
        orderMapper.update(order);
    }

}
上次更新: 2025/6/10 17:21:17
Day12
Spring注解

← Day12 Spring注解→

最近更新
01
md
06-29
02
Redis
06-29
03
HBase
06-29
更多文章>
Theme by Vdoing | Copyright © 2025-2025 Cyan Blog
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式