diff --git a/zh/12.3.md b/zh/12.3.md index eed4fc10..6962c72d 100644 --- a/zh/12.3.md +++ b/zh/12.3.md @@ -9,104 +9,104 @@ ```Go - d := flag.Bool("d", false, "Whether or not to launch in the background(like a daemon)") - if *d { - cmd := exec.Command(os.Args[0], - "-close-fds", - "-addr", *addr, - "-call", *call, - ) - serr, err := cmd.StderrPipe() - if err != nil { - log.Fatalln(err) - } - err = cmd.Start() - if err != nil { - log.Fatalln(err) - } - s, err := ioutil.ReadAll(serr) - s = bytes.TrimSpace(s) - if bytes.HasPrefix(s, []byte("addr: ")) { - fmt.Println(string(s)) - cmd.Process.Release() - } else { - log.Printf("unexpected response from MarGo: `%s` error: `%v`\n", s, err) - cmd.Process.Kill() - } + d := flag.Bool("d", false, "Whether or not to launch in the background(like a daemon)") + if *d { + cmd := exec.Command(os.Args[0], + "-close-fds", + "-addr", *addr, + "-call", *call, + ) + serr, err := cmd.StderrPipe() + if err != nil { + log.Fatalln(err) } + err = cmd.Start() + if err != nil { + log.Fatalln(err) + } + s, err := ioutil.ReadAll(serr) + s = bytes.TrimSpace(s) + if bytes.HasPrefix(s, []byte("addr: ")) { + fmt.Println(string(s)) + cmd.Process.Release() + } else { + log.Printf("unexpected response from MarGo: `%s` error: `%v`\n", s, err) + cmd.Process.Kill() + } + } ``` - 另一种是利用syscall的方案,但是这个方案并不完善: ```Go - package main - - import ( - "log" - "os" - "syscall" - ) - - func daemon(nochdir, noclose int) int { - var ret, ret2 uintptr - var err uintptr - - darwin := syscall.OS == "darwin" - - // already a daemon - if syscall.Getppid() == 1 { - return 0 - } - - // fork off the parent process - ret, ret2, err = syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0) - if err != 0 { - return -1 - } - - // failure - if ret2 < 0 { - os.Exit(-1) - } - - // handle exception for darwin - if darwin && ret2 == 1 { - ret = 0 - } - - // if we got a good PID, then we call exit the parent process. - if ret > 0 { - os.Exit(0) - } - - /* Change the file mode mask */ - _ = syscall.Umask(0) - - // create a new SID for the child process - s_ret, s_errno := syscall.Setsid() - if s_errno != 0 { - log.Printf("Error: syscall.Setsid errno: %d", s_errno) - } - if s_ret < 0 { - return -1 - } - - if nochdir == 0 { - os.Chdir("/") - } - - if noclose == 0 { - f, e := os.OpenFile("/dev/null", os.O_RDWR, 0) - if e == nil { - fd := f.Fd() - syscall.Dup2(fd, os.Stdin.Fd()) - syscall.Dup2(fd, os.Stdout.Fd()) - syscall.Dup2(fd, os.Stderr.Fd()) - } - } - + package main + + import ( + "log" + "os" + "syscall" + ) + + func daemon(nochdir, noclose int) int { + var ret, ret2 uintptr + var err uintptr + + darwin := syscall.OS == "darwin" + + // already a daemon + if syscall.Getppid() == 1 { return 0 - } + } + + // fork off the parent process + ret, ret2, err = syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0) + if err != 0 { + return -1 + } + + // failure + if ret2 < 0 { + os.Exit(-1) + } + + // handle exception for darwin + if darwin && ret2 == 1 { + ret = 0 + } + + // if we got a good PID, then we call exit the parent process. + if ret > 0 { + os.Exit(0) + } + + /* Change the file mode mask */ + _ = syscall.Umask(0) + + // create a new SID for the child process + s_ret, s_errno := syscall.Setsid() + if s_errno != 0 { + log.Printf("Error: syscall.Setsid errno: %d", s_errno) + } + if s_ret < 0 { + return -1 + } + + if nochdir == 0 { + os.Chdir("/") + } + + if noclose == 0 { + f, e := os.OpenFile("/dev/null", os.O_RDWR, 0) + if e == nil { + fd := f.Fd() + syscall.Dup2(fd, os.Stdin.Fd()) + syscall.Dup2(fd, os.Stdout.Fd()) + syscall.Dup2(fd, os.Stderr.Fd()) + } + } + + return 0 + } ``` 上面提出了两种实现Go的daemon方案,但是我还是不推荐大家这样去实现,因为官方还没有正式的宣布支持daemon,当然第一种方案目前来看是比较可行的,而且目前开源库skynet也在采用这个方案做daemon。 @@ -128,45 +128,45 @@ Supervisord默认的配置文件路径为/etc/supervisord.conf,通过文本编 ```conf - ;/etc/supervisord.conf - [unix_http_server] - file = /var/run/supervisord.sock - chmod = 0777 - chown= root:root +;/etc/supervisord.conf +[unix_http_server] +file = /var/run/supervisord.sock +chmod = 0777 +chown= root:root - [inet_http_server] - # Web管理界面设定 - port=9001 - username = admin - password = yourpassword +[inet_http_server] +# Web管理界面设定 +port=9001 +username = admin +password = yourpassword - [supervisorctl] - ; 必须和'unix_http_server'里面的设定匹配 - serverurl = unix:///var/run/supervisord.sock +[supervisorctl] +; 必须和'unix_http_server'里面的设定匹配 +serverurl = unix:///var/run/supervisord.sock - [supervisord] - logfile=/var/log/supervisord/supervisord.log ; (main log file;default $CWD/supervisord.log) - logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB) - logfile_backups=10 ; (num of main logfile rotation backups;default 10) - loglevel=info ; (log level;default info; others: debug,warn,trace) - pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) - nodaemon=true ; (start in foreground if true;default false) - minfds=1024 ; (min. avail startup file descriptors;default 1024) - minprocs=200 ; (min. avail process descriptors;default 200) - user=root ; (default is current user, required if root) - childlogdir=/var/log/supervisord/ ; ('AUTO' child log dir, default $TEMP) +[supervisord] +logfile=/var/log/supervisord/supervisord.log ; (main log file;default $CWD/supervisord.log) +logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB) +logfile_backups=10 ; (num of main logfile rotation backups;default 10) +loglevel=info ; (log level;default info; others: debug,warn,trace) +pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid) +nodaemon=true ; (start in foreground if true;default false) +minfds=1024 ; (min. avail startup file descriptors;default 1024) +minprocs=200 ; (min. avail process descriptors;default 200) +user=root ; (default is current user, required if root) +childlogdir=/var/log/supervisord/ ; ('AUTO' child log dir, default $TEMP) - [rpcinterface:supervisor] - supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface +[rpcinterface:supervisor] +supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface - ; 管理的单个进程的配置,可以添加多个program - [program:blogdemon] - command=/data/blog/blogdemon - autostart = true - startsecs = 5 - user = root - redirect_stderr = true - stdout_logfile = /var/log/supervisord/blogdemon.log +; 管理的单个进程的配置,可以添加多个program +[program:blogdemon] +command=/data/blog/blogdemon +autostart = true +startsecs = 5 +user = root +redirect_stderr = true +stdout_logfile = /var/log/supervisord/blogdemon.log ``` ### Supervisord管理