Commit 8c316f22 authored by Tsaiilin's avatar Tsaiilin

配置文件支持配置为守护运行模式

parent 58161403
...@@ -10,12 +10,14 @@ import ( ...@@ -10,12 +10,14 @@ import (
"net/http" "net/http"
_ "net/http/pprof" _ "net/http/pprof"
"os" "os"
"os/exec"
"os/signal" "os/signal"
"path/filepath"
"runtime" "runtime"
"syscall" "syscall"
"time" "time"
"virjar.com/majora-go/client" "virjar.com/majora-go/client"
"virjar.com/majora-go/daemon"
"virjar.com/majora-go/global" "virjar.com/majora-go/global"
"virjar.com/majora-go/initialize" "virjar.com/majora-go/initialize"
"virjar.com/majora-go/log" "virjar.com/majora-go/log"
...@@ -24,7 +26,7 @@ import ( ...@@ -24,7 +26,7 @@ import (
var ( var (
configure string configure string
daemon bool
) )
var ( var (
...@@ -32,14 +34,9 @@ var ( ...@@ -32,14 +34,9 @@ var (
Date string Date string
) )
var (
cmd *exec.Cmd
)
func init() { func init() {
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())
flag.StringVar(&configure, "conf", "", "./majora -c path/to/your/majora.ini") flag.StringVar(&configure, "conf", "", "./majora -c path/to/your/majora.ini")
flag.BoolVar(&daemon, "daemon", false, "daemon")
flag.Parse() flag.Parse()
} }
...@@ -61,22 +58,6 @@ func initial() { ...@@ -61,22 +58,6 @@ func initial() {
}, },
} }
} }
if daemon {
var args []string
for _, arg := range os.Args[1:] {
if arg != "-daemon" {
args = append(args, arg)
}
}
cmd = exec.Command(os.Args[0], args...)
cmd.Env = os.Environ()
if err := cmd.Start(); err != nil {
panic(err)
}
log.Run().Infof("%s [pid-%d] running...\n", os.Args[0], cmd.Process.Pid)
os.Exit(0)
}
} }
func cli() { func cli() {
...@@ -99,8 +80,15 @@ func main() { ...@@ -99,8 +80,15 @@ func main() {
fmt.Println(Version) fmt.Println(Version)
os.Exit(0) os.Exit(0)
} }
initialize.MustInitConfig(configure, global.Config) initialize.MustInitConfig(configure, global.Config)
if global.Config.Daemon {
logFile := filepath.Join(global.Config.LogPath, "daemon.log")
d := daemon.NewDaemon(logFile)
d.MaxCount = 20 //最大重启次数
d.Run()
}
initialize.InitLogger() initialize.InitLogger()
initial() initial()
cli() cli()
......
...@@ -87,12 +87,10 @@ func (client *Client) check() { ...@@ -87,12 +87,10 @@ func (client *Client) check() {
continue continue
} }
log.Run().Warnf("Redial net check fail, redial...") log.Run().Warnf("Redial net check fail, redial...")
if client.session != nil { if client.redial.RedialByCheck(cfg) {
client.Redial(client.session, "check") client.natTunnel.Close()
} else { client.connect()
client.redial.RedialByCheck(cfg)
} }
} }
}) })
} }
...@@ -98,5 +98,6 @@ func (client *Client) Redial(session getty.Session, tag string) { ...@@ -98,5 +98,6 @@ func (client *Client) Redial(session getty.Session, tag string) {
log.Run().Info("[Redial %s] start close local session", tag) log.Run().Info("[Redial %s] start close local session", tag)
client.CloseAll(session) client.CloseAll(session)
client.redial.Redial(client.config, tag) client.redial.Redial(client.config, tag)
session.Close() client.natTunnel.Close()
client.connect()
} }
env: debug
tunnel_addr: majora-vps-zj.virjar.com:5879 tunnel_addr: majora-vps-zj.virjar.com:5879
dns_server: 114.114.114.114:53 dns_server: 114.114.114.114:53
pprof_port: 16666 daemon: true
log_level: debug log_level: debug
log_path: ./output/log/ log_path: ./majora-log/
reconn_intervalz: 5s reconn_intervalz: 5s
net_check_interval: 5s net_check_interval: 5s
dns_cache_duration: 10m dns_cache_duration: 10m
net_check_url: https://www.baidu.com[extra] net_check_url: https://www.baidu.com[extra]
account: superman account: superman
#redial: redial:
# command: /bin/bash command: /bin/bash
# exec_path: /root/ppp_redial.sh exec_path: /root/ppp_redial.sh
# redial_duration: 5m redial_duration: 5m
# wait_time: 10s wait_time: 10s
...@@ -2,6 +2,8 @@ env: debug ...@@ -2,6 +2,8 @@ env: debug
tunnel_addr: majora-vps-zj.virjar.com:5879 tunnel_addr: majora-vps-zj.virjar.com:5879
dns_server: 114.114.114.114:53 dns_server: 114.114.114.114:53
log_level: info log_level: info
log_path: ./majora-log/
daemon: true
reconn_interval: 5s reconn_interval: 5s
net_check_interval: 5s net_check_interval: 5s
net_check_url: https://www.baidu.com net_check_url: https://www.baidu.com
...@@ -10,4 +12,4 @@ redial: ...@@ -10,4 +12,4 @@ redial:
command: /bin/bash command: /bin/bash
exec_path: /root/ppp_redial.sh exec_path: /root/ppp_redial.sh
redial_duration: 5m redial_duration: 5m
wait_time: 10s wait_time: 15s
...@@ -12,7 +12,6 @@ echo "old pid is ${old_pid}" ...@@ -12,7 +12,6 @@ echo "old pid is ${old_pid}"
echo "clean old ..." echo "clean old ..."
`ps -ef | grep majora | grep -v grep | awk '{print $2}'| xargs kill -9` `ps -ef | grep majora | grep -v grep | awk '{print $2}'| xargs kill -9`
mkdir -p "majora-log"
mkdir -p output/log exec ./majora -conf majora.yaml
\ No newline at end of file
exec ./majora -daemon -conf majora.yaml
\ No newline at end of file
...@@ -9,11 +9,11 @@ rm -fr majora.yaml ...@@ -9,11 +9,11 @@ rm -fr majora.yaml
rm -fr majora.service rm -fr majora.service
rm -fr majora-dev.yaml rm -fr majora-dev.yaml
rm -fr majora.log rm -fr majora.log
rm -fr output rm -fr majora-log
rm -fr std.log rm -fr std.log
tar -zxvf majora-cli.tar.gz tar -zxvf majora-cli.tar.gz
mv -f majora-cli*/* . mv -f majora-cli*/* .
exec bash ./start.sh exec bash ./start.sh
\ No newline at end of file
// +build !windows,!plan9
package daemon
import "syscall"
func NewSysProcAttr() *syscall.SysProcAttr {
return &syscall.SysProcAttr{
Setsid: true,
}
}
// +build windows
package daemon
import "syscall"
func NewSysProcAttr() *syscall.SysProcAttr {
return &syscall.SysProcAttr{
HideWindow: true,
}
}
package daemon
import (
"fmt"
"log"
"os"
"os/exec"
"strconv"
"time"
)
const EnvName = "XW_DAEMON_IDX"
var runIdx = 0
type Daemon struct {
LogFile string
MaxCount int
MaxError int
MinExitTime int64
}
func Background(logFile string, isExit bool) (*exec.Cmd, error) {
runIdx++
envIdx, err := strconv.Atoi(os.Getenv(EnvName))
if err != nil {
envIdx = 0
}
if runIdx <= envIdx {
return nil, nil
}
env := os.Environ()
env = append(env, fmt.Sprintf("%s=%d", EnvName, runIdx))
cmd, err := startProc(os.Args, env, logFile)
if err != nil {
log.Println(os.Getpid(), " Start child process error:", err)
return nil, err
} else {
log.Println(os.Getpid(), " Start child process success:", cmd.Process.Pid)
}
if isExit {
os.Exit(0)
}
return cmd, nil
}
func NewDaemon(logFile string) *Daemon {
return &Daemon{
LogFile: logFile,
MaxCount: 0,
MaxError: 3,
MinExitTime: 10,
}
}
func (d *Daemon) Run() {
_, _ = Background(d.LogFile, true)
var t int64
count := 1
errNum := 0
for {
dInfo := fmt.Sprintf("daemon process(pid:%d; count:%d/%d; errNum:%d/%d):",
os.Getpid(), count, d.MaxCount, errNum, d.MaxError)
if errNum > d.MaxError {
log.Println(dInfo, "Start child process error too many,exit")
os.Exit(1)
}
if d.MaxCount > 0 && count > d.MaxCount {
log.Println(dInfo, "Too many restarts")
os.Exit(0)
}
count++
t = time.Now().Unix()
cmd, err := Background(d.LogFile, false)
if err != nil {
log.Println(dInfo, "Start child process err:", err)
errNum++
continue
}
if cmd == nil {
log.Printf("child process pid=%d: start", os.Getpid())
break
}
err = cmd.Wait()
dat := time.Now().Unix() - t
if dat < d.MinExitTime {
errNum++
} else {
errNum = 0
}
log.Printf("%s child process(%d)exit, Ran for %d seconds: %v\n", dInfo, cmd.ProcessState.Pid(), dat, err)
}
}
func startProc(args, env []string, logFile string) (*exec.Cmd, error) {
cmd := &exec.Cmd{
Path: args[0],
Args: args,
Env: env,
SysProcAttr: NewSysProcAttr(),
}
if logFile != "" {
stdout, err := os.OpenFile(logFile, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666)
if err != nil {
log.Println(os.Getpid(), ": Open log file error", err)
return nil, err
}
cmd.Stderr = stdout
cmd.Stdout = stdout
}
err := cmd.Start()
if err != nil {
return nil, err
}
return cmd, nil
}
...@@ -26,7 +26,7 @@ func NewPPPRedial() *PPPRedial { ...@@ -26,7 +26,7 @@ func NewPPPRedial() *PPPRedial {
} }
} }
func (p *PPPRedial) Redial(cfg *model.Configure, tag string) { func (p *PPPRedial) Redial(cfg *model.Configure, tag string) bool{
if p.inRedialing.CAS(false, true) { if p.inRedialing.CAS(false, true) {
log.Run().Infof("[PPPRedial %s] start", tag) log.Run().Infof("[PPPRedial %s] start", tag)
beforeIp := GetPPP() beforeIp := GetPPP()
...@@ -46,13 +46,15 @@ func (p *PPPRedial) Redial(cfg *model.Configure, tag string) { ...@@ -46,13 +46,15 @@ func (p *PPPRedial) Redial(cfg *model.Configure, tag string) {
} }
} }
p.inRedialing.CAS(true, false) p.inRedialing.CAS(true, false)
return true
} else { } else {
log.Run().Infof("[PPPRedial %s] inRedialing ignore this", tag) log.Run().Infof("[PPPRedial %s] inRedialing ignore this", tag)
return false
} }
} }
func (p *PPPRedial) RedialByCheck(cfg *model.Configure) { func (p *PPPRedial) RedialByCheck(cfg *model.Configure) bool {
p.Redial(cfg, "check") return p.Redial(cfg, "check")
} }
func command(cfg *model.Configure) bool { func command(cfg *model.Configure) bool {
......
...@@ -22,6 +22,7 @@ type Configure struct { ...@@ -22,6 +22,7 @@ type Configure struct {
Env string `mapstructure:"env"` Env string `mapstructure:"env"`
LogLevel string `mapstructure:"log_level"` LogLevel string `mapstructure:"log_level"`
LogPath string `mapstructure:"log_path"` LogPath string `mapstructure:"log_path"`
Daemon bool `mapstructure:"daemon"`
PprofPort int `mapstructure:"pprof_port"` PprofPort int `mapstructure:"pprof_port"`
TunnelAddr string `mapstructure:"tunnel_addr"` TunnelAddr string `mapstructure:"tunnel_addr"`
DNSServer string `mapstructure:"dns_server"` DNSServer string `mapstructure:"dns_server"`
...@@ -43,6 +44,7 @@ func NewDefMajoraConf() *Configure { ...@@ -43,6 +44,7 @@ func NewDefMajoraConf() *Configure {
return &Configure{ return &Configure{
Env: "product", Env: "product",
LogLevel: "info", LogLevel: "info",
Daemon: false,
PprofPort: 0, PprofPort: 0,
TunnelAddr: common.DefNatAddr, TunnelAddr: common.DefNatAddr,
DNSServer: common.DNSServer, //nolint:typecheck DNSServer: common.DNSServer, //nolint:typecheck
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment