mirror of
https://gitee.com/johng/gf
synced 2026-06-07 10:22:11 +08:00
ghttp.Server热重启机制在windows系统下的稳定性测试
This commit is contained in:
@ -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())
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
@ -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 : ]
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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))...)
|
||||
|
||||
@ -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)
|
||||
|
||||
Reference in New Issue
Block a user