我们有一个相当高的吞吐量演员系统,它通过http进行异步调用外部系统。我们发现,由于他们从我们那里收到的电话数量众多,下游系统正在遭到不测。限制异步调用演员
使用由下游系统中的呼叫“管”在这里描述的模式:https://petabridge.com/blog/akkadotnet-async-actors-using-pipeto/
之所以如此多的呼叫到下游系统做是因为一个演员不会等待响应异步调用在它的邮箱中处理下一条消息之前返回(当异步调用被启动时,它完成了消息)。显然这是设计的,但在这种情况下,会导致对外部服务进行非常多的异步调用。
我们需要一种限制呼叫的方法。我可以想到解决这个问题的几个可能的解决方案。
通过等待任务完成来同步执行对外部服务的调用。为演员设置一个池路由器,这基本上是一种限制对这个外部服务进行调用的方式。
使用ReceiveAsync方法而不是Receive。这基本上是完全相同的选项1.在petabride页我张贴以上虽然说这个这个方法 - “只是不去做” :)
使异步调用之前,开始积攒任何来电消息,然后在异步任务完成后取消它们。显然使用这种方法的吞吐量要受限得多。
我想知道有没有人在使用akka时有类似的问题,并能解决它?
编辑:
那么它到底是只为我们的工作选项1。即有一个带有Receive()的池路由器,该路由器专门等待IO调用所需的(调用外部系统的api)。这似乎工作得很好,我们可以通过设置池大小来控制'节流'。
我们尝试了选项2(ReceiveAsync),但是我们发现在某些时候系统会停下来并停止响应而不会引发任何错误。我们怀疑它陷入了僵局。这可能是由于异步函数的工作方式,而只是使用.Wait()或.Result等待任务。我现在可以看到为什么Petabridge建议不要使用ReceiveAsync :)
我们没有尝试选项3,因为这意味着更重要的更改。
感谢您的回复,这听起来像我们正在接近这个以相当类似的方式对自己这是很好的......稍后将发布一个答案,一旦我们制定了什么适合我们。 – lachy