广告
  • 微信号:shenxiaobin0810

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/config
upstream 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的平滑重启

流程图

基于openresty配置的golang平滑重启1.jpg

很赞哦! (9)

本站所有文章、数据、图片均来自作者原创,一切版权均归网站作者所有。

如果转载请标明出处。如有侵权请联系。邮箱:bing0810@126.com

标签: NGINX  GOLANG 

上一篇:

下一篇: 基于M3u8的视频加密及播放

微信

沈雁斌

只要你奔跑,这个世界就会跟着你奔跑,只要你停驻,这个世界就会舍弃你独自奔跑。唯有你确定一个方向,使劲的跑起来,这个世界会为你而让路。

微信

猜你喜欢