scala - 在 akka-http 中,当响应不是 200 时,是否需要在接收器中消耗响应实体?

标签 scala akka akka-stream akka-http

在此akka-http documentation page底部有警告:

Be sure to consume the response entities dataBytes:Source[ByteString,Unit] by for example connecting it to a Sink (for example response.entity.dataBytes.runWith(Sink.ignore) if you don't care about the response entity), since otherwise Akka HTTP (and the underlying Streams infrastructure) will understand the lack of entity consumption as a back-pressure signal and stop reading from the underlying TCP connection!

This is a feature of Akka HTTP that allows consuming entities (and pulling them through the network) in a streaming fashion, and only on demand when the client is ready to consume the bytes - it may be a bit suprising at first though.

为什么在响应的状态代码不是 StatusCodes.OK 的情况下不需要这样做?还是实际上需要它,而该页面(也在下面)上显示的代码示例缺少它?

  def receive = {
    case HttpResponse(StatusCodes.OK, headers, entity, _) =>
      log.info("Got response, body: " + entity.dataBytes.runFold(ByteString(""))(_ ++ _))
    case HttpResponse(code, _, _, _) =>
      //why not here?
      log.info("Request failed, response code: " + code)
  }

最佳答案

应始终使用响应实体,但在实践中,错误响应通常是 HttpEntity.Strict 类型,无法使用这些实体不会导致任何背压问题。

对于感兴趣的人,从 Akka 2.4.9 开始,此行为来自 SlotProcessor.running它使用 HttpEntity.captureTermination 包装 HttpEntity .这种包装用于发出响应已被消耗的信号,从而提供正确的背压信号。对于 HttpEntity.Strict,因为实体主体已经在内存中,captureTermination 方法将返回 Future.success(()) 而另一个types 将包装 Source 并返回一个 Future,它在底层 Source 完成时完成。

关于返回的 HttpEntity 类型,就 API 而言,没有任何保证某些响应将是 HttpEntity.Strict,这就是为什么建议始终使用响应。 HttpResponseParser正在做解析响应的工作。据我了解,如果正文已读入内存(基于缓冲区大小)并且没有传输编码,则在读取响应时可以返回 HttpEntity.Strict,因为我们已经完成了所有操作工作。否则将返回 HttpEntity.DefaultHttpEntity.Chunked

在最后一次捕获时,如果您使用 HttpEntity 作为服务器响应的一部分(例如,在 complete 指令中),那么服务器可能会超时而不打扰消耗实体。在这种情况下,您可以使用 withRequestTimeoutResponse 指令来使用响应。

关于scala - 在 akka-http 中,当响应不是 200 时,是否需要在接收器中消耗响应实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39048057/

相关文章:

java - Scala 与 Spray Routing - 访问 GET 参数?

akka - 如何使用 SubFlows 对已排序流的项目进行分组?

scala - 如何从scala中的子类调用父类(super class)构造函数以及如何进行构造函数链接

kubernetes - 如何确定akka集群是否在kubernetes上运行?

azure - AKKA 是否尝试在内存中执行与 Azure 服务总线队列在磁盘上执行的操作相同的操作?

scala - Akka:在集成测试中模拟组件的策略

scala - 如何使用 akka 的 http 客户端设置最大内容长度?

java - Akka:Java 中的 Flow 相当于什么

scala - Sbt:如何为所有项目定义任务?

scala - 如何将对象传递给 Scala 中的方法