跳到主要内容
版本:3.0.0

事件总线

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.Dataobject,消费端要自己转回业务对象

常见问题

为什么发了消息却没有被消费

优先检查:

  • 是否启用了 EventBus
  • MessageName 是否完全一致
  • 消费者是否实现了 IMessageConsumer<Message>
  • 消费者所在程序集是否已经被应用引用

一个消息能不能给多个消费者

可以。
这正是当前事件总线最常见的用法之一。

什么场景下要切 Redis 容器

当你需要把默认消息容器替换成 Redis 介质时,就接 Redis 容器扩展。

继续阅读