diff --git a/CHANGELOG b/CHANGELOG index cd64371..7b80d0e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,11 @@ proxy更新日志 +v3.9 +1.增加了守护运行参数--forever,比如: proxy http --forever , + proxy会fork子进程,然后监控子进程,如果子进程异常退出,5秒后重启子进程. + 该参数配合后台运行参数--daemon和日志参数--log,可以保障proxy一直在后台执行不会因为意外退出, + 而且可以通过日志文件看到proxy的输出日志内容. + 比如: proxy http -p ":9090" --forever --log proxy.log --daemon + v3.8 1.增加了日志输出到文件--log参数,比如: --log proxy.log,日志就会输出到proxy.log方便排除问题. diff --git a/README.md b/README.md index 31f1cce..dd9c8ff 100644 --- a/README.md +++ b/README.md @@ -112,23 +112,15 @@ curl -L https://raw.githubusercontent.com/snail007/goproxy/master/install_auto.s 安装完成,配置目录是/etc/proxy,更详细的使用方法参考下面的进一步了解. 如果安装失败或者你的vps不是linux64位系统,请按照下面的半自动步骤安装: -#### 手动安装 -#### **1.登录你的VPS,下载守护进程monexec,选择合适你的版本,vps一般选择"linux_amd64.tar.gz"的即可.** -下载地址:https://github.com/reddec/monexec/releases -比如下载到/root/proxy/ -执行: -```shell -mkdir /root/proxy/ -cd /root/proxy/ -wget https://github.com/reddec/monexec/releases/download/v0.1.1/monexec_0.1.1_linux_amd64.tar.gz -``` -#### **2.下载proxy** +#### 手动安装 + +#### **1.下载proxy** 下载地址:https://github.com/snail007/goproxy/releases ```shell cd /root/proxy/ -wget https://github.com/snail007/goproxy/releases/download/v3.8/proxy-linux-amd64.tar.gz +wget https://github.com/snail007/goproxy/releases/download/v3.9/proxy-linux-amd64.tar.gz ``` -#### **3.下载自动安装脚本** +#### **2.下载自动安装脚本** ```shell cd /root/proxy/ wget https://raw.githubusercontent.com/snail007/goproxy/master/install.sh diff --git a/config.go b/config.go index 87f03f2..396019f 100755 --- a/config.go +++ b/config.go @@ -1,12 +1,14 @@ package main import ( + "bufio" "fmt" "log" "os" "os/exec" "proxy/services" "proxy/utils" + "time" kingpin "gopkg.in/alecthomas/kingpin.v2" ) @@ -14,6 +16,7 @@ import ( var ( app *kingpin.Application service *services.ServiceItem + cmd *exec.Cmd ) func initConfig() (err error) { @@ -38,6 +41,7 @@ func initConfig() (err error) { app.Author("snail").Version(APP_VERSION) debug := app.Flag("debug", "debug log output").Default("false").Bool() daemon := app.Flag("daemon", "run proxy in background").Default("false").Bool() + forever := app.Flag("forever", "run proxy in forever,fail and retry").Default("false").Bool() logfile := app.Flag("log", "log file path").Default("").String() //########http######### @@ -155,18 +159,6 @@ func initConfig() (err error) { //parse args serviceName := kingpin.MustParse(app.Parse(os.Args[1:])) flags := log.Ldate - if *daemon { - args := []string{} - for _, arg := range os.Args[1:] { - if arg != "--daemon" { - args = append(args, arg) - } - } - cmd := exec.Command(os.Args[0], args...) - cmd.Start() - fmt.Printf("%s [PID] %d running...\n", os.Args[0], cmd.Process.Pid) - os.Exit(0) - } if *debug { flags |= log.Lshortfile | log.Lmicroseconds } else { @@ -180,7 +172,75 @@ func initConfig() (err error) { log.Fatal(e) } log.SetOutput(f) - } else { + } + if *daemon { + args := []string{} + for _, arg := range os.Args[1:] { + if arg != "--daemon" { + args = append(args, arg) + } + } + cmd = exec.Command(os.Args[0], args...) + cmd.Start() + f := "" + if *forever { + f = "forever " + } + log.Printf("%s%s [PID] %d running...\n", f, os.Args[0], cmd.Process.Pid) + os.Exit(0) + } + if *forever { + args := []string{} + for _, arg := range os.Args[1:] { + if arg != "--forever" { + args = append(args, arg) + } + } + go func() { + for { + if cmd != nil { + cmd.Process.Kill() + } + cmd = exec.Command(os.Args[0], args...) + cmdReaderStderr, err := cmd.StderrPipe() + if err != nil { + log.Printf("ERR:%s,restarting...\n", err) + continue + } + cmdReader, err := cmd.StdoutPipe() + if err != nil { + log.Printf("ERR:%s,restarting...\n", err) + continue + } + scanner := bufio.NewScanner(cmdReader) + scannerStdErr := bufio.NewScanner(cmdReaderStderr) + go func() { + for scanner.Scan() { + fmt.Println(scanner.Text()) + } + }() + go func() { + for scannerStdErr.Scan() { + fmt.Println(scannerStdErr.Text()) + } + }() + if err := cmd.Start(); err != nil { + log.Printf("ERR:%s,restarting...\n", err) + continue + } + pid := cmd.Process.Pid + log.Printf("worker %s [PID] %d running...\n", os.Args[0], pid) + if err := cmd.Wait(); err != nil { + log.Printf("ERR:%s,restarting...", err) + continue + } + log.Printf("%s [PID] %d unexpected exited, restarting...\n", os.Args[0], pid) + time.Sleep(time.Second * 5) + } + }() + return + } + if *logfile == "" { poster() } //regist services and run service diff --git a/install.sh b/install.sh index f972333..971ac34 100755 --- a/install.sh +++ b/install.sh @@ -1,12 +1,6 @@ #!/bin/bash set -e -# install monexec -tar zxvf monexec_0.1.1_linux_amd64.tar.gz -cd monexec_0.1.1_linux_amd64 -cp monexec /usr/bin/ -chmod +x /usr/bin/monexec -cd .. # #install proxy tar zxvf proxy-linux-amd64.tar.gz cp proxy /usr/bin/ diff --git a/install_auto.sh b/install_auto.sh index 9887e29..6a2f4c1 100755 --- a/install_auto.sh +++ b/install_auto.sh @@ -5,15 +5,8 @@ if [ -e /tmp/proxy ]; then fi mkdir /tmp/proxy cd /tmp/proxy -wget https://github.com/reddec/monexec/releases/download/v0.1.1/monexec_0.1.1_linux_amd64.tar.gz -wget https://github.com/snail007/goproxy/releases/download/v3.8/proxy-linux-amd64.tar.gz +wget https://github.com/snail007/goproxy/releases/download/v3.9/proxy-linux-amd64.tar.gz -# install monexec -tar zxvf monexec_0.1.1_linux_amd64.tar.gz -cd monexec_0.1.1_linux_amd64 -cp monexec /usr/bin/ -chmod +x /usr/bin/monexec -cd .. # #install proxy tar zxvf proxy-linux-amd64.tar.gz cp proxy /usr/bin/ diff --git a/main.go b/main.go index 01fd68f..6e91cee 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,6 @@ package main import ( - "fmt" "log" "os" "os/signal" @@ -9,14 +8,18 @@ import ( "syscall" ) -const APP_VERSION = "3.8" +const APP_VERSION = "3.9" func main() { err := initConfig() if err != nil { log.Fatalf("err : %s", err) } - Clean(&service.S) + if service != nil && service.S != nil { + Clean(&service.S) + } else { + Clean(nil) + } } func Clean(s *services.Service) { signalChan := make(chan os.Signal, 1) @@ -29,8 +32,14 @@ func Clean(s *services.Service) { syscall.SIGQUIT) go func() { for _ = range signalChan { - fmt.Println("\nReceived an interrupt, stopping services...") - (*s).Clean() + log.Println("Received an interrupt, stopping services...") + if s != nil && *s != nil { + (*s).Clean() + } + if cmd != nil { + log.Printf("clean process %d", cmd.Process.Pid) + cmd.Process.Kill() + } cleanupDone <- true } }() diff --git a/release.sh b/release.sh index c45a55d..5bdc01a 100755 --- a/release.sh +++ b/release.sh @@ -1,5 +1,5 @@ #!/bin/bash -VER="3.8" +VER="3.9" RELEASE="release-${VER}" rm -rf .cert mkdir .cert