mirror of
https://gitee.com/johng/gf
synced 2026-06-07 10:22:11 +08:00
改进ghttp.Server平滑重启进程间通信机制
This commit is contained in:
@ -25,6 +25,8 @@ import (
|
||||
"gitee.com/johng/gf/g/os/gfile"
|
||||
"gitee.com/johng/gf/g/os/genv"
|
||||
"github.com/gorilla/websocket"
|
||||
"gitee.com/johng/gf/g/os/gtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -127,6 +129,8 @@ func init() {
|
||||
|
||||
// 信号量管理操作监听
|
||||
go handleProcessSignal()
|
||||
// 异步监听进程间消息
|
||||
go handleProcessMessage()
|
||||
}
|
||||
|
||||
// 获取/创建一个默认配置的HTTP Server(默认监听端口是80)
|
||||
@ -213,6 +217,13 @@ func (s *Server) Start() error {
|
||||
s.startServer(nil)
|
||||
}
|
||||
|
||||
// 如果是子进程,那么服务开启后通知父进程销毁
|
||||
if gproc.IsChild() {
|
||||
gtime.SetTimeout(2*time.Second, func() {
|
||||
gproc.Send(gproc.PPid(), []byte("exit"))
|
||||
})
|
||||
}
|
||||
|
||||
// 开启异步关闭队列处理循环
|
||||
s.startCloseQueueLoop()
|
||||
return nil
|
||||
|
||||
@ -22,14 +22,15 @@ import (
|
||||
"gitee.com/johng/gf/g/util/gconv"
|
||||
"time"
|
||||
"runtime"
|
||||
"bytes"
|
||||
)
|
||||
|
||||
const (
|
||||
gADMIN_ACTION_INTERVAL_LIMIT = 2000 // (毫秒)服务开启后允许执行管理操作的间隔限制
|
||||
gADMIN_ACTION_RESTARTING = 1
|
||||
gADMIN_ACTION_SHUTINGDOWN = 2
|
||||
gADMIN_ACTION_RELOAD_ENVKEY = "gf.server.reload"
|
||||
gADMIN_ACTION_RESTART_ENVKEY = "gf.server.restart"
|
||||
gADMIN_ACTION_RELOAD_ENVKEY = "GF_SERVER_RELOAD"
|
||||
gADMIN_ACTION_RESTART_ENVKEY = "GF_SERVER_RESTART"
|
||||
)
|
||||
|
||||
// 用于服务管理的对象
|
||||
@ -240,11 +241,6 @@ func restartWebServers(newExeFilePath...string) {
|
||||
})
|
||||
} else {
|
||||
forkReloadProcess(newExeFilePath...)
|
||||
// 异步2秒后再执行关闭,目的是让新进程将服务成功接管后,再关闭自身进程(后续可以根据进程间通信来改进)
|
||||
gtime.SetTimeout(2*time.Second, func() {
|
||||
go gracefulShutdownWebServers()
|
||||
doneChan <- struct{}{}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -281,4 +277,17 @@ func forcedlyCloseWebServers() {
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 异步监听进程间消息
|
||||
func handleProcessMessage() {
|
||||
for {
|
||||
if msg := gproc.Receive(); msg != nil {
|
||||
if bytes.EqualFold(msg.Data, []byte("exit")) {
|
||||
gracefulShutdownWebServers()
|
||||
doneChan <- struct{}{}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -37,7 +37,8 @@ type sendQueueItem struct {
|
||||
|
||||
// 进程管理/通信初始化操作
|
||||
func init() {
|
||||
if os.Getenv(gPROC_ENV_KEY_COMM_KEY) == "1" {
|
||||
// 默认下为空("")
|
||||
if os.Getenv(gPROC_ENV_KEY_COMM_KEY) != "0" {
|
||||
go startTcpListening()
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ type Process struct {
|
||||
exec.Cmd
|
||||
Manager *Manager // 所属进程管理器
|
||||
PPid int // 自定义关联的父进程ID
|
||||
CommEnabled bool // 是否开启TCP通信监听服务
|
||||
DisableComm bool // 是否关闭TCP通信监听服务
|
||||
}
|
||||
|
||||
// 创建一个进程(不执行)
|
||||
@ -32,7 +32,6 @@ func NewProcess(path string, args []string, environment []string) *Process {
|
||||
p := &Process {
|
||||
Manager : nil,
|
||||
PPid : os.Getpid(),
|
||||
CommEnabled : true,
|
||||
Cmd : exec.Cmd {
|
||||
Args : []string{path},
|
||||
Path : path,
|
||||
@ -62,9 +61,9 @@ func (p *Process) Start() (int, error) {
|
||||
if p.Process != nil {
|
||||
return p.Pid(), nil
|
||||
}
|
||||
commEnabled := 0
|
||||
if p.CommEnabled {
|
||||
commEnabled = 1
|
||||
commEnabled := 1
|
||||
if p.DisableComm {
|
||||
commEnabled = 0
|
||||
}
|
||||
p.Env = append(p.Env, fmt.Sprintf("%s=%d", gPROC_ENV_KEY_PPID_KEY, p.PPid))
|
||||
p.Env = append(p.Env, fmt.Sprintf("%s=%d", gPROC_ENV_KEY_COMM_KEY, commEnabled))
|
||||
|
||||
Reference in New Issue
Block a user