From 5bbf4117412b1d7fca48e5901d4d782641c8a517 Mon Sep 17 00:00:00 2001 From: John Date: Wed, 16 May 2018 21:27:27 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90ghttp.Server=E7=83=AD?= =?UTF-8?q?=E9=87=8D=E5=90=AF=E7=89=B9=E6=80=A7=E7=9A=84HTTP&HTTPS?= =?UTF-8?q?=E5=9C=A8Linux=E4=B8=8B=E7=9A=84=E5=8A=9F=E8=83=BD=E5=8F=8A?= =?UTF-8?q?=E7=A8=B3=E5=AE=9A=E6=80=A7=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/net/ghttp/ghttp_server.go | 7 +++- g/net/ghttp/ghttp_server_comm_main.go | 3 +- g/net/ghttp/ghttp_server_comm_signal_unix.go | 3 ++ g/net/ghttp/ghttp_server_graceful.go | 40 ++++++++----------- g/os/gproc/gproc.go | 7 +++- geg/net/ghttp/https/https_http.go | 5 ++- .../ghttp/{hot_restart => reload}/admin.go | 0 geg/net/ghttp/reload/https_http.go | 18 +++++++++ .../{hot_restart => reload}/multi_port.go | 0 .../multi_port_and_server.go | 0 .../ghttp/{hot_restart => reload}/simple.go | 0 11 files changed, 53 insertions(+), 30 deletions(-) rename geg/net/ghttp/{hot_restart => reload}/admin.go (100%) create mode 100644 geg/net/ghttp/reload/https_http.go rename geg/net/ghttp/{hot_restart => reload}/multi_port.go (100%) rename geg/net/ghttp/{hot_restart => reload}/multi_port_and_server.go (100%) rename geg/net/ghttp/{hot_restart => reload}/simple.go (100%) diff --git a/g/net/ghttp/ghttp_server.go b/g/net/ghttp/ghttp_server.go index 13ade8479..773155342 100644 --- a/g/net/ghttp/ghttp_server.go +++ b/g/net/ghttp/ghttp_server.go @@ -127,7 +127,11 @@ func init() { doneChan <- struct{}{} if !gproc.IsChild() { - glog.Printfln("%d: all web server shutdown smoothly", gproc.Pid()) + if serverMapping.Size() > 1 { + glog.Printfln("%d: all web servers shutdown", gproc.Pid()) + } else { + glog.Printfln("%d: web server shutdown", gproc.Pid()) + } } }() } @@ -262,6 +266,7 @@ func (s *Server) startServer(fdMap listenerFdMap) { } else { s.servers = append(s.servers, s.newGracefulServer(addr)) } + s.servers[len(s.servers) - 1].isHttps = true } } // ================ diff --git a/g/net/ghttp/ghttp_server_comm_main.go b/g/net/ghttp/ghttp_server_comm_main.go index 5666fbfbf..04fa6a8ed 100644 --- a/g/net/ghttp/ghttp_server_comm_main.go +++ b/g/net/ghttp/ghttp_server_comm_main.go @@ -59,6 +59,7 @@ func onCommMainNewFork(pid int, data []byte) { // 关闭服务,通知所有子进程退出(Kill强制性退出) func onCommMainShutdown(pid int, data []byte) { + procManager.Send(formatMsgBuffer(gMSG_CLOSE, nil)) procManager.KillAll() procManager.WaitAll() } @@ -83,7 +84,7 @@ func handleMainProcessHeartbeat() { } } } - // 如果所有子进程都退出,并且主进程未活动达到超时时间,那么主进程也没存在的必要 + // (双保险)如果所有子进程都退出,并且主进程未活动达到超时时间,那么主进程也没存在的必要 if procManager.Size() == 0 && int(gtime.Millisecond()) - lastUpdateTime.Val() > gPROC_HEARTBEAT_TIMEOUT{ os.Exit(0) } diff --git a/g/net/ghttp/ghttp_server_comm_signal_unix.go b/g/net/ghttp/ghttp_server_comm_signal_unix.go index 760212c07..0c8316419 100644 --- a/g/net/ghttp/ghttp_server_comm_signal_unix.go +++ b/g/net/ghttp/ghttp_server_comm_signal_unix.go @@ -34,6 +34,9 @@ func handleProcessSignal() { // 进程终止,停止所有子进程运行 case syscall.SIGINT, syscall.SIGQUIT, syscall.SIGKILL, syscall.SIGHUP, syscall.SIGTERM: sendProcessMsg(gproc.Pid(), gMSG_SHUTDOWN, nil) + if gproc.IsChild() { + sendProcessMsg(gproc.PPid(), gMSG_SHUTDOWN, nil) + } return // 用户信号,热重启服务 diff --git a/g/net/ghttp/ghttp_server_graceful.go b/g/net/ghttp/ghttp_server_graceful.go index 8d93af987..13a17bdf2 100644 --- a/g/net/ghttp/ghttp_server_graceful.go +++ b/g/net/ghttp/ghttp_server_graceful.go @@ -7,19 +7,14 @@ package ghttp import ( + "os" "fmt" "net" - "os" "context" "net/http" "crypto/tls" "gitee.com/johng/gf/g/os/glog" "gitee.com/johng/gf/g/os/gproc" - "time" -) - -const ( - gGRACEFUL_SHUTDOWN_TIMEOUT = 10*time.Second // 优雅关闭链接时的超时时间 ) // 优雅的Web Server对象封装 @@ -27,8 +22,8 @@ type gracefulServer struct { fd uintptr addr string httpServer *http.Server - rawln *net.TCPListener // 原始listener - listener net.Listener // 接口化封装的listener + rawListener net.Listener // 原始listener + listener net.Listener // 接口化封装的listener isHttps bool shutdownChan chan bool } @@ -40,6 +35,7 @@ func (s *Server) newGracefulServer(addr string, fd...int) *gracefulServer { httpServer : s.newHttpServer(addr), shutdownChan : make(chan bool), } + // 是否有继承的文件描述符 if len(fd) > 0 && fd[0] > 0 { gs.fd = uintptr(fd[0]) } @@ -65,19 +61,15 @@ func (s *gracefulServer) ListenAndServe() error { if err != nil { return err } - //file, err := ln.(*net.TCPListener).File() - //if err != nil { - // return err - //} - //s.fd = file.Fd() - s.listener = ln + s.listener = ln + s.rawListener = ln return s.doServe() } // 获得文件描述符 func (s *gracefulServer) Fd() uintptr { - if s.listener != nil { - file, err := s.listener.(*net.TCPListener).File() + if s.rawListener != nil { + file, err := s.rawListener.(*net.TCPListener).File() if err == nil { return file.Fd() } @@ -110,13 +102,9 @@ func (s *gracefulServer) ListenAndServeTLS(certFile, keyFile string) error { if err != nil { return err } - //file, err := ln.(*net.TCPListener).File() - //if err != nil { - // return err - //} - //s.fd = file.Fd() - s.listener = tls.NewListener(ln, config) - s.isHttps = true + + s.listener = tls.NewListener(ln, config) + s.rawListener = ln return s.doServe() } @@ -131,7 +119,11 @@ func (s *gracefulServer) getProto() string { // 开始执行Web Server服务处理 func (s *gracefulServer) doServe() error { - glog.Printfln("%d: %s server started listening on [%s]", gproc.Pid(), s.getProto(), s.addr) + action := "started" + if s.fd != 0 { + action = "reloaded" + } + glog.Printfln("%d: %s server %s listening on [%s]", gproc.Pid(), s.getProto(), action, s.addr) err := s.httpServer.Serve(s.listener) <-s.shutdownChan return err diff --git a/g/os/gproc/gproc.go b/g/os/gproc/gproc.go index 3b6deaa9b..8c435a8af 100644 --- a/g/os/gproc/gproc.go +++ b/g/os/gproc/gproc.go @@ -31,14 +31,17 @@ func Pid() int { return os.Getpid() } -// 获取父进程ID(gproc父进程,不存在时则使用系统父进程) +// 获取父进程ID(gproc父进程,如果当前进程本身就是父进程,那么返回自身的pid,不存在时则使用系统父进程) func PPid() int { + if !IsChild() { + return Pid() + } // gPROC_ENV_KEY_PPID_KEY为gproc包自定义的父进程 ppidValue := os.Getenv(gPROC_ENV_KEY_PPID_KEY) if ppidValue != "" { return gconv.Int(ppidValue) } - return os.Getppid() + return PPidOS() } // 获取父进程ID(系统父进程) diff --git a/geg/net/ghttp/https/https_http.go b/geg/net/ghttp/https/https_http.go index 4440453d0..3a42b01a7 100644 --- a/geg/net/ghttp/https/https_http.go +++ b/geg/net/ghttp/https/https_http.go @@ -11,7 +11,8 @@ func main() { r.Response.Writeln("您可以同时通过HTTP和HTTPS方式看到该内容!") }) s.EnableHTTPS("/home/john/temp/server.crt", "/home/john/temp/server.key") - s.SetHTTPSPort(8198) - s.SetPort(8199) + s.SetHTTPSPort(8198, 8199) + s.SetPort(8200, 8300) + s.EnableAdmin() s.Run() } \ No newline at end of file diff --git a/geg/net/ghttp/hot_restart/admin.go b/geg/net/ghttp/reload/admin.go similarity index 100% rename from geg/net/ghttp/hot_restart/admin.go rename to geg/net/ghttp/reload/admin.go diff --git a/geg/net/ghttp/reload/https_http.go b/geg/net/ghttp/reload/https_http.go new file mode 100644 index 000000000..3a42b01a7 --- /dev/null +++ b/geg/net/ghttp/reload/https_http.go @@ -0,0 +1,18 @@ +package main + +import ( + "gitee.com/johng/gf/g/net/ghttp" +) + +func main() { + s := ghttp.GetServer() + s.EnableAdmin() + s.BindHandler("/", func(r *ghttp.Request){ + r.Response.Writeln("您可以同时通过HTTP和HTTPS方式看到该内容!") + }) + s.EnableHTTPS("/home/john/temp/server.crt", "/home/john/temp/server.key") + s.SetHTTPSPort(8198, 8199) + s.SetPort(8200, 8300) + s.EnableAdmin() + s.Run() +} \ No newline at end of file diff --git a/geg/net/ghttp/hot_restart/multi_port.go b/geg/net/ghttp/reload/multi_port.go similarity index 100% rename from geg/net/ghttp/hot_restart/multi_port.go rename to geg/net/ghttp/reload/multi_port.go diff --git a/geg/net/ghttp/hot_restart/multi_port_and_server.go b/geg/net/ghttp/reload/multi_port_and_server.go similarity index 100% rename from geg/net/ghttp/hot_restart/multi_port_and_server.go rename to geg/net/ghttp/reload/multi_port_and_server.go diff --git a/geg/net/ghttp/hot_restart/simple.go b/geg/net/ghttp/reload/simple.go similarity index 100% rename from geg/net/ghttp/hot_restart/simple.go rename to geg/net/ghttp/reload/simple.go