最佳答案
我也对这个主题进行了很多研究(将应用于我的 NServiceBus 和 MessageHandler 的工作),并想提供我对此事的想法。但是我还没有确定最好的模型是什么。
如果您忽略 ServiceFabric 的实际实现,那么在可靠性方面,我会按以下顺序对提议的方法进行分类:
- C) 在服务间通信方面,存储转发模型可能是 3 种模型中最好的,所有服务都可以彼此独立工作,并且绝不会受到网络中断的影响(缺点是延迟增加)
- A) 每个服务的输入队列:每个服务的工作不受网络中断的影响。然而,当它希望将消息发送到另一个服务时,它可能会受到网络中断的影响,并且需要内置重试来适应这种情况。
- B) 每个服务的输出队列:可能是 3 个模型中最少的一个,因为每个服务都直接依赖于其他服务的资源,这会导致对节点之间网络可用性的极大依赖。
如果从简单的角度来看,我会按以下方式分类
- A) 每个服务的输入队列:由于消息源需要主动将消息路由到给定的目标队列,因此使用路由模式实现业务流程或工作流程(我假设您的管道将代表的内容)相当简单(静态路由或使用路由滑动模式的动态路由
- C) 存储和转发:同样,路由是实现的显式部分,因此静态和动态路由模式都是可能的,但是实际实现比较困难,因为您需要构建和管理从传输中传输消息的消息泵队列(输出)到目标队列以及关联的需要将上下文从消息源流到消息泵。 (无耻插件:NServiceBus 是一个框架,可以为你消除复杂性,让这个场景像 A 一样简单)
- B) 每个服务的输出队列:每个服务都需要设置为显式地从另一个队列中读取,这种方法只允许静态路由,因为路由规则嵌入在您仅读取的位置中(这严重限制了您从功能透视)
如果我们考虑 ServiceFabric 的实现细节,那么我假设您想使用 IReliableQueue 实现?但这种实现有一些缺点,这让我想知道这些模式是否真的可以在 ServiceFabric 的 native 存储基础设施上正确实现。
- 存储基础架构仅适用于有状态服务,因此无状态服务(例如 Rest API 或其他协议(protocol)终止网关)不能成为管道的一部分(通常您需要其中之一作为入口点)
- 只有 1 个线程可以同时访问可靠队列,因此不可能同时对同一个队列进行写入和读取。这严重限制了队列的吞吐量。
- 访问可靠队列需要本地事务,但这些事务仅限于单个分区。因此,也不可能扩展有状态服务来创建竞争性的消费者模式。
鉴于这些缺点,我仍然倾向于为 SF 服务使用另一种类型的排队基础设施,而不是 SF 的持久性模型,例如 Azure 服务总线或 Azure 存储队列(NserviceBus 也允许)。
简而言之,我会支持 A 和 C,稍微偏爱 C,但在这些缺点得到解决之前,我不相信使用可靠队列作为实现。
关于c# - Service Fabric 可靠服务管道设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33726653/