1. 问题背景
假设有一个订单服务系统,当用户提交订单后,系统会根据订单信息生成订单,并在订单生成成功后,自动发送邮件提醒用户。为了实现这一过程,系统通常会按照以下顺序同步(从上往下)执行:
用户提交订单。
订单生成成功。
邮件发送成功。
用户收到反馈。
1.1 问题描述
这个同步执行的流程可能带来一些性能和用户体验上的问题。特别是在邮件发送的过程可能会存在一定的延迟,而订单服务又依赖于该过程的成功完成来反馈结果给用户。举个例子,如果有十个用户都生成订单,但是服务器每次只能发3封邮件,那就有7个用户要干等着,这样不仅可能导致响应时间变长,还可能影响系统的可扩展性。
1.2 问题解决
当我们引入了了rabbitMQ,我们就可以将要发邮件做一个任务清单(消息队列),在订单生成以后就返回用户成功了,然后把要发的邮件放入消息队列,然后让服务器慢慢从消息队列里面一条一条数据读,一个邮件一个邮件的发就好了。
在专业的名词解释里面,用户被成为生产者,处理用户请求的服务器被称为消费者,而rabbit所提供的功能就是存储消息队列(任务清单)并且作为交换机连接用户和服务器,如下图

2. 示例代码
RabbitConfig.java
@Configuration
public class RabbitConfig {
@Bean
public TopicExchange mainExchange() {
return new TopicExchange("mainExchange");
}
@Bean
public Queue orderQueue() {
return new Queue("orderQueue");
}
@Bean
public Queue emailQueue() {
return new Queue("emailQueue");
}
@Bean
public Binding orderBinding(Queue orderQueue, TopicExchange mainExchange) {
return BindingBuilder.bind(orderQueue).to(mainExchange).with("order");
}
@Bean
public Binding emailBinding(Queue emailQueue, TopicExchange mainExchange) {
return BindingBuilder.bind(emailQueue).to(mainExchange).with("email");
}
}
MessageSender.java
@Service
public class MessageSender {
@Autowired
private RabbitTemplate rabbitTemplate;
// 发送订单消息
public void sendOrderMessage(String message) {
rabbitTemplate.convertAndSend("mainExchange", "order", message);
}
// 发送邮件消息
public void sendEmailMessage(String message) {
rabbitTemplate.convertAndSend("mainExchange", "email", message);
}
}
MessageController.java
@RestController
@RequestMapping("/mq")
public class MessageController {
@Autowired
private MessageSender sender;
// 发送订单消息
@GetMapping("/sendOrder")
public String sendOrder() {
sender.sendOrderMessage("用户下了一个订单!");
return "订单消息已发送";
}
// 发送邮件消息
@GetMapping("/sendEmail")
public String sendEmail() {
sender.sendEmailMessage("发送确认邮件给用户");
return "邮件消息已发送";
}
}
MessageConsumer.java
@Service
public class MessageConsumer {
@RabbitListener(queues = "orderQueue")
public void handleOrder(String msg) {
System.out.println("📦 订单处理:" + msg);
}
@RabbitListener(queues = "emailQueue")
public void handleEmail(String msg) {
System.out.println("📧 邮件处理:" + msg);
}
}
application.yml
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest