【问题标题】:actor getting BufferOverflowException when sending Single发送 Single 时演员得到 BufferOverflowException
【发布时间】:2021-12-08 19:13:37
【问题描述】:

我正在尝试从 akka actor 发送数百个 http 请求,但是我收到了

akka.stream.BufferOverflowException: Exceeded configured max-open-requests value of [16]. This means that the request queue of this pool (HostConnectionPoolSetup(places.api.here.com,443,ConnectionPoolSetup(ConnectionPoolSettings(16,1,5,16,1,Duration.Inf,100 milliseconds,2 minutes,30 seconds,ClientConnectionSettings(Some(User-Agent: akka-http/10.2.0)...

这个application.conf

   http {
          host-connection-pool {
            max-connections = 16
            min-connections = 1
            max-open-requests = 16
          }
        }

这是代码

override def receive: Receive = {
      case Foo(_) => 
       val res: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = "http://..."))
   // do something for the result

我试图通过状态来控制,例如

override def receive: Receive = run(0)
def run(openRequests: Int) : Receive = {
  case Foo(_) if openRequests <= 16 => 
     context.become(run(openRequests + 1))
       val responseFuture: Future[HttpResponse] = Http().singleRequest(HttpRequest(uri = "http://..."))
       responseFuture.foreach(context.become(run(openRequests - 1)))
        //...

无论哪种方式,我都遇到了 BufferOverflowException 的相同异常

任何建议将不胜感激

【问题讨论】:

    标签: scala akka akka-stream akka-http


    【解决方案1】:

    Future 中异步使用context 是个坏主意。 context 仅在调用actor期间有效。

    错误是context.become(run(openRequests - 1)) 在创建Future 时使用openRequests 的值,而不是在调用它时的值。因此,当第一个请求完成时,即使可能有 15 个未完成的请求,它也会调用 context.become(run(-1))(这显然是假的)。

    解决办法是在foreach给自己发私信,而不是直接打电话给context.become。当参与者处理该消息时,它会减少 当前 请求计数,并在必要时发送新请求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-02
      • 1970-01-01
      • 1970-01-01
      • 2012-10-09
      • 1970-01-01
      • 2017-01-24
      • 1970-01-01
      • 2014-12-03
      相关资源
      最近更新 更多