【问题标题】:Is it a good idea to use kinesis for message passing in akka.net在 akka.net 中使用 kinesis 进行消息传递是个好主意吗
【发布时间】:2018-06-27 18:27:04
【问题描述】:
我们目前正在 Akka.NET 之上使用 DDD 原则构建一个演员系统。
在如何使我们的服务具有弹性方面,我们有几个缺失点:
- Actor 之间默认为 At-Most-Once-Delivery
- 演员邮箱的弹性
- FSMactor 正在存储无法立即处理的传入消息 - 弹性?
- Pub/Sub 模式(和弹性)
如果某些消息丢失,我们不确定该怎么办,因此我们无法转换到下一个状态来完成请求,这涉及到多个参与者。
我的想法是使用像 kinesis 这样的事件流系统来传递消息。然后,我们到处都有弹性,只需要知道我们处理了流中的哪个事件。
我还缺少其他东西吗?你认为这是个好主意吗?这是否违反了某些最佳做法?
【问题讨论】:
标签:
actor
amazon-kinesis
akka.net
akka.net-streams
【解决方案1】:
对于 Akka.NET(实际上是所有流行的分布式参与者模型实现),最多一次交付是经过深思熟虑的选择。过去,来自 JVM 的原始 Akka 在持久队列上实现了邮箱实现,但这个想法在几年前因为实验失败而被放弃。
- Akka.NET 主要面向消息传递。对于每个用户请求,可能有数十(或数百)条消息在参与者之间传递以对其进行处理。使用内存消息传递,这既快速又简单(Akka.NET 可以在单台机器内传递数百万条消息/秒)。
- 当谈到可靠处理时,您通常想到的并不是可靠的持久邮箱,而是重要的。线索是可靠地处理消息 - 您可以轻松地从队列或日志中删除消息,并且在您完成处理之前机器会中断。
- 至少一次处理强制您能够识别重复项(除了重新交付之外,这对每个参与者来说都不是经济高效的),或者将您的所有处理逻辑设计为以幂等方式工作。
在某些情况下,确认就足够了,即用户发送请求并期望响应在某个超时内到达。如果回复没有到达,即因为一些消息丢失,只需向请求者返回一个失败(并可能要求他/她重试)。
另一种常见模式是在特定位置使用队列/日志,即作为演员系统前面的层。这样,所有用户请求首先发送到持久队列,然后由参与者系统逻辑从中获取。一旦内部的参与者完成处理请求,他们就可以提交它并从队列中删除。如果发生了一些故障,整个过程(或其中的一部分)会被简单地重试。