Format and remove 12.3.md spaces
This commit is contained in:
250
zh/12.3.md
250
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管理
|
||||
|
||||
Reference in New Issue
Block a user