MassTransit高级请求/响应模式实现:请求发往TransactionService响应从PspService返回
实现方案
你需要的是跨服务透传响应的通信模式,核心逻辑是将API发起请求时自带的ResponseAddress(API的响应队列地址)、RequestId(请求唯一标识)两个消息头,从TransactionService透传给PspService,最后由PspService直接将响应发送到API的响应队列即可。
各服务代码修改示例
1. API端(无额外修改,保持原有调用逻辑即可)
API侧仅需正常注册CreatePayment的请求客户端,原有调用逻辑不需要改动:
// 服务注册时添加请求客户端配置 services.AddMassTransit(x => { // 设置请求超时时间可根据业务调整 x.AddRequestClient<CreatePayment>(TimeSpan.FromSeconds(30)); // 其余RabbitMQ、服务配置保持原有即可 }); // 业务调用逻辑 var form = await requestClient.GetResponse<PaymentForm>(new CreatePayment());
2. TransactionService端(透传消息头)
在CreatePaymentConsumer中发送BuildPaymentForm消息时,透传API的响应地址和请求标识:
namespace TransactionService { public class CreatePaymentConsumer : IConsumer<CreatePayment> { public async Task Consume(ConsumeContext<CreatePayment> context) { await context.Send<BuildPaymentForm>(new BuildPaymentForm { // 填充你的业务参数 }, sendContext => { // 透传API的响应队列地址 sendContext.ResponseAddress = context.ResponseAddress; // 透传原始请求ID,用于API侧匹配对应的请求 sendContext.RequestId = context.RequestId; // 可选:透传关联ID用于链路追踪 sendContext.CorrelationId = context.CorrelationId; }); // 不需要给API返回响应,直接结束当前消费逻辑即可 } } }
3. PspService端(直接向API发响应)
不要使用默认的context.Respond方法(该方法会将响应发给当前消息的发送方也就是TransactionService),而是手动向透传过来的ResponseAddress发送响应:
namespace PspService { public class BuildPaymentFormConsumer : IConsumer<BuildPaymentForm> { public async Task Consume(ConsumeContext<BuildPaymentForm> context) { var paymentForm = new PaymentForm { // 你的业务逻辑生成支付表单 }; // 直接向API的响应队列发送结果 await context.Send(context.ResponseAddress.Value, paymentForm, sendContext => { // 必须携带原始请求ID,API的请求客户端才能匹配到对应的等待任务 sendContext.RequestId = context.RequestId; sendContext.CorrelationId = context.CorrelationId; }); } } }
注意事项
- 三个服务需要使用统一的消息契约,
CreatePayment、BuildPaymentForm、PaymentForm三个类的命名空间、字段定义必须完全一致。 - 异常场景下可透传
FaultAddress消息头,将错误消息直接发送给API,API侧的请求客户端可以正常捕获到异常信息。 - 需注意设置合理的请求超时时间,避免API侧长时间等待无效请求。
内容的提问来源于stack exchange,提问作者Hiep
相关产品推荐
相关产品推荐

