ghttp.Server热重启机制在windows系统下的稳定性测试

This commit is contained in:
John
2018-05-16 23:42:02 +08:00
parent 5856605fc3
commit cc70bbf6a2
6 changed files with 22 additions and 21 deletions

View File

@ -127,11 +127,7 @@ func init() {
doneChan <- struct{}{}
if !gproc.IsChild() {
if serverMapping.Size() > 1 {
glog.Printfln("%d: all web servers shutdown", gproc.Pid())
} else {
glog.Printfln("%d: web server shutdown", gproc.Pid())
}
glog.Printfln("%d: all web servers shutdown", gproc.Pid())
}
}()
}

View File

@ -17,6 +17,7 @@ import (
"errors"
"fmt"
"gitee.com/johng/gf/g/container/gtype"
"gitee.com/johng/gf/g/os/glog"
)
const (
@ -101,6 +102,7 @@ func (s *Server) Reload() error {
if err := s.checkActionFrequence(); err != nil {
return err
}
glog.Printfln("%d: server reloading", gproc.Pid())
sendProcessMsg(gproc.Pid(), gMSG_RELOAD, nil)
return nil
}
@ -112,6 +114,7 @@ func (s *Server) Restart() error {
if err := s.checkActionFrequence(); err != nil {
return err
}
glog.Printfln("%d: server restarting", gproc.Pid())
sendProcessMsg(gproc.Pid(), gMSG_RESTART, nil)
return nil
}
@ -123,6 +126,7 @@ func (s *Server) Shutdown() error {
if err := s.checkActionFrequence(); err != nil {
return err
}
glog.Printfln("%d: server shutting down", gproc.Pid())
sendProcessMsg(gproc.PPid(), gMSG_SHUTDOWN, nil)
return nil
}

View File

@ -15,6 +15,7 @@ import (
"gitee.com/johng/gf/g/container/gtype"
"gitee.com/johng/gf/g/encoding/gbinary"
"gitee.com/johng/gf/g/os/gtime"
"fmt"
)
const (
@ -34,7 +35,7 @@ const (
var procSignalChan = make(chan os.Signal)
// 上一次进程间心跳的时间戳
var lastUpdateTime = gtype.NewInt()
var lastUpdateTime = gtype.NewInt(int(gtime.Millisecond()))
// (主子进程)在第一次创建子进程成功之后才会开始心跳检测,同理对应超时时间才会生效
var checkHeartbeat = gtype.NewBool()
@ -56,8 +57,8 @@ func handleProcessMsg() {
for {
if msg := gproc.Receive(); msg != nil {
// 记录消息日志,用于调试
//content := gconv.String(msg.Pid) + "=>" + gconv.String(gproc.Pid()) + ":" + fmt.Sprintf("%v\n", msg.Data)
//fmt.Print(content)
content := gconv.String(msg.Pid) + "=>" + gconv.String(gproc.Pid()) + ":" + fmt.Sprintf("%v\n", msg.Data)
fmt.Print(content)
//gfile.PutContentsAppend("/tmp/gproc-log", content)
act := gbinary.DecodeToUint(msg.Data[0 : 1])
data := msg.Data[1 : ]

View File

@ -14,6 +14,8 @@ import (
"gitee.com/johng/gf/g/os/gtime"
"gitee.com/johng/gf/g/container/gmap"
"gitee.com/johng/gf/g/os/gproc"
"fmt"
"gitee.com/johng/gf/g/os/glog"
)
// (主进程)主进程与子进程上一次活跃时间映射map
@ -22,7 +24,11 @@ var procUpdateTimeMap = gmap.NewIntIntMap()
// 开启服务
func onCommMainStart(pid int, data []byte) {
p := procManager.NewProcess(os.Args[0], os.Args, os.Environ())
p.Start()
if _, err := p.Start(); err != nil {
glog.Errorfln("%d: fork new process error:%s", gproc.Pid(), err.Error())
return
}
updateProcessCommTime(p.Pid())
sendProcessMsg(p.Pid(), gMSG_START, nil)
}
@ -38,7 +44,7 @@ func onCommMainReload(pid int, data []byte) {
// 完整重启服务
func onCommMainRestart(pid int, data []byte) {
// 如果是父进程接收到重启指令,那么通知所有子进程重启
// 如果是父进程自身发送的重启指令,那么通知所有子进程重启
if pid == gproc.Pid() {
procManager.Send(formatMsgBuffer(gMSG_RESTART, nil))
return
@ -77,7 +83,9 @@ func handleMainProcessHeartbeat() {
// 清理过期进程
if checkHeartbeat.Val() {
for _, pid := range procManager.Pids() {
if int(gtime.Millisecond()) - procUpdateTimeMap.Get(pid) > gPROC_HEARTBEAT_TIMEOUT {
updatetime := procUpdateTimeMap.Get(pid)
if updatetime > 0 && int(gtime.Millisecond()) - updatetime > gPROC_HEARTBEAT_TIMEOUT {
fmt.Println("remove pid", pid, int(gtime.Millisecond()), updatetime)
// 这里需要手动从进程管理器中去掉该进程
procManager.RemoveProcess(pid)
sendProcessMsg(pid, gMSG_CLOSE, nil)
@ -86,6 +94,7 @@ func handleMainProcessHeartbeat() {
}
// (双保险)如果所有子进程都退出,并且主进程未活动达到超时时间,那么主进程也没存在的必要
if procManager.Size() == 0 && int(gtime.Millisecond()) - lastUpdateTime.Val() > gPROC_HEARTBEAT_TIMEOUT{
//glog.Printfln("%d: all children died, exit", gproc.Pid())
os.Exit(0)
}
}

View File

@ -122,10 +122,6 @@ func Receive() *Msg {
// 向指定gproc进程发送数据
// 数据格式:总长度(32bit) | PID(32bit) | 校验(32bit) | 参数(变长)
func Send(pid int, data interface{}) error {
// 首先检测进程存在不存在,存在才能发送消息
if _, err := os.FindProcess(pid); err != nil {
return err
}
buffer := gconv.Bytes(data)
b := make([]byte, 0)
b = append(b, gbinary.EncodeInt32(int32(len(buffer) + 12))...)

View File

@ -6,8 +6,6 @@ import (
"gitee.com/johng/gf/g/os/gtime"
"gitee.com/johng/gf/g/encoding/gbinary"
"gitee.com/johng/gf/g/os/gproc"
"os"
"syscall"
)
// 数据解包,防止黏包
@ -45,10 +43,7 @@ func checksum(buffer []byte) uint32 {
}
func main(){
p, _ := os.FindProcess(10354)
fmt.Println(p.Signal(syscall.Signal(1)))
return
b := gfile.GetBinContents("/tmp/gproc/30588")
b := gfile.GetBinContents("/home/john/Documents/11248")
for _, msg := range bufferToMsgs(b) {
fmt.Println(msg.Pid)
fmt.Println(msg.Data)