2011-12-29 11 views
5

Ho scritto uno script Upstart per Redis come segue:Esecuzione Redis in forma daemonized e utilizzando Upstart per gestirlo non funziona

description "Redis Server" 

start on runlevel [2345] 
stop on shutdown 
expect daemon 

exec sudo -u redis /usr/local/bin/redis-server /etc/redis/redis.conf 

respawn 
respawn limit 10 5 

Ho quindi configurare Redis via E 'redis.conf a:

Tutta la documentazione e la mia sperimentazione dimostrano che Redis supporta due volte in modalità demonizzata e "expect daemon" dovrebbe funzionare, ma lo script Upstart è sempre in attesa sul PID dell'ex genitore (PID-1). Qualcuno ha funzionato?

risposta

3

Altre persone hanno lo stesso problema. Vedi this gist.

Quando l'opzione è attivata demonizzare, Redis non verifica se il processo è già un demone (non v'è alcuna chiamata a getppid). Si biforca sistematicamente, ma solo una volta. È piuttosto insoliti, altri meccanismi daemonization può richiedere la prima osservazione getppid e forchetta di essere chiamato due volte (prima e dopo la chiamata setsid), ma in Linux questo non è strettamente necessaria.

Vedi this faq per ulteriori informazioni su daemonization.

Redis demonizzare funzione è estremamente semplice:

void daemonize(void) { 
    int fd; 

    if (fork() != 0) exit(0); /* parent exits */ 
    setsid(); /* create a new session */ 

    /* Every output goes to /dev/null. If Redis is daemonized but 
    * the 'logfile' is set to 'stdout' in the configuration file 
    * it will not log at all. */ 
    if ((fd = open("/dev/null", O_RDWR, 0)) != -1) { 
     dup2(fd, STDIN_FILENO); 
     dup2(fd, STDOUT_FILENO); 
     dup2(fd, STDERR_FILENO); 
     if (fd > STDERR_FILENO) close(fd); 
    } 
} 

documentazione Upstart dice:

expect daemon 
Specifies that the job's main process is a daemon, and will fork twice after being run. 
init(8) will follow this daemonisation, and will wait for this to occur before running 
the job's post-start script or considering the job to be running. 
Without this stanza init(8) is unable to supervise daemon processes and will 
believe them to have stopped as soon as they daemonise on startup. 

expect fork 
Specifies that the job's main process will fork once after being run. init(8) will 
follow this fork, and will wait for this to occur before running the job's post-start 
script or considering the job to be running. 
Without this stanza init(8) is unable to supervise forking processes and will believe 
them to have stopped as soon as they fork on startup. 

così mi sia disattivare daemonization sul lato Redis, o provare a utilizzare aspettarsi forchetta piuttosto che aspettare daemon in configurazione iniziale.

+0

Grazie per la risposta. Le mie ricerche strazianti e l'osservazione normale suggeriscono che Redis si biforca due volte. Leggendo il codice, non vedo come sia possibile, ma in qualche modo sembra. Inoltre, ho provato "expect fork" e questo non ha portato alla ricerca del PID corretto. Avevo visto Gist, ma non ci si può mai fidare che altri abbiano fatto i compiti a fondo per arrivare al problema di fondo. Presumo che la demonizzazione sia fuori questione con Upstart. –

+0

Ho appena provato una semplice strace -f/Redis server src redis.conf 2> strace.log su un'istanza daemonized, e lo fa forchetta solo una volta. Nota: su Linux, la chiamata al sistema clone viene utilizzata per creare sia processi che thread (e Redis utilizza ora un paio di thread in background). I parametri dovrebbero chiarire se si tratta di un thread o di un processo. Peccato che "expect fork" non funzioni come ci aspetteremmo ... –

+0

Ok, grazie per aver confermato che è un singolo fork. Ho sicuramente provato "expect fork" senza successo, ma potrei farne un altro per assicurarmi. Ti riporto. –

6

Il seguente configurazione upstart sembra funzionare per me, con upstart 1.5 su Ubuntu 12.04, con redis.conf demonizzare impostato su yes:

description "redis server" 

start on (local-filesystems and net-device-up IFACE=eth0) 
stop on shutdown 

setuid redis 
setgid redis 
expect fork 

exec /opt/redis/redis-server /opt/redis/redis.conf 

respawn 
+0

Grazie Mike, questo funziona per me. –

+0

Script funziona per me, ma ancora TBD per convincerlo a giocare bene con Monit ... –