salvo-rs/salvo

平滑重启的最佳实践是什么?

Opened this issue · 1 comments

我看example的listenfd应该指的是平滑监听吧?理论上平滑重启的最佳实践是怎样的?
就比如用salvo实现网关,这种场景对平滑监听的要求高点。

关于平滑重启,我个人设想的流程是:

  • 新程序启动,初始化完成后发信号给旧程序
  • 旧程序停止accept进入优雅停机流程,并发送信号给新程序
  • 新程序通过旧程序共享的fd信息启动tcp监听
  • 旧程序优雅停机结束后自动关闭进程

listenfd是通过环境变量共享fd信息的,但新旧程序传递信号用什么方式(tcp?unix?namedpipe?signals?http?)比较合适?如果双方有别的通信渠道,似乎好像就没必要用listenfd共享fd信息了?

感觉最省事的就是路由里搞一个优雅关闭api,新程序发送一个http请求给旧程序,旧程序启动优雅关闭后响应fd信息给新程序(也可以把需要共享的其他数据(本地缓存之类的)一起发了),然后新程序通过fd启动服务。

你的 graceful restart 的需求应该是要自己重写 server 的,官方只有 graceful stop 的实现。

tokio 感觉你也没怎么了解。

如果本地监听的地址有变化,则启动新 server 后 signal 通知旧的 async accept loop 使其退出循环即可,这种情况最简单;但是如果本地监听的地址没变化就不行了,得等旧 server 完成优雅停机,TcpListener 被 drop 掉、释放本地端口后才能启动新 server。

不过看了眼 salvo 的源代码,要实现平滑重启感觉蛮麻烦的。

建议你先行学习 async Rust 相关知识,了解 tokio 并阅读 salvo 的源代码。