完成ghttp.Server热重启机制在Windows下的测试

This commit is contained in:
John
2018-05-16 22:32:56 +08:00
parent 7ecf111c5e
commit 730664ee11
4 changed files with 77 additions and 23 deletions

View File

@ -321,21 +321,6 @@ func (s *Server) startServer(fdMap listenerFdMap) {
s.status = 1
}
// 平滑重启Web Server
func (s *Server) Reload() {
sendProcessMsg(gproc.Pid(), gMSG_RELOAD, nil)
}
// 完整重启Web Server
func (s *Server) Restart() {
sendProcessMsg(gproc.Pid(), gMSG_RESTART, nil)
}
// 关闭Web Server
func (s *Server) Shutdown() {
sendProcessMsg(gproc.PPid(), gMSG_SHUTDOWN, nil)
}
// 获取当前监听的文件描述符信息构造成map返回
func (s *Server) getListenerFdMap() map[string]string {
m := map[string]string {

View File

@ -11,11 +11,27 @@ import (
"strings"
"gitee.com/johng/gf/g/os/gview"
"runtime"
"gitee.com/johng/gf/g/os/gproc"
"sync"
"gitee.com/johng/gf/g/os/gtime"
"errors"
"fmt"
"gitee.com/johng/gf/g/container/gtype"
)
const (
gADMIN_ACTION_INTERVAL_LIMIT = 0 // (毫秒)每一次执行管理操作的间隔限制
)
// 用于服务管理的对象
type utilAdmin struct {}
// (进程级别)用于Web Server管理操作的互斥锁保证管理操作的原子性
var serverActionLocker sync.Mutex
// (进程级别)用于记录上一次操作的时间(毫秒)
var serverActionLastTime = gtype.NewInt64(gtime.Millisecond())
// 服务管理首页
func (p *utilAdmin) Index(r *Request) {
data := map[string]interface{}{
@ -41,21 +57,31 @@ func (p *utilAdmin) Reload(r *Request) {
if runtime.GOOS == "windows" {
p.Restart(r)
} else {
r.Response.Write("reload server")
r.Server.Reload()
if err := r.Server.Reload(); err == nil {
r.Response.Write("server reloaded")
} else {
r.Response.Write(err.Error())
}
}
}
// 服务完整重启
func (p *utilAdmin) Restart(r *Request) {
r.Response.Write("restart server")
r.Server.Restart()
if err := r.Server.Restart(); err == nil {
r.Response.Write("server restarted")
} else {
r.Response.Write(err.Error())
}
}
// 服务关闭
func (p *utilAdmin) Shutdown(r *Request) {
r.Response.Write("shutdown server")
r.Server.Shutdown()
if err := r.Server.Shutdown(); err == nil {
r.Response.Write("server shutdown")
} else {
r.Response.Write(err.Error())
}
}
@ -66,4 +92,47 @@ func (s *Server) EnableAdmin(pattern...string) {
p = pattern[0]
}
s.BindObject(p, &utilAdmin{})
}
// 平滑重启Web Server
func (s *Server) Reload() error {
serverActionLocker.Lock()
defer serverActionLocker.Unlock()
if err := s.checkActionFrequence(); err != nil {
return err
}
sendProcessMsg(gproc.Pid(), gMSG_RELOAD, nil)
return nil
}
// 完整重启Web Server
func (s *Server) Restart() error {
serverActionLocker.Lock()
defer serverActionLocker.Unlock()
if err := s.checkActionFrequence(); err != nil {
return err
}
sendProcessMsg(gproc.Pid(), gMSG_RESTART, nil)
return nil
}
// 关闭Web Server
func (s *Server) Shutdown() error {
serverActionLocker.Lock()
defer serverActionLocker.Unlock()
if err := s.checkActionFrequence(); err != nil {
return err
}
sendProcessMsg(gproc.PPid(), gMSG_SHUTDOWN, nil)
return nil
}
// 检测当前操作的频繁度
func (s *Server) checkActionFrequence() error {
interval := gtime.Millisecond() - serverActionLastTime.Val()
if interval < gADMIN_ACTION_INTERVAL_LIMIT {
return errors.New(fmt.Sprintf("too frequent action, please retry in %d ms", gADMIN_ACTION_INTERVAL_LIMIT - interval))
}
serverActionLastTime.Set(gtime.Millisecond())
return nil
}

View File

@ -24,7 +24,7 @@ const (
gPROC_CHILD_MAX_IDLE_TIME = 3000 // 子进程闲置时间(未开启心跳机制的时间)
)
// 心跳消息
// 心跳处理(方法为空逻辑放到公共通信switch中进行处理)
func onCommChildHeartbeat(pid int, data []byte) {
}

View File

@ -26,9 +26,9 @@ func onCommMainStart(pid int, data []byte) {
sendProcessMsg(p.Pid(), gMSG_START, nil)
}
// 心跳处理
// 心跳处理(方法为空逻辑放到公共通信switch中进行处理)
func onCommMainHeartbeat(pid int, data []byte) {
updateProcessCommTime(pid)
}
// 平滑重启服务