【问题标题】:Using transactional bus inside consumer在消费者内部使用事务总线
【发布时间】:2021-04-21 10:38:23
【问题描述】:

我有 REST API 网关,它使用 MassTransit 请求客户端调用其中一项微服务。这个请求不是持久的,并且只存在很短的时间 - 本质上它只是替换“传统”同步(通过 HTTP/GRPC/等)网关-微服务通信。

在微服务方面,我有消费者,它在后台使用 DbContext 和事务 (EFC) 在数据库中执行一些工作。工作完成后,它应该发布“WorkDoneEvent”(稍后由其他微服务使用)并将工作结果返回给 api 网关。事件必须与用于执行工作的事务一起以原子方式发布。 ApiGateway 是否会收到响应/是否会重试请求并不重要 - 一旦提交事务,必须保证工作结果和发送“WorkDoneEvent”。

通常这是通过事务发件箱完成的,它首先将发布的事件保存到与工作完成相同的事务中的数据库中。 (然后一些进程不断地“轮询”发件箱并尝试向代理发送消息,完成后它会从发件箱中删除消息)。据我所知。

MassTransit 似乎内置了交易发件箱:https://masstransit-project.com/advanced/middleware/transactions.html#transactional-bus

但在文档中明确指出:

在编写消费者时切勿使用 TransactionalBus 或 TransactionalEnlistmentBus。这些工具非常具体,只应在所描述的场景中使用。

而这正是我想做的……

为什么我不应该这样做?

【问题讨论】:

    标签: masstransit


    【解决方案1】:

    我建议使用作为 MassTransit 一部分的 InMemoryOutbox。它的重量明显更轻,旨在在消费者中工作,并且在消费者完成之后(但在代理确认消息之前)才会发布您的事件。唯一的考虑是您的消费者应该是幂等的(在您的方法中也必须是这种情况),如果该操作已经在重试时执行,它应该重新发布事件。

    videosarticlessample与之配套。

    【讨论】:

    • 我阅读了有关内存发件箱的信息,但我仍然不明白 - 如果消费者中的数据库事务成功并且在整个系统出现故障后一微秒(代理、消费者服务、网关服务)。客户端收到来自网关的超时错误和发生坏事的信息。由于这是短暂的请求响应消息,因此它会在 20 秒后过期。系统启动,我们最终在数据库中提交了数据,代理为空,并且没有任何信息是否将“WorkDone”事件发送到代理。内存发件箱只有在请求-响应持久且保留在代理中(未过期)时才能工作?
    • “短期请求/响应”和“数据库中的持久存储”不应在同一段落中使用...
    • 好的,我想我现在明白了:你的意思是成功的“请求”(发送给代理)应该已经保证它会被处理(并且它确实是因为它是持久的)。在我的情况下是 API GW 微服务通信,它是“响应”,可以在超时后安全丢弃(消费者也可以忽略发送响应引起的任何错误)。
    • 完全正确 - 如果超时,API 连接消失,响应是额外的。持久命令仍将被处理/重试/等。基于接收端点配置并且不会丢失。
    猜你喜欢
    • 2021-11-14
    • 1970-01-01
    • 2015-08-15
    • 2022-07-16
    • 1970-01-01
    • 2020-04-21
    • 1970-01-01
    • 2019-01-15
    • 2013-05-23
    相关资源
    最近更新 更多