事件总线
3.0.0 页面说明
- 3.0.0 说明:当前页已重写为
3.x的事件总线路由页。- 推荐阅读顺序:先看当前页选型,再进入组件页。
Aegis.EventBus 用来做应用内部的异步生产消费。它适合把主链路里的非核心后置动作拆出来,比如写业务日志、做状态同步、触发后续处理。
先做选型
当前这组能力建议这样理解:
| 方案 | 适合什么场景 |
|---|---|
Aegis.EventBus | 默认基础能力,适合应用内异步解耦 |
Aegis.EventBus + Aegis.EventBus.Container.Redis | 需要把消息容器切到 Redis |
如果你只是要用消息生产消费,先从 Aegis.EventBus 开始就够了。
推荐接入路径
第一步:启用 EventBus
{
"Components": {
"Services": [
"EventBus"
],
"Middlewares": []
}
}
第二步:在业务里发送消息
public class UserService : IUserContract
{
private readonly IMessageSender _messageSender;
public UserService(IMessageSender messageSender)
{
_messageSender = messageSender;
}
public async Task SendUserMessageAsync(UserDto dto)
{
await _messageSender.Send(new Message
{
MessageName = "UserChanged",
Data = dto,
CreatedTime = DateTime.Now
});
}
}
第三步:定义消费者
public class UserChangedConsumer : IMessageConsumer<Message>
{
public string MessageName { get; } = "UserChanged";
public async Task<bool> ExecuteAsync(Message message)
{
var dto = message.Data as UserDto;
Console.WriteLine(dto?.Name);
await Task.CompletedTask;
return true;
}
}
一个消息可以有多个消费者
如果多个消费者使用同一个 MessageName,它们都会被执行。
public class HealthConsumer : IMessageConsumer<Message>
{
public string MessageName { get; } = "Health";
public Task<bool> ExecuteAsync(Message message)
{
Console.WriteLine("consumer-1");
return Task.FromResult(true);
}
}
public class Health2Consumer : IMessageConsumer<Message>
{
public string MessageName { get; } = "Health";
public Task<bool> ExecuteAsync(Message message)
{
Console.WriteLine("consumer-2");
return Task.FromResult(true);
}
}
这很适合把一个业务动作拆成多个后置处理步骤。
什么时候要上 Redis 容器
如果你要把消息容器切到 Redis,可以继续接:
接入后,发送端和消费端代码本身不用改,变的是底层消息容器。
使用时的几个关键点
- 当前对外主线只讲
Message模型 MessageName最好统一写成常量,避免拼写不一致- 消费者默认是单例,复杂业务建议继续下沉到服务层
Message.Data是object,消费端要自己转回业务对象
常见问题
为什么发了消息却没有被消费
优先检查:
- 是否启用了
EventBus MessageName是否完全一致- 消费者是否实现了
IMessageConsumer<Message> - 消费者所在程序集是否已经被应用引用
一个消息能不能给多个消费者
可以。
这正是当前事件总线最常见的用法之一。
什么场景下要切 Redis 容器
当你需要把默认消息容器替换成 Redis 介质时,就接 Redis 容器扩展。