架构是这样的:
nginx做反向代理,将http请求proxy pass到后端的golang http server
nginx==>httpserver
可否这样实现优雅重启
1.启动一个新的golang http server监听其他端口
2.修改nginx配置文件,将之前的代理端口改为新启动的server监听的端口
3.reload nginx
4.并行一段时间老的http server没有请求处理,则kill掉
整体实现优雅重启?这个是否可行,还有什么更好的方案?
架构是这样的:
nginx做反向代理,将http请求proxy pass到后端的golang http server
nginx==>httpserver
可否这样实现优雅重启
1.启动一个新的golang http server监听其他端口
2.修改nginx配置文件,将之前的代理端口改为新启动的server监听的端口
3.reload nginx
4.并行一段时间老的http server没有请求处理,则kill掉
整体实现优雅重启?这个是否可行,还有什么更好的方案?
15 回答8.4k 阅读
7 回答5.3k 阅读
6 回答6.9k 阅读✓ 已解决
8 回答6.2k 阅读
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
想到两个方法:
方法一:
如果是比较新的内核版本3.9以上,支持SO_REUSEPORT,那么你可以:
等所有已经存在的连接处理完自动退出。
如果不支持SO_REUSEPORT,不同进程无法同时监听同一个端口,则需要在老的进程内fork一个子进程,并且把负责监听的文件描述符传给新进程。
这个方法可以实现你的需求,但需要比较多的修改Golang封装的net/http等系统库,技术复杂度比较高。
好处是不需要nginx参与,对它透明。
方法二:
可以同时运行两个或更多个http server,同时提供服务,让nginx做负载均衡,其中有一个需要升级重启时,就发个信号,收到信号后停止接收新请求,已有请求处理完毕正常退出就可以了。这个过程不需要修改nginx配置,也不需要reload nginx。
这个方法也需要改Golang封装的net/http,但修改量相比方法一会小很多。