[英]How to gracefully shutdown http4s
我正在使用 http4s BlazeServer 0.21,如何正常关机? 我想拒绝所有即将到来的请求,并在硬关闭时间内保持处理未完成的请求和响应。
我尝试使用serveWhile
启动服务器并设置 shutdownHook SignallingRef
。 服务器流和中间件按预期延迟(因此我们的指标和日志中间件仍记录此响应)
//serverStream
for {
signal <- fs2.Stream.eval(SignallingRef[F, Boolean](false))
exitCode <- fs2.Stream.eval(Ref[F].of(ExitCode.Success))
_ <- fs2.Stream.eval(shutdown(signal))
server <- BlazeServerBuilder[F]
.bindHttp(8080, "0.0.0.0")
.withHttpApp(httpApp)
.serveWhile(signal, exitCode)
} yield server
def shutdown[F[_]: Effect](interrupter: SignallingRef[F, Boolean]): F[Unit] = {
LiftIO[F].liftIO(IO {
sys.addShutdownHook {
...
interrupter.set(true)
}
})
}
object Server extends IOApp {
def run(args: List[String]): IO[ExitCode] =
serverStream[IO].compile.drain.as(ExitCode.Success)
}
但是 http 服务器没有像我预期的那样工作,似乎 http4s 的内部ServerChannel
有自己的 shutdownHook 并且已经取消了所有响应。
任何建议/解决方法? 或者也许只是一种在x
秒内保持并且不终止请求的方法也很受欢迎。
为方便起见,服务器被 SIGTERM 挂钩。
为方便起见,cats-effect 提供了一个带有抽象 run 方法的 cat.effect.IOApp trait,该方法返回一个 IO[ExitCode]。 IOApp 运行该进程并添加 JVM 关闭挂钩以中断无限进程并在收到 SIGTERM 时正常关闭服务器。
如果您想使用 URL 关闭,例如http://localhost:8080/ops/shutdown/true
,它也可以工作。
代码很简单,
class SysOpsEndpoints[F[_]: Sync](signal: SignallingRef[F, Boolean]) extends Http4sDsl[F] {
private def shutdown: HttpRoutes[F] =
HttpRoutes.of[F] {
case GET -> Root / "shutdown" / shutdown =>
for {
_ <- signal.set(Try(shutdown.toBoolean).getOrElse(false))
result <- Ok(s"Shutdown: $shutdown")
} yield result
}
}
object SysOpsEndpoints {
def endpoints[F[_]: Sync](signal: SignallingRef[F, Boolean]): HttpRoutes[F] =
new SysOpsEndpoints(signal).shutdown
}
并且服务器的设置与您的相似,
for {
signal <- fs2.Stream.eval(SignallingRef[F, Boolean](false))
exitCode <- fs2.Stream.eval(Ref[F].of(ExitCode.Success))
httpApp = Router(
"/ops" -> SysOpsEndpoints.endpoints(signal)
).orNotFound
server <- BlazeServerBuilder[F](serverEc)
.bindHttp(8080, "0.0.0.0")
.withHttpApp(httpApp)
.serveWhile(signal, exitCode)
} yield server
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.