项目地址
- 教程作者:
- 教程地址:
- 代码仓库地址:
- 所用到的框架和插件:
dbt
airflow
一、OutBox Pattern
- 这种方式依赖于MediaR的publish方法,将DomainEvent发送到消息队列
毛子038
1.1 OutBox表配置
1. OutBoxMessage类
- 定义OutBoxMessage类
2. OutboxMessage表配置
- 创建outbob message表
3. 给每个模块生成outboxmessage表
- 给所有模块生成该表
1.2 发布OutBox Message
- Users模块里,对Users的领域事件进行发布
1. 修改Intercepotor
- 之前不需要事务,所以直接在EF save之后,进行了事件的发布,现在需要将业务的保存和outbox message一起原子性的保存,所以,需要在save 之前对领域事件进行处理
SerializerSettings
:用于序列化和反序列化DomainEvent时,实例的构造
2. 配置Quartz
- 安装Quartz包
<PackageReference Include="Quartz.Extensions.Hosting" Version="3.8.1" />
3. 创建Quatz方法发布领域事件
- IJob.Execute方法,Quatz定时任务执行的逻辑,通过MediaR发布DomainEvent
GetOutboxMessagesAsync
使用行锁,获取outbox_message表未处理的message
UpdateOutboxMessageAsync
:将处理过的消息,在outbox_message表里标记未处理
4. 创建Quatz定时任务
5. 注册Quatz服务和配置
6. 流程梳理
- OubBox模式,Publish消息的流程
Quartz Job Start
↓
Begin Transaction
↓
SELECT 未处理消息 (FOR UPDATE)
↓
for 每条消息:
↓
反序列化为 DomainEvent
↓
通过 MediatR 发布事件 (IPublisher.Publish)
↓
成功 or 记录异常
↓
更新消息状态(已处理/失败)
↓
Commit Transaction
↓
结束日志
- 当我们发起用户注册后
- 在用户save之前会将用户的DomainEvent保存在outbox message表
- 然后Quatz会每5秒一次,一次50条数据读取该表里processed_on_utc为空的值,并且通过MessTransit发布出去,然后将发布