mirror of
https://github.com/chenjia404/go-p2ptunnel.git
synced 2025-10-24 23:51:11 +08:00
0.0.2:增加进程守护,增加自动重启释放资源
This commit is contained in:
42
main.go
42
main.go
@@ -13,6 +13,7 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/chenjia404/go-p2ptunnel/pRuntime"
|
||||||
"github.com/libp2p/go-libp2p"
|
"github.com/libp2p/go-libp2p"
|
||||||
"github.com/libp2p/go-libp2p/core/network"
|
"github.com/libp2p/go-libp2p/core/network"
|
||||||
"github.com/libp2p/go-libp2p/core/peerstore"
|
"github.com/libp2p/go-libp2p/core/peerstore"
|
||||||
@@ -191,7 +192,7 @@ func createLibp2pHost(ctx context.Context, priv crypto.PrivKey) (host.Host, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
version = "0.0.1"
|
version = "0.0.2"
|
||||||
gitRev = ""
|
gitRev = ""
|
||||||
buildTime = ""
|
buildTime = ""
|
||||||
)
|
)
|
||||||
@@ -207,6 +208,45 @@ func main() {
|
|||||||
networkType := flag.String("type", "tcp", "network type tcp/udp")
|
networkType := flag.String("type", "tcp", "network type tcp/udp")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
|
RE:
|
||||||
|
proc, err := pRuntime.NewProc()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("up proc fail........")
|
||||||
|
}
|
||||||
|
//如果proc为nil表示当前进程已经是子进程了
|
||||||
|
//不为空表示当前进程为主进程
|
||||||
|
if proc != nil {
|
||||||
|
go func() {
|
||||||
|
pRuntime.HandleEndSignal(func() {
|
||||||
|
if err := proc.Kill(); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
fmt.Println("main proc exit....")
|
||||||
|
|
||||||
|
os.Exit(0)
|
||||||
|
})
|
||||||
|
}()
|
||||||
|
//等待子进程退出后 重启
|
||||||
|
err = proc.Wait()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("proc wait err........")
|
||||||
|
} else {
|
||||||
|
goto RE
|
||||||
|
}
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
now := time.Now()
|
||||||
|
next := now.Add(time.Hour * 4)
|
||||||
|
timer := time.NewTimer(next.Sub(now))
|
||||||
|
t := <-timer.C //从定时器拿数据
|
||||||
|
fmt.Println("restart time:", t)
|
||||||
|
os.Exit(0)
|
||||||
|
}()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
|
||||||
priv, _ := loadUserPrivKey()
|
priv, _ := loadUserPrivKey()
|
||||||
|
|||||||
169
pRuntime/pRuntime.go
Normal file
169
pRuntime/pRuntime.go
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
package pRuntime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"os/signal"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
var pidFile = "go-p2ptunnel.pid"
|
||||||
|
|
||||||
|
func SetPidFile(pFile string) {
|
||||||
|
pidFile = pFile
|
||||||
|
}
|
||||||
|
|
||||||
|
func forkDaemon(isWritePidFile bool, environ ...string) (*exec.Cmd, error) {
|
||||||
|
cmdRet := &exec.Cmd{
|
||||||
|
Path: os.Args[0],
|
||||||
|
Args: os.Args,
|
||||||
|
Stdin: os.Stdin,
|
||||||
|
Stdout: os.Stdout,
|
||||||
|
Stderr: os.Stderr,
|
||||||
|
Env: append(os.Environ(), environ...),
|
||||||
|
}
|
||||||
|
err := cmdRet.Start()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
//写入pid
|
||||||
|
if isWritePidFile {
|
||||||
|
err = ioutil.WriteFile(pidFile, []byte(strconv.Itoa(cmdRet.Process.Pid)), 0666)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return cmdRet, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func DaemonInit() {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if os.Getenv("__Daemon") == "true" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c := "start"
|
||||||
|
if l := len(os.Args); l > 1 {
|
||||||
|
c = os.Args[l-1]
|
||||||
|
}
|
||||||
|
switch c {
|
||||||
|
case "start":
|
||||||
|
if CheckProIsRun() {
|
||||||
|
log.Fatal("当前进程已运行...")
|
||||||
|
}
|
||||||
|
cmdRet, err := forkDaemon(true, "__Daemon=true")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("start err : ", err)
|
||||||
|
}
|
||||||
|
log.Println("Daemon is run... pid: ", cmdRet.Process.Pid)
|
||||||
|
case "restart":
|
||||||
|
err := Stop()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("restart stop err : ", err)
|
||||||
|
}
|
||||||
|
os.Args = os.Args[:len(os.Args)-1]
|
||||||
|
cmdRet, err := forkDaemon(true, "__Daemon=true")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("forkDaemon err : ", err)
|
||||||
|
}
|
||||||
|
log.Println("Daemon is run... pid: ", cmdRet.Process.Pid)
|
||||||
|
case "stop":
|
||||||
|
err := Stop()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("stop err : ", err)
|
||||||
|
}
|
||||||
|
log.Println("Daemon is stop....")
|
||||||
|
case "reload":
|
||||||
|
err := Reload()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("reload err : ", err)
|
||||||
|
}
|
||||||
|
log.Println("Daemon reload success....")
|
||||||
|
}
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckProIsRun() bool {
|
||||||
|
if GetRunningPid() == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func FileExists(path string) bool {
|
||||||
|
_, err := os.Stat(path) //os.Stat获取文件信息
|
||||||
|
if err != nil {
|
||||||
|
if os.IsExist(err) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetRunningPid() int {
|
||||||
|
if !FileExists(pidFile) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
b, err := ioutil.ReadFile(pidFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("程序异常:", err)
|
||||||
|
}
|
||||||
|
pid, _ := strconv.Atoi(string(b))
|
||||||
|
p, err := os.FindProcess(pid)
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
err = p.Signal(syscall.Signal(0))
|
||||||
|
if err == nil {
|
||||||
|
return p.Pid
|
||||||
|
}
|
||||||
|
_ = os.Remove(pidFile)
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleEndSignal(fn func()) {
|
||||||
|
sig := make(chan os.Signal)
|
||||||
|
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
<-sig
|
||||||
|
_ = os.Remove(pidFile)
|
||||||
|
fn()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleReloadSignal(fn func()) {
|
||||||
|
sig := make(chan os.Signal)
|
||||||
|
signal.Notify(sig, syscall.SIGHUP)
|
||||||
|
for {
|
||||||
|
<-sig
|
||||||
|
fn()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Stop() error {
|
||||||
|
if !CheckProIsRun() {
|
||||||
|
return errors.New("进程没有运行")
|
||||||
|
}
|
||||||
|
pro, err := os.FindProcess(GetRunningPid())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return pro.Signal(syscall.SIGTERM)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Reload() error {
|
||||||
|
if !CheckProIsRun() {
|
||||||
|
return errors.New("进程没有运行")
|
||||||
|
}
|
||||||
|
pro, err := os.FindProcess(GetRunningPid())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return pro.Signal(syscall.SIGHUP)
|
||||||
|
}
|
||||||
47
pRuntime/proc.go
Normal file
47
pRuntime/proc.go
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package pRuntime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Proc struct {
|
||||||
|
proc *os.Process
|
||||||
|
procState *os.ProcessState
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProc() (*Proc, error) {
|
||||||
|
if os.Getenv("__NewProc") == "true" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
cmdRet, err := forkDaemon(false, "__NewProc=true")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Proc{
|
||||||
|
proc: cmdRet.Process,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Proc) Pid() int {
|
||||||
|
if p.proc == nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return p.proc.Pid
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Proc) Kill() error {
|
||||||
|
if p.proc == nil {
|
||||||
|
return fmt.Errorf("proc is null")
|
||||||
|
}
|
||||||
|
return p.proc.Kill()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Proc) Wait() error {
|
||||||
|
var err error
|
||||||
|
p.procState, err = p.proc.Wait()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user