From bd29552e0ff997a9d64dc3d0dd4731903c4d3b74 Mon Sep 17 00:00:00 2001 From: gotoeasy Date: Wed, 14 Sep 2022 20:03:18 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A9=E7=94=A8pid=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=91=BD=E4=BB=A4=E8=A1=8C=E5=8F=82=E6=95=B0=20-d=E3=80=81stop?= =?UTF-8?q?=E3=80=81restart?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- glc/onstart/daemon.go | 99 ++++++++++++++++++++++++------------------- glc/onstart/pid.go | 29 +------------ 2 files changed, 56 insertions(+), 72 deletions(-) diff --git a/glc/onstart/daemon.go b/glc/onstart/daemon.go index c2901b4..29eacac 100644 --- a/glc/onstart/daemon.go +++ b/glc/onstart/daemon.go @@ -1,12 +1,13 @@ package onstart import ( - "flag" "fmt" - "log" "os" "os/exec" + "os/user" + "path/filepath" "runtime" + "time" ) func init() { @@ -16,11 +17,20 @@ func init() { return } - pidfile := "~/.gologcenter/glc.pid" + // pid 目录、文件 + pidpath := "." + pidfile := "glc.pid" + u, err := user.Current() + if err == nil { + pidpath = filepath.Join(u.HomeDir, ".glogcenter") + os.MkdirAll(pidpath, 0766) + } + pidpathfile := filepath.Join(pidpath, pidfile) // 操作系统是linux时,支持以命令行参数【-d】后台方式启动,【stop】停止 daemon := false stop := false + restart := false for index, arg := range os.Args { if index == 0 { continue @@ -31,61 +41,62 @@ func init() { if arg == "stop" { stop = true } + if arg == "restart" { + restart = true + } } - // 停止 - if stop { - tmpPid := readPid(pidfile) - if tmpPid != "" { - exec.Command("sh", "-c", "kill "+tmpPid) + rs := checkPidFile(pidpathfile) + if rs != nil { + if stop { + // 退出 + cmd := exec.Command("sh", "-c", "kill "+rs.Pid) + cmd.Start() + } else if restart { + // 重启 + cmd := exec.Command("sh", "-c", "kill "+rs.Pid) + cmd.Start() + // + time.Sleep(time.Duration(2) * time.Second) + } else { + // 禁止重复启动 + fmt.Printf("%s\n", rs.Pid) + os.Exit(0) } + } + + if stop { os.Exit(0) } - // 启动守护进程 if daemon { + // cmd := exec.Command(os.Args[0], flag.Args()...) + cmd := exec.Command(os.Args[0]) // 不再需要启动参数了 - // 已启动时忽略 - chk := checkPidFile(pidfile) - if chk != nil { - log.Println(chk.Pid) - os.Exit(0) // 进程已存在,不重复启动 + err := cmd.Start() + for i := 0; i < 60; i++ { + if err != nil { + time.Sleep(time.Duration(1) * time.Second) // 原进程没退出的话会导致启动失败,等待1秒后再试 + } else { + break + } } - - // 启动失败则退出 - cmd := exec.Command(os.Args[0], flag.Args()...) - if err := cmd.Start(); err != nil { + if err != nil { + // 最多等1分钟,仍旧启动失败就放弃 fmt.Printf("start %s failed, error: %v\n", os.Args[0], err) os.Exit(1) } - // 启动成功则保存pid - daemonPid := fmt.Sprintf("%d", cmd.Process.Pid) - err := savePid(pidfile, daemonPid) - if err != nil { - // 保存pid失败则退出 - exec.Command("sh", "-c", "kill "+daemonPid) - os.Exit(1) // 创建或保存pid文件失败 - } - - log.Println(daemonPid) + fmt.Printf("%d\n", cmd.Process.Pid) os.Exit(0) - } - - // 普通启动 - // 已启动时忽略 - chk := checkPidFile(pidfile) - if chk != nil { - log.Println(chk.Pid) - os.Exit(0) // 进程已存在,不重复启动 - } - - // 保存pid失败则退出 - pid := fmt.Sprintf("%d", os.Getpid()) - err := savePid(pidfile, pid) - if err != nil { - exec.Command("sh", "-c", "kill "+pid) - os.Exit(1) // 创建或保存pid文件失败 + } else { + npid := fmt.Sprintf("%d", os.Getpid()) + nerr := savePid(pidpathfile, npid) + if nerr != nil { + cmd := exec.Command("sh", "-c", "kill "+npid) + cmd.Start() + os.Exit(1) + } } } diff --git a/glc/onstart/pid.go b/glc/onstart/pid.go index c4f14c5..4e9fe4d 100644 --- a/glc/onstart/pid.go +++ b/glc/onstart/pid.go @@ -14,33 +14,6 @@ type PidFile struct { Err error // error } -// 指定路径下生成pid文件,文件内容为pid,已存在时检查pid有效性 -func NewPid(pathfile string, pid string) *PidFile { - - // 运行中时直接返回 - if opid := checkPidFile(pathfile); opid != nil { - return opid - } - - // 保存PID - if err := savePid(pathfile, pid); err != nil { - log.Println("save pid file failed", pathfile) - return &PidFile{ - Path: pathfile, - Err: err, - } - } - - // 成功创建后返回 - return &PidFile{ - Path: pathfile, - Pid: pid, - IsNew: false, - Err: nil, - } - -} - func checkPidFile(path string) *PidFile { pid := readPid(path) if pid == "" { @@ -64,7 +37,6 @@ func readPid(path string) string { } func savePid(path string, pid string) error { - if err := os.MkdirAll(filepath.Dir(path), os.FileMode(0755)); err != nil { log.Println("create pid file failed", path) return err @@ -74,5 +46,6 @@ func savePid(path string, pid string) error { log.Println("save pid file failed", path) return err } + return nil }