golang平滑重启(优雅重启)方案
作者:xiaobing
时间:2025-12-15
背景
在使用goframe框架时,goframe配置graceful: true gracefulTimeout: 10 开启平滑重启goframe在重启的过程中主进程会fock出一个子进程,主进程在gracefulTimeout的时间后退出。在子进程被fock出,主进程未退出的这段时间内,主进程和子进程都在接收请求。主进程退出后,主进程正在执行的请求会中断。
解决方案
使用openresty的来做web服务器解决golang的平滑重启,OpenResty是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。
安装openresty
openresty官网 ,在官网中下载系统合适的安装包进行安装。具体安装过程官网中有详细的说明,这里就不在重复说明
使用systemd守护goframe的进程
goframe配置文件增加在address后追进address1的配置
address: ":8203"
address1: ":8204"在internal/cmd/cmd.go 文件中在s.Run()之前增加如下代码
param := gcmd.GetOpt("address")
address, _ := g.Cfg().Get(ctx, "server.address")
if param.String() != "" {
address, _ = g.Cfg().Get(ctx, "server.address"+param.String())
}
systemd配置,启动监听端口号为8203和8204的两个进程
[Unit]
Description= api address
[Service]
Type=simple
KillMode=control-group #杀掉当前进程中所有的进程
ExecStart=/home/www/api/api #启动端口号为8203的进程
Restart=on-failure #只在服务非正常退出时重启
[Install]
WantedBy=multi-user.target
[Unit]
Description= api address 1
[Service]
Type=simple
KillMode=control-group #杀掉当前进程中所有的进程
ExecStart=/home/www/api/api -address=1 #启动端口号为8204的进程
Restart=on-failure #只在服务非正常退出时重启
[Install]
WantedBy=multi-user.target
重启服务
systemcel restart server.service #重启进程
systemcel stop server.service #进程进程
systemcel start server.service #停止进程配置openresty的nginx配置
cd /usr/local/openresty/nginx/configupstream api_backend {
server 127.0.0.1:8203;
}
server {
listen 80;
server_name xxx.com;
location /{
# 动态设置当前 upstream, 未设置则使用默认 upstream
set_by_lua_block $cur_ups {
local ups = ngx.shared.upstream:get("api_backend_server")
if ups ~= nil then
return ups
end
return "api_backend";
}
proxy_pass http://$cur_ups;
}
}
server {
listen 81;
server_name localhost;
#设置api的反向代理的端口地址
location /update_upstream {
content_by_lua_block {
local new_server = ngx.var.arg_server
ngx.say("param server: ", new_server)
if new_server then
local upstream = ngx.shared.upstream
ngx.say("old server: ", upstream:get("api_backend_server"))
upstream:set("api_backend_server", new_server)
ngx.say("new server: ", upstream:get("api_backend_server"))
else
ngx.say("No new server specified")
end
}
}
#获取api的反向代理的端口地址
location /get_upstream {
content_by_lua_block {
local upstream = ngx.shared.upstream
local server = upstream:get("api_backend_server")
if server ~= nil then
ngx.say(server)
else
ngx.say("127.0.0.1:8800")
end
}
}
}
通过get请求来动态修改需要监听的端口地址
curl http://127.0.0.1:81/update_upstreamu?server=127.0.0.1:8204获取当前反向代理的端口号地址
curl http://127.0.0.1:81/get_upstreamu后台管理
在后台管理中做一个服务管理的列表,列表实现启动、停止、重启、修改服务地址功能
通过get_upstreamu判断当前nginx使用反向代理的服务,将在反向代理的服务重启后切换到重启的服务
以此操作来达到golang的平滑重启流程图
很赞哦! (9)
本站所有文章、数据、图片均来自作者原创,一切版权均归网站作者所有。
如果转载请标明出处。如有侵权请联系。邮箱:bing0810@126.com
上一篇:
下一篇: 基于M3u8的视频加密及播放


