改进ghttp.Server平滑重启进程间通信机制

This commit is contained in:
John
2018-06-29 17:26:34 +08:00
parent 6c1e0bfc51
commit 373264da3f
4 changed files with 33 additions and 13 deletions

View File

@ -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

View File

@ -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
}
}
}
}

View File

@ -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()
}
}

View File

@ -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))