以守护程序形式运行 Redis 并使用 Upstart 对其进行管理不起作用



我为Redis写了一个Upstart脚本,如下所示:

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

我然后配置redis通过它的redis.conf:

daemonize yes

所有的文档和我自己的实验说Redis分叉两次在守护形式和"期望守护进程"应该工作,但Upstart脚本总是坚持前父(PID - 1)的PID。有人得到这个工作吗?

下面的upstart配置似乎为我工作,upstart 1.5在ubuntu 12.04上,与redis.conf daemonize设置为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

其他人也有同样的问题。请看要点。

当daemonize选项被激活时,Redis不会检查进程是否已经是守护进程(没有调用getppid)。它系统地分叉,但只有一次。这有点不寻常,其他守护进程机制可能需要对getppid进行初始检查,并调用fork两次(在setsid调用之前和之后),但在Linux上这不是严格要求的。

有关守护进程的更多信息,请参阅此常见问题解答。

Redis daemonize函数非常简单:

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);
    }
}

Upstart文档说:

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.

所以我要么停用Redis端的守护进程,要么尝试在upstart配置中使用expect fork而不是expect daemon。

最新更新