Allenxuxu / gev

🚀Gev is a lightweight, fast non-blocking TCP network library / websocket server based on Reactor mode. Support custom protocols to quickly and easily build high-performance servers.
MIT License
1.73k stars 194 forks source link

如何支持 Graceful Restart #104

Closed xuxiangyang closed 3 years ago

xuxiangyang commented 3 years ago

类似于这种逻辑 https://github.com/gobwas/graceful

Allenxuxu commented 3 years ago

目前没有相关的支持,简单看了下你发的链接,这里目的是想实现让客户端感知不到 tcp 链接断开了?

xuxiangyang commented 3 years ago

不是的,是为了解决部署时的重启问题。类似于 https://studygolang.com/articles/19990 里说的 FD继承模式。facebook以前也有个类似的 https://github.com/facebookarchive/grace ,关键是重启,不只是ShutDown

Allenxuxu commented 3 years ago

不是的,是为了解决部署时的重启问题。类似于 https://studygolang.com/articles/19990 里说的 FD继承模式。facebook以前也有个类似的 https://github.com/facebookarchive/grace ,关键是重启,不只是ShutDown

是重启的时候,客户端感知不到服务重启,即连接不会断开的意思吗

xuxiangyang commented 3 years ago

对,就是在重启时已有链接由老进程保持,通过FD继承新的进程监听同样地接口接收新链接,老进程等已有链接全部断开或超时后再退出

Allenxuxu commented 3 years ago

如果客户端一直不退出,这里老进程不是会一直不退出?

xuxiangyang commented 3 years ago

老进程会等待比如1、2个小时(具体值应该由业务侧决定)如果链接还没有短会直接退出

Allenxuxu commented 3 years ago

老进程会等待比如1、2个小时(具体值应该由业务侧决定)如果链接还没有短会直接退出

这种策略看起来不是很实用,因为现在大多数容器化了,如果进程一直不退出,会强杀它的,不然可能会影响集群调度

xuxiangyang commented 3 years ago

容器化的也是要依赖一个负载均衡吧,这里我有点不是特别熟悉。不过,这类的核心做法应该都是把一个节点从负载均衡中设置不再接受新的请求,等待老请求全部处理完成后进程退出,然后启动新的进程,开始接受新的请求,这样一个过程吧?如果是这样的,问题就是对于节点不是特别多的情况,让一个停止处理新的请求,可能导致其他节点压力过重。更灵活的可能是类似的graceful方案。

类似的需求gin 也可以通过使用 fvbock/endless 当作middleware来实现的 https://gin-gonic.com/docs/examples/graceful-restart-or-stop/。当然这个是应用层http协议,但因为是重写了传输层的业务,这类插件就没法用了。类似的比如 websocket 或 http等plugins是不是能提供些思路或案例来实现呢?

个人觉得对于websocket或者http这种应用层协议,类似的需求应该是挺普遍的。如果应用层协议可以做的更完善,也应该有助于传输层协议的推广?不过这个可能确实不属于传输层协议的职责

Allenxuxu commented 3 years ago

容器化的也是要依赖一个负载均衡吧,这里我有点不是特别熟悉。不过,这类的核心做法应该都是把一个节点从负载均衡中设置不再接受新的请求,等待老请求全部处理完成后进程退出,然后启动新的进程,开始接受新的请求,这样一个过程吧?如果是这样的,问题就是对于节点不是特别多的情况,让一个停止处理新的请求,可能导致其他节点压力过重。更灵活的可能是类似的graceful方案。

类似的需求gin 也可以通过使用 fvbock/endless 当作middleware来实现的 https://gin-gonic.com/docs/examples/graceful-restart-or-stop/。当然这个是应用层http协议,但因为是重写了传输层的业务,这类插件就没法用了。类似的比如 websocket 或 http等plugins是不是能提供些思路或案例来实现呢?

个人觉得对于websocket或者http这种应用层协议,类似的需求应该是挺普遍的。如果应用层协议可以做的更完善,也应该有助于传输层协议的推广?不过这个可能确实不属于传输层协议的职责

一般来说,都是新起新的pod/进程,然后杀老的进程。 至于 graceful stop 确实是需要的,一般是停止新的请求,并通知客户端退出(处理完当前请求),库能到做到的也只有这个了,至于能允许老进程处理多久再退出,一般由运维平台觉得把,太慢了,会导致有很多残余进程把,需要强杀他们。

这里我理解需要业务自己来实现这个逻辑?gev 内部提供了 ShutdownWrite 方法

xuxiangyang commented 3 years ago

那我先看看怎么能实现吧