// Re-exec this image without dropping the listener passed to this function. func restart(listener net.Listener, errLogger *common.ErrorLogger) error { argv0, err := exec.LookPath(os.Args[0]) if nil != err { return err } wd, err := os.Getwd() if nil != err { return err } v := reflect.ValueOf(listener).Elem().FieldByName("fd").Elem() fd := uintptr(v.FieldByName("sysfd").Int()) allFiles := append([]*os.File{os.Stdin, os.Stdout, os.Stderr}, os.NewFile(fd, string(v.FieldByName("sysfile").String()))) p, err := os.StartProcess(argv0, os.Args, &os.ProcAttr{ Dir: wd, Env: append(os.Environ(), fmt.Sprintf("%s=%d", FDKey, fd)), Files: allFiles, }) if nil != err { return err } errLogger.Printf("spawned child %d\n", p.Pid) return nil }
func (services *Services) RunTcpServe(listener *controledListener, errLogger *common.ErrorLogger) { defer services.wg.Done() defer listener.Close() var tempDelay time.Duration for { conn, err := listener.Accept() if err != nil { if ne, ok := err.(net.Error); ok && ne.Temporary() { if tempDelay == 0 { tempDelay = 5 * time.Millisecond } else { tempDelay *= 2 } if max := 1 * time.Second; tempDelay > max { tempDelay = max } errLogger.Println("http: Accept error:", err, "retry:", tempDelay) time.Sleep(tempDelay) continue } errLogger.Println("http: Accept error:;", err) break } tempDelay = 0 worker, err := newWorkConn(conn, listener, errLogger) if err != nil { continue } listener.clientDict.Set(conn.RemoteAddr().String(), worker) listener.count += 1 go worker.RunWorker() } //监听socket关闭后,在这里等所有连接结束 listener.wg.Wait() }
func RunServer(addr_tcp string, addr_monitor string, errLogger *common.ErrorLogger) { runtime.GOMAXPROCS(runtime.NumCPU()) errLogger.Println("program start.") tcpAddr, err := net.ResolveTCPAddr("tcp", addr_tcp) if err != nil { errLogger.Fatalln("ResolveTCPAddr:", err) } controledListener, err := GetControledListener(tcpAddr) if err != nil { errLogger.Fatalln("GetControledListener:", err) } tcpMonitor, err := net.ResolveTCPAddr("tcp", addr_monitor) if err != nil { errLogger.Fatalln("ResolveMonitorAddr:", err) } controledMonitor, err := GetControledListener(tcpMonitor) if err != nil { errLogger.Fatalln("GetControledMonitorListener:", err) } //强杀 common.SignalWatchRegister(func() { os.Exit(-1) }, syscall.SIGTERM) //和平结束 common.SignalWatchRegister(func() { controledListener.Close(); controledMonitor.Close() }, os.Interrupt) //重启 common.SignalWatchRegister(func() { ReceiveSignupSignal(controledListener, errLogger) }, syscall.SIGHUP) common.SignalWatchRun() services := Services{wg: &sync.WaitGroup{}} //启动tcp服务 services.wg.Add(1) go services.RunTcpServe(controledListener, errLogger) services.wg.Add(1) go services.RunHttpServe(controledMonitor, controledListener, errLogger) //等等所有服务协程都结束 services.wg.Wait() errLogger.Println("program stop normal.") }