以守护程序形式运行Redis并使用Upstart来管理它不起作用

Chr*_*s F 5 daemon upstart redis

我为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
Run Code Online (Sandbox Code Playgroud)

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

daemonize yes
Run Code Online (Sandbox Code Playgroud)

所有文档和我自己的实验都表示Redis以守护进程形式分叉两次并且"expect daemon"应该可以工作,但Upstart脚本始终保持前父级的PID(PID-1).有人有这个工作吗?

Mik*_*enn 6

以下的upstart配置似乎对我有用,ubuntu 12.04上有upstart 1.5,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
Run Code Online (Sandbox Code Playgroud)


Did*_*zia 3

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

当 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

新贵文档说:

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.
Run Code Online (Sandbox Code Playgroud)

因此,我要么在 Redis 端停用守护进程,要么尝试在 upstart 配置中使用 Expect fork 而不是 Expect 守护进程。