Rebus使用疑问:API如何离线将消息存入SQL队列无需Worker在线
解决方案
核心问题分析
你的API当前配置了SetNumberOfWorkers(1),这会让Rebus在API启动时自动启动消费者,尝试处理QueueMsgs队列里的消息。当找不到对应消息的处理器时,就会触发重试策略,最终将消息移入错误队列。而你的需求是API仅作为消息生产者,不处理消息,只负责将消息存入队列等待Worker处理。
步骤1:修正API的Rebus配置
移除SetNumberOfWorkers(1),并添加配置明确API仅作为生产者(不启动消费者):
services.AddRebus((configure) => configure .Logging(l => l.NLog()) .Transport(t => t.UseSqlServer(transportOptions, "ApiProducerQueue")) // 设置API专属的输入队列(无需消费,仅用于标识生产者端点) .Options(o => o.SimpleRetryStrategy(maxDeliveryAttempts: 10)) .Options(o => o.DoNotStartAutoHandlers()) // 禁用自动启动处理器 .Options(o => o.SetMaxParallelism(0)) // 彻底关闭消费能力 );
步骤2:正确发送消息到Worker的队列
使用Send方法时,明确指定Worker监听的队列名称(假设Worker的输入队列是QueueMsgs):
// 直接将消息发送到Worker的专属队列 await _bus.Send(user, destinationAddress: "QueueMsgs");
关于Publish模式的补充说明
如果想用发布/订阅模式,需满足以下条件:
- Worker服务启动时,针对
User类型消息注册处理器,并完成订阅。 - API与Worker使用同一个订阅存储表
QueueMsgsSubs。 - API仍需保留仅生产者的配置(移除消费相关设置)。
但对于你的点对点队列处理场景,使用Send指定目标队列更直接,无需维护订阅关系。
Worker服务的配置注意事项
Worker需监听QueueMsgs队列,并注册对应消息处理器:
services.AddRebus((configure) => configure .Logging(l => l.NLog()) .Transport(t => t.UseSqlServer(transportOptions, "QueueMsgs")) // Worker的输入队列 .Options(o => o.SetNumberOfWorkers(1)) .Options(o => o.SimpleRetryStrategy(maxDeliveryAttempts: 10)) ); // 注册User消息的处理器 services.AddRebusHandler<UserHandler>();
完成上述配置后,API启动时不会尝试消费消息,只会将消息存入QueueMsgs队列;Worker启动后会自动从该队列读取并处理消息,即使Worker未运行,消息也会一直保留在队列中。
内容的提问来源于stack exchange,提问作者Luis Agudo
相关产品推荐
相关产品推荐

