系列导读:本篇将深入讲解事件驱动架构的核心概念、设计模式与最佳实践。
文章目录
-
- 一、事件驱动概述
-
- [1.1 什么是事件驱动架构?](#1.1 什么是事件驱动架构?)
- [1.2 架构对比](#1.2 架构对比)
- 二、核心概念
-
- [2.1 事件定义](#2.1 事件定义)
- [2.2 事件流](#2.2 事件流)
- 三、事件模式
-
- [3.1 事件通知](#3.1 事件通知)
- [3.2 事件溯源](#3.2 事件溯源)
- [3.3 CQRS](#3.3 CQRS)
- 四、技术选型
-
- [4.1 消息中间件对比](#4.1 消息中间件对比)
- [4.2 选型建议](#4.2 选型建议)
- 五、代码实战
-
- [5.1 Spring Event](#5.1 Spring Event)
- [5.2 Kafka 集成](#5.2 Kafka 集成)
- 总结
一、事件驱动概述
1.1 什么是事件驱动架构?
事件驱动架构是一种以事件为核心进行系统通信的架构模式。
┌─────────────────────────────────────────────────────────────┐
│ 事件驱动特征 │
├─────────────────────────────────────────────────────────────┤
│ 📢 松耦合:生产者和消费者互不依赖 │
│ ⚡ 异步处理:提高系统响应速度 │
│ 🔄 可扩展:易于添加新的事件消费者 │
│ 📊 可追溯:事件日志便于审计和回放 │
└─────────────────────────────────────────────────────────────┘
1.2 架构对比
| 模式 | 说明 |
|---|---|
| 同步调用 | 请求-响应模式,强耦合 |
| 异步消息 | 生产者-消费者模式,松耦合 |
| 事件驱动 | 发布-订阅模式,完全解耦 |
二、核心概念
2.1 事件定义
java
// 事件基类
public abstract class DomainEvent {
private final String eventId;
private final LocalDateTime occurredOn;
protected DomainEvent() {
this.eventId = UUID.randomUUID().toString();
this.occurredOn = LocalDateTime.now();
}
}
// 订单创建事件
public class OrderCreatedEvent extends DomainEvent {
private final String orderId;
private final String customerId;
private final BigDecimal totalAmount;
public OrderCreatedEvent(String orderId, String customerId, BigDecimal totalAmount) {
super();
this.orderId = orderId;
this.customerId = customerId;
this.totalAmount = totalAmount;
}
}
2.2 事件流
┌─────────┐ 事件 ┌─────────┐ 事件 ┌─────────┐
│ 生产者 │ ────────► │ 通道 │ ────────► │ 消费者 │
└─────────┘ └─────────┘ └─────────┘
│
▼
┌─────────┐
│ 存储 │
└─────────┘
三、事件模式
3.1 事件通知
java
// 简单事件通知
@Service
public class OrderService {
@Autowired
private ApplicationEventPublisher eventPublisher;
public void createOrder(Order order) {
// 业务逻辑
orderRepository.save(order);
// 发布事件
eventPublisher.publishEvent(new OrderCreatedEvent(order));
}
}
// 事件监听
@Component
public class NotificationListener {
@EventListener
public void onOrderCreated(OrderCreatedEvent event) {
// 发送通知
notificationService.send(event.getCustomerId(), "订单创建成功");
}
}
3.2 事件溯源
java
// 事件存储
public class EventStore {
public void append(String aggregateId, List<DomainEvent> events) {
events.forEach(event -> {
EventEntry entry = new EventEntry(
aggregateId,
event.getClass().getName(),
JSON.toJSONString(event),
LocalDateTime.now()
);
eventRepository.save(entry);
});
}
public List<DomainEvent> loadEvents(String aggregateId) {
return eventRepository.findByAggregateId(aggregateId)
.stream()
.map(this::deserialize)
.collect(Collectors.toList());
}
}
// 聚合重建
public class Order {
public static Order fromEvents(List<DomainEvent> events) {
Order order = new Order();
events.forEach(order::apply);
return order;
}
private void apply(DomainEvent event) {
if (event instanceof OrderCreatedEvent) {
applyOrderCreated((OrderCreatedEvent) event);
} else if (event instanceof OrderItemAddedEvent) {
applyOrderItemAdded((OrderItemAddedEvent) event);
}
}
}
3.3 CQRS
┌─────────────────────────────────────────────────────────────┐
│ CQRS 架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Command Side (写) Query Side (读) │
│ ┌─────────┐ ┌─────────┐ │
│ │ Command │ │ Query │ │
│ │ Handler │ │ Handler │ │
│ └────┬────┘ └────┬────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ │
│ │ Write │ │ Read │ │
│ │ Model │ │ Model │ │
│ └────┬────┘ └────┬────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ │
│ │ Write DB│ │ Read DB │ │
│ └─────────┘ └─────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
四、技术选型
4.1 消息中间件对比
| 中间件 | 吞吐量 | 延迟 | 适用场景 |
|---|---|---|---|
| Kafka | 百万级 | ms级 | 日志、大数据 |
| RabbitMQ | 万级 | μs级 | 业务消息 |
| RocketMQ | 十万级 | ms级 | 金融、交易 |
| Pulsar | 百万级 | ms级 | 云原生 |
4.2 选型建议
高吞吐、大数据 → Kafka
低延迟、可靠性 → RabbitMQ
金融级、事务 → RocketMQ
云原生、多租户 → Pulsar
五、代码实战
5.1 Spring Event
java
// 事件定义
public class OrderPaidEvent extends ApplicationEvent {
private final String orderId;
private final BigDecimal amount;
public OrderPaidEvent(Object source, String orderId, BigDecimal amount) {
super(source);
this.orderId = orderId;
this.amount = amount;
}
}
// 事件发布
@Service
public class OrderService {
@Autowired
private ApplicationEventPublisher eventPublisher;
public void payOrder(String orderId, BigDecimal amount) {
// 业务逻辑
orderRepository.updateStatus(orderId, OrderStatus.PAID);
// 发布事件
eventPublisher.publishEvent(new OrderPaidEvent(this, orderId, amount));
}
}
// 事件监听
@Component
public class OrderEventListener {
@EventListener
@Async
public void onOrderPaid(OrderPaidEvent event) {
// 更新积分
pointsService.addPoints(event.getOrderId(), event.getAmount());
// 发送通知
notificationService.sendOrderPaidNotification(event.getOrderId());
}
}
5.2 Kafka 集成
java
// 生产者配置
@Configuration
public class KafkaProducerConfig {
@Bean
public ProducerFactory<String, String> producerFactory() {
Map<String, Object> config = new HashMap<>();
config.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
config.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
config.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
return new DefaultKafkaProducerFactory<>(config);
}
@Bean
public KafkaTemplate<String, String> kafkaTemplate() {
return new KafkaTemplate<>(producerFactory());
}
}
// 消费者配置
@Configuration
@EnableKafka
public class KafkaConsumerConfig {
@Bean
public ConsumerFactory<String, String> consumerFactory() {
Map<String, Object> config = new HashMap<>();
config.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
config.put(ConsumerConfig.GROUP_ID_CONFIG, "order-group");
config.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
config.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
return new DefaultKafkaConsumerFactory<>(config);
}
}
// 消息发送
@Service
public class OrderEventPublisher {
@Autowired
private KafkaTemplate<String, String> kafkaTemplate;
public void publishOrderCreated(Order order) {
String message = JSON.toJSONString(order);
kafkaTemplate.send("order-created", order.getId(), message);
}
}
// 消息消费
@Component
public class OrderEventConsumer {
@KafkaListener(topics = "order-created", groupId = "inventory-group")
public void handleOrderCreated(String message) {
Order order = JSON.parseObject(message, Order.class);
inventoryService.reserveStock(order);
}
}
总结
✅ 事件驱动概述 :定义、特征、优势
✅ 核心概念 :事件、通道、存储
✅ 事件模式 :通知、溯源、CQRS
✅ 技术选型 :Kafka、RabbitMQ、RocketMQ
✅ 代码实战:Spring Event、Kafka 集成
本系列完结
作者 :刘~浪地球
系列 :架构设计(五)
更新时间:2026-04-10