Tras la finalización del programa de desarrollo, ahora queremos implementar aplicaciones Web, pero ¿cómo hacemos uso de estas aplicaciones hacen? Porque después de la compilación de programas Go es un archivo ejecutable, por escrito un programa en C utilizando lectores demonio debe saber que usted puede conseguir el programa de fondo perfecto funciona de forma continua, pero todavía no es perfecto en el daemon presente Go realización, por lo tanto, para un despliegue de la aplicación Go, podemos usar herramientas de terceros para gestionar, hay muchas herramientas de terceros, como Supervisord, advenedizo, daemon tools, etc Esta sección describe mi propio sistema utilizando las herramientas actuales Supervisord.
Actualmente los programas go no pueden ser alcanzados demonio, consulte el Go detallada bug idioma: <http://code.google.com/p/go/issues/detail?id=227
>, probablemente significa que es difícil desde el uso del tenedor actual de un hilo, porque no hay manera fácil de asegurarse de que todos los hilos han usado problema de la consistencia del estado.
Pero podemos ver algunas implementaciones daemon muchos métodos en línea, tales como las siguientes dos maneras:
- MarGo una implementación de la idea de utilizar Command para ejecutar sus propias aplicaciones, si realmente queremos lograr, se recomienda que este tipo de programas
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()
}
}
- Otra solución es usar la llamada al sistema, pero esta solución no es perfecta::
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
}
The above proposed two implementations Go's daemon program, but I still do not recommend you to realize this, because the official announcement has not officially support daemon, of course, the first option is more feasible for now, but it is currently open source library skynet in adopting this program do daemon.
Go has been described above, there are two options currently are to realize his daemon, but the government itself does not support this one, so it is recommended that you use sophisticated tools to manage our third-party applications, here I'll give you a present more extensive use of process management software: Supervisord. Supervisord is implemented in Python a very useful process management tool. supervisord will help you to manage applications into daemon process, but can be easily turned on via the command, shut down, restart, etc, and it is managed by the collapse will automatically restart once the process so that you can ensure that the program execution is interrupted in the case there are self-healing capabilities.
I stepped in front of a pit in the application, because all applications are made Supervisord parent born, then when you change the operating system file descriptor after, do not forget to restart Supervisord, light restart following application program useless. I just had the system installed after the first installed Supervisord, then start the deployment process, modify the file descriptor, restart the program, that the file descriptor is already 100,000, but in fact Supervisord this time or the default 1024, led him to manage the process All descriptors is 1024. pressure after opening up the system to start a newspaper run out of file descriptors, search for a long time to find the pit.
Supervisord can sudo easy_install supervisor
installation, of course, can also Supervisord official website to download, unzip and go to the folder where the source code, run setup.py install
to install.
- Must be installed using easy_install setuptools
Open the http://pypi.python.org/pypi/setuptools# files
, depending on your system version of python download the appropriate file, and then execute sh setuptoolsxxxx.egg
, so that you can use easy_install command to install Supervisord.
Supervisord default configuration file path is /etc/supervisord.conf
, through a text editor to modify this file, the following is a sample configuration file:
;/etc/supervisord.conf
[unix_http_server]
file = /var/run/supervisord.sock
chmod = 0777
chown= root:root
[inet_http_server]
# Web management interface settings
port=9001
username = admin
password = yourpassword
[supervisorctl]
; Must 'unix_http_server' match the settings inside
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)
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
; Manage the configuration of a single process, you can add multiple program
[program: blogdemon]
command =/data/blog/blogdemon
autostart = true
startsecs = 5
user = root
redirect_stderr = true
stdout_logfile =/var/log/supervisord/blogdemon.log
After installation is complete, there are two Supervisord available command line supervisor and supervisorctl, command explained as follows:
- Supervisord, initial startup Supervisord, start, set in the configuration management process.
- Supervisorctl stop programxxx, stop one process(programxxx), programxxx for the [program: blogdemon] in configured value, this example is blogdemon.
- Supervisorctl start programxxx, start a process
- Supervisorctl restart programxxx, restarting a process
- Supervisorctl stop all, stop all processes, Note: start, restart, stop will not load the latest configuration files.
- Supervisorctl reload, load the latest configuration file, and press the new configuration to start, manage all processes.
This section we describe how to implement daemon of the Go, but due to the current lack of Go-daemon implementation, need to rely on third-party tools to achieve the application daemon management approach, so here describes a process using python to write management tools Supervisord by Supervisord can easily put our Go up and application management.
- Directory
- Previous section: Errors and crashes
- Next section: Backup and recovery