MassTransit
类似于EF core 的作用,让开发者更容易与RabbitMQ、kafka
等消息代理系统交互(等同于EF core 与MySQL、MSSQL、Sqlite的关系)。
当然,我们也可以引用RabbitMQ
等提供的原生Client
支持。
长远来看,如果想让系统更具兼容性(面对抽象接口开发),MassTransit
更为合适。
基本用法
AddMassTransit
委托定义:Action<IBusRegistrationConfigurator> configure
内部方法:ServiceCollectionBusConfigurator:RegistrationConfigurator AddConsumer
委托调用:configure?.Invoke(configurator);
作用:委托传出configurator
,提供了AddConsumer
的方法
AddConsumer
Activator.CreateInstance ConsumerDefinition
转为IRegister
通过 IContainerRegistrar.GetOrAdd
注册为Scoped
TConsumer
注入为scope
collection.TryAddScoped
Endpoint
以上面同样的方式注册为Scoped
AddMassTransitComponents
collection.TryAddScoped(GetCurrentPublishEndpoint) new PublishEndpoint(...)
注册为scoped
,解析为IPublishEndpoint
IPublishEndpoint.Publish
调用 sendEndpoint.Send
UsingRabbitMq
IBusRegistrationConfigurator.SetBusFactory
ServiceCollectionBusConfigurator
实现了IBusRegistrationConfigurator
,并在SetBusFactory
中注入依赖,其中调用了RabbitMqRegistrationBusFactory.CreateBus(嵌套了基类的CreateBus)
生成IBusInstance
,,生命周期是单例。
其中参数列表中Action<IBusRegistrationContext, IRabbitMqBusFactoryConfigurator> configure
,则表示你可以在生成bus前修改某些配置
BusRegistrationContext
提供configure Consumer/Endpoint
的方法
IRabbitMqBusFactoryConfigurator
对应Endpoint
注意,IRabbitMqBusFactoryConfigurator
定义了接口方法Host
,意味着UsingRabbitMq
可以通过委托修改hostsetting
void Host(RabbitMqHostSettings settings);
IBus
的Publish
原理
MassTransitBus
构造函数中传入IReceiveEndpointConfiguration
,并初始化PublishEndpoint
,后续Publish
中调用PublishEndpoint.Publish
PublishEndpoint
调用PublishInternal
,通过PublishEndpointProvider.GetPublishSendEndpoint
获取SendEndpoint
列表,再依次调用SendEndpoint.Send
SendEndpoint
调用(RabbitMqSendTransport)ISendTransport.Send
ISendTransport.Send
调用(SendTransportContext)RabbitMqSendTransportContext.Send
中 实例化并传入SendPipe<T>
SendTransportContext
调用(PipeContextSupervisor) IModelContextSupervisor.Send
IModelContextSupervisor.Send
调用SendPipe.Send(context)
SendPipe.Send
中调用 RabbitMqModelContext.BasicPublishAsync
RabbitMqModelContext.BasicPublishAsync
调用 ImmediatePublisher.Publish
ImmediatePublisher.Publish
调用 RabbitMQ.Client.IModel.BasicPublish
Masstransit
规则
UsingRabbitMq
中ConfigureEndpoints(context)
将在rabbitMQ
上以SetKebabCaseEndpointNameFormatter
方式自动配置exchange
和queue
exchange:
- 命名空间
+
:+interfaceName
,如Lsd.Events:StaffUpdated
,类型fanout,durable
staff-updated
,接口名短横线隔开,类型fanout,durable
queue:
staff-updated,binding from exchange(staff-updated)
,同名交换机
webapi 控制器中注入IPublishEndpoint
,_publishEndpoint.Publish<StaffUpdated>(...)
将发送staff-updated exchange, routingkey = staff-updated
,即匹配queue staff-updated
在不同的项目中,共用相同命名空间的接口(shared project
),可以打通默认规则的sender/publisher
对应的consumer
aspnetcore 依赖注入
IBusControl
(单例)IBus
(单件)ISendEndpointProvider
(范围)IPublishEndpoint
(范围)
Send
发送信息到端点
如果是注入ISendEndpointProvider
,需要通过EndpointConvention
匹配endpoint
或者通过GetSendEndpoint
或者endpoint
Publish
广播消息到订阅了该消息类型的所有消费者consumers
IPublishEndpoint
,则与默认规则一致,或在UsingRabbitMq
中手动配置Message(...交换机)
和Send(...routingkey)
MediatR
与 MassTransit
不同,目的是为了解耦,避免Controller
变得越来越臃肿,适用于in-process
的信息交互
基本用法
先定义IRequest/INotification 、IRequestHandler/INotificationHandler
,在Controller
中通过解析的IMediator
调用Publish
,方法返回Task/Task<ReponseType>
流量冲击
MQ-client
提供拉模式,定时或者批量拉取,可以起到削平流量,下游自我保护的作用(MQ需要做的)
要想提升整体吞吐量,需要下游优化,例如批量处理等方式(消息接收方需要做的)