RabbitMQ安装和使用(例如取消订单功能),只有代码没有废话

一、Windows系统安装:

rabbitmq安装前提是erlang环境,我把两个安装包都放云盘了,安装细节就不说了 都是傻瓜式安装,注意点就是安装路径不要有中文。
链接:https://pan.xunlei.com/s/VO4dwLaZaV10xGlKkhjY5ZknA1?pwd=xx8e#

# 安装rabbitMQ

正常安装完成然后执行下面命令就可以使用了:

1、进入安装目录 cd 你的RabbitMQ安装目录\sbin
 
2、打开节点:rabbitmqctl start_app
 
3、配置管理模块:rabbitmq-plugins enable rabbitmq_management
 
4、关闭节点:rabbitmqctl stop

这篇文章是草稿之前忘记记录错误和解决方法,现在发出来已经忘记当时出现的错误和解决办法(报一丝)


二、使用案例(超时未支付取消订单)

依赖

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

配置RabbitMQ

在项目的配置类中,配置RabbitMQ的交换机、队列和绑定关系,如下:

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMqConfig {

    public static final String ORDER_EXCHANGE = "order_exchange";
    public static final String DEAD_LETTER_EXCHANGE = "dead_letter_exchange";
    public static final String ORDER_QUEUE = "order_queue";
    public static final String DEAD_LETTER_QUEUE = "dead_letter_queue";
    public static final String ROUTING_KEY = "order_routing_key";
    public static final String DEAD_LETTER_ROUTING_KEY = "dead_letter_routing_key";

    @Bean
    public DirectExchange orderExchange() {
        return new DirectExchange(ORDER_EXCHANGE);
    }

    @Bean
    public DirectExchange deadLetterExchange() {
        return new DirectExchange(DEAD_LETTER_EXCHANGE);
    }

    @Bean
    public Queue orderQueue() {
        Map<String, Object> args = new HashMap<>();
        args.put("x-dead-letter-exchange", DEAD_LETTER_EXCHANGE);
        args.put("x-dead-letter-routing-key", DEAD_LETTER_ROUTING_KEY);
        args.put("x-message-ttl", 900000); // 设置消息存活时间为15分钟(毫秒)
        return QueueBuilder.durable(ORDER_QUEUE).withArguments(args).build();
    }

    @Bean
    public Queue deadLetterQueue() {
        return QueueBuilder.durable(DEAD_LETTER_QUEUE).build();
    }

    @Bean
    public Binding orderBinding(@Qualifier("orderQueue") Queue queue,
                                @Qualifier("orderExchange") DirectExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(ROUTING_KEY);
    }

    @Bean
    public Binding deadLetterBinding(@Qualifier("deadLetterQueue") Queue queue,
                                     @Qualifier("deadLetterExchange") DirectExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(DEAD_LETTER_ROUTING_KEY);
    }
}

创建生产者

在服务类中,创建一个生产者,用于将订单信息发送到RabbitMQ队列中:

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class OrderProducer {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendOrder(Order order) {
        rabbitTemplate.convertAndSend(RabbitMqConfig.ORDER_EXCHANGE, RabbitMqConfig.ROUTING_KEY, order);
    }
}

消费者处理超时订单:

创建一个消费者,用于监听死信队列,并处理超时订单:

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class OrderConsumer {

    @Autowired
    private OrderService orderService;

    @RabbitListener(queues = RabbitMqConfig.DEAD_LETTER_QUEUE)
    public void handleOrderTimeout(Order order) {
        // 检查订单状态是否为待支付
        if (order.getStatus() == 0) {
            // 更新订单状态为已取消
            order.setStatus(5);
            order.setCancelReason("订单超时未支付,系统自动取消");
            orderService.updateOrder(order);
        }
    }
}

调用RabbitMQ

在订单创建后,调用OrderProducer的sendOrder方法,将订单信息发送到RabbitMQ队列中:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private OrderProducer orderProducer;

    @Autowired
    private OrderService orderService;

    @PostMapping("/create")
    @ResponseBody
    public String createOrder(@RequestBody Order order) {
        // 创建订单逻辑
        orderService.createOrder(order);
        
        // 将订单信息发送到RabbitMQ队列中
        orderProducer.sendOrder(order);
        
        return "订单创建成功";
    }
}

在service中调用

如果你想在service中调用,需要考虑生成订单的代码出错然后回滚事务:
使用RabbitMQ事务机制:

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class OrderService {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Transactional(rollbackFor = Exception.class)
    public void createOrder(Order order) {
        // 创建订单逻辑
        try {
            // 模拟订单创建
            System.out.println("订单创建成功");

            // 开启RabbitMQ事务
            rabbitTemplate.execute(channel -> {
                try {
                    channel.txSelect(); // 开启事务
                    rabbitTemplate.convertAndSend("order_exchange", "order_routing_key", order);
                    channel.txCommit(); // 提交事务
                    return null;
                } catch (Exception e) {
                    channel.txRollback(); // 回滚事务
                    throw e;
                }
            });

            // 模拟其他业务逻辑
            System.out.println("其他业务逻辑执行成功");
        } catch (Exception e) {
            // 如果发生异常,回滚事务
            throw new RuntimeException("订单创建失败", e);
        }
    }
}
  • @Transactional并不能回滚取消RabbitMQ已发送的消息
  • @Transactional注解主要用于管理数据库事务,确保在事务边界内的数据库操作要么全部成功提交,要么在发生异常时回滚。
  • 因为RabbitMQ的消息发送和数据库操作是两种不同的资源,Spring的事务管理器无法直接管理RabbitMQ的消息发送操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哒不溜-w

别给我打手续费太贵

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值