我写了一个API,它需要几分钟来创建一个响应。这显然会导致连接重置:
curl: (56) Recv failure: Connection reset by peer
我已经尝试了Akka HTTP的超时配置,但似乎没有解决上述问题。
akka.http.server.idle-timeout = 600 s
akka.http.client.idle-timeout = 600 s
akka.http.server.request-timeout = 600 s
我怀疑问题出在idle-timeout
上,但上面的配置似乎没有任何影响。
谁能告诉我问题出在哪里?
我尝试了一个相反的场景,我把idle-timeout
设置为5s
,这是为了重置连接,但即使这样也不起作用。不知道这里到底是什么问题。有人能解释一下这种行为吗?我该如何修复它?
我已经实现了一个完整的工作示例,任何人都可以尝试使用here。
application.conf
akka.http.server.idle-timeout = 5 s
akka.http.client.idle-timeout = 5 s
akka.http.server.request-timeout = 600 s
helloworld {
http {
interface = "127.0.0.1"
port = "8066"
}
}
Routes.scala
package com.codingkapoor.helloworld.http
import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.Route
import akka.util.Timeout
import akka.stream.ActorMaterializer
import scala.concurrent.duration._
private[helloworld] trait Routes extends JsonSupport {
implicit lazy val timeout: Timeout = Timeout(5.minute)
implicit def materializer: ActorMaterializer
lazy val routes: Route = pathSingleSlash {
get {
Thread.sleep(180000)
complete(StatusCodes.OK, "Hello World!")
}
}
}
1条答案
按热度按时间xiozqbni1#
有两个错误,我发现,修复这解决了问题。
错误1
在创建
ActorSystem
的示例时,我忘记了传递appConf
作为参数,没有它,ActorSystem
总是用默认的akka配置来创建的。因此,在创建ActorSystem
的示例时,一定要确保传递appConf
,否则你的akka配置将永远不会生效。你好世界.Scala
错误2
在这个问题中,我把
Thread.sleep
放到了路由线程中,这导致idle-timeout
只有在睡眠结束后才能访问日志。我想说的是,当我在没有
appConf
的情况下创建ActorSystem
时,应该使用1 min
的默认idle-timeout
,但因为我在路由线程中放置了3 min
的Thread.sleep
,所以1 min
的idle-timeout
只在3 mins
之后才被记录。模拟延迟响应的最好方法是使用如下所示的future来完成请求。这里我设置了
4 mins
的idle-timeout
和3 mins
的request-timeout
。这会导致请求总是得到服务!希望这能澄清。应用程序.conf
路径.scala
整个想法是,如果
idle-timeout
大于request-timeout
,您的请求至少有机会得到服务,否则它们将被丢弃!您可以找到工作解决方案here。