MassTransit出现Messages types must not be System types异常问题咨询
问题1:状态机事件触发时机
StartProcessingMessage 发布后会同时被两个订阅者消费:一个是 StartReconstructionConsumer,另一个是绑定到saga.service队列的状态机。只要不存在对应ActivationId的已创建Saga实例,状态机就会触发Initially分支的逻辑,创建新的Saga实例,执行自定义逻辑并切换到ProcessingStartedState状态。默认两者消费并行,没有固定先后顺序。
问题2:状态流转时序保证
当前设计存在时序风险:如果StartReconstructionConsumer处理速度快,在状态机完成初始化进入ProcessingStartedState之前就发布了ReconstructionFinishedMessage,状态机找不到对应状态的Saga实例,消息会被路由到错误队列。可通过两种方案解决:
- 把业务处理逻辑封装为状态机活动(Activity)放在状态机内部执行,状态机天然保证状态流转顺序
- 给Saga配置重试策略,收到
ReconstructionFinishedMessage无匹配实例时自动重试,等待状态机初始化完成
整体消息交互逻辑符合多阶段流程的设计方向,解决时序问题即可正常运行。
问题3:
Messages types must not be System types错误解决 报错根源是状态机中Publish方法的用法错误:
你当前的写法中context.Init<T>返回的是Task<T>类型,直接作为返回值传给同步的Publish方法,MassTransit会将Task<ProcessingFinishedMessage>识别为要发布的消息类型,而Task属于系统类型,因此抛出异常。
修改方案二选一即可:
- 使用异步的
PublishAsync方法接收Init的返回值
.PublishAsync(async context => { return await context.Init<ProcessingFinishedMessage>(new { ActivationId = context.Data.ActivationId }); })
- 直接传入匿名类,无需手动调用
Init
.Publish<ProcessingFinishedMessage>(context => new { ActivationId = context.Data.ActivationId })
内容的提问来源于stack exchange,提问作者Lentyai
相关产品推荐
相关产品推荐

