前言
在我之前的文章中,我们探讨了 Brighter 如何与 RabbitMQ 集成。本文将深入解析 Brighter 中三个核心消息处理方法:Send、Publish 和 Post 的区别与应用场景。
什么是消息总线(Bus)?
消息总线是系统中用于组件间数据传输的通道。Brighter 将其分为两种类型:
1. 内部总线(Internal Bus)
-
运行范围:应用程序内部。
-
优化特性:直接内存处理(无需序列化消息)。
-
自动注册:默认注册所有消息和对应的处理程序(Handler)。
2. 外部总线(External Bus)
-
运行范围:连接外部系统(如 RabbitMQ、Kafka、AWS SQS/SNS)。
-
依赖 I/O:需通过网络或文件操作访问外部资源。
示例:配置 RabbitMQ 外部总线
var rmqConnection = new RmqMessagingGatewayConnection
{
AmpqUri = new AmqpUriSpecification(new Uri("amqp://guest:guest@localhost:5672")),
Exchange = new Exchange("paramore.brighter.exchange")
};
// 注册外部总线
services.AddServiceActivator(options => {})
.UseExternalBus(
new RmqProducerRegistryFactory(
rmqConnection,
new RmqPublication[]
{
new()
{
MakeChannels = OnMissingChannel.Create,
Topic = new RoutingKey("greeting.event")
}
}
).Create()
);
命令(Command)与事件(Event)
命令(Command)
-
用途:触发一个立即执行的操作(如
CreateUser、UpdateData)。 -
处理规则:仅允许一个处理程序(Brighter 强制要求)。
-
命名规范:使用祈使句动词(如
ShipOrder)。
public class CreateUser : Command
{
public CreateUser() : base(Guid.NewGuid()) { }
public string Name { get; set; }
}
事件(Event)
-
用途:通知已发生的状态变化(如
UserCreated、OrderShipped)。 -
处理规则:允许多个处理程序。
-
命名规范:使用过去式动词(如
InventoryUpdated)。
public class UserCreated : Event
{
public UserCreated() : base(Guid.NewGuid()) { }
public string Name { get; set; }
}
Send、Publish 和 Post 的使用场景
| 方法 | 用途 | 总线类型 | 处理行为 |
|---|---|---|---|
| Send | 命令(Command) | 内部总线 | 执行唯一处理程序 |
| Publish | 事件(Event) | 内部总线 | 执行所有注册的处理程序 |
| Post | 命令/事件 | 外部总线 | 发送到外部系统 |
使用示例:
// 发送命令(内部总线,单处理程序)
commandProcessor.Send(new CreateUser { Name = "Alice" });
// 发布事件(内部总线,多处理程序)
commandProcessor.Publish(new UserCreated { Name = "Bob" });
// 投递到外部队列(如 RabbitMQ)
commandProcessor.Post(new OrderShipped { OrderId = 123 });
代码解析:Send 与 Publish
命令处理程序(单例)
public class MyCommandHandler : RequestHandler<MyCommand>
{
private readonly ILogger<MyCommandHandler> _logger;
public MyCommandHandler(ILogger<MyCommandHandler> logger) => _logger = logger;
public override MyCommand Handle(MyCommand command)
{
_logger.LogInformation(
"命令处理完成:ID={Id}, 内容={Text}",
command.Id, command.Text
);
return base.Handle(command);
}
}
事件处理程序(多例)
public class MyEventHandler1 : RequestHandler<MyEvent>
{
private readonly ILogger<MyEventHandler1> _logger;
public MyEventHandler1(ILogger<MyEventHandler1> logger) => _logger = logger;
public override MyEvent Handle(MyEvent @event)
{
_logger.LogInformation(
"处理程序1:事件 ID={Id}, 内容={Text}",
@event.Id, @event.Text
);
return base.Handle(@event);
}
}
public class MyEventHandler2 : RequestHandler<MyEvent>
{
// 实现与 MyEventHandler1 类似
}
执行代码
var processor = provider.GetRequiredService<IAmACommandProcessor>();
// 发送命令(触发单处理程序)
processor.Send(new MyCommand { Text = "你好,命令" });
// 发布事件(触发所有处理程序)
processor.Publish(new MyEvent { Text = "你好,事件" });
关键注意事项:
-
若对同一个命令使用
Send但存在多个处理程序,Brighter 会抛出异常。 -
Post会绕过进程内处理,直接通过外部总线传输消息。
总结
Brighter 的命令模式通过解耦操作与执行,为构建可扩展系统提供了优雅的解决方案。后续文章将深入探讨重试机制、管道(Pipeline)和监控功能。
完整代码示例:
GitHub 仓库
1029

被折叠的 条评论
为什么被折叠?



