在此akka-http documentation page底部有警告:
Be sure to consume the response entities
dataBytes:Source[ByteString,Unit]
by for example connecting it to a Sink (for exampleresponse.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.Default
或 HttpEntity.Chunked
。
在最后一次捕获时,如果您使用 HttpEntity
作为服务器响应的一部分(例如,在 complete
指令中),那么服务器可能会超时而不打扰消耗实体。在这种情况下,您可以使用 withRequestTimeoutResponse
指令来使用响应。
关于scala - 在 akka-http 中,当响应不是 200 时,是否需要在接收器中消耗响应实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39048057/