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

发布于 2024-12-24 02:23:20 字数 430 浏览 1 评论 0原文

我为 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.conf 将 redis 配置为:

daemonize yes

所有文档和我自己的实验都说 Redis 以守护进程形式分叉两次,并且“期望守护进程”应该可以工作,但 Upstart 脚本是始终保留前一个父级的 PID (PID - 1)。有人让这个工作吗?

I've written an Upstart script for Redis as follows:

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

I then configure redis via it's redis.conf to:

daemonize yes

All the documentation and my own experimentation says Redis forks twice in daemonized form and "expect daemon" should work, but the Upstart script is always holding on to the PID of the former parent (PID - 1). Has anyone got this working?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

轻拂→两袖风尘 2024-12-31 02:23:20

以下 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

The following upstart config seems to be working for me, with upstart 1.5 on ubuntu 12.04, with redis.conf daemonize set to 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
寒江雪… 2024-12-31 02:23:20

其他人也有同样的问题。请参阅此要点

当 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 端停用守护进程,要么尝试使用 Expect fork 而不是 Upstart 配置中的 Expect Daemon。

Other people have the same problem. See this gist.

When the daemonize option is activated, Redis does not check if the process is already a daemon (there is no call to getppid). It systematically forks, but only once. It is somewhat unusual, other daemonization mechanisms may require the initial check on getppid, and fork to be called twice (before and after the setsid call), but on Linux this is not strictly required.

See this faq for more information about daemonization.

Redis daemonize function is extremely simple:

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 documentation says:

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.

So I would either deactivate daemonization on Redis side, either try to use expect fork rather than expect daemon in upstart configuration.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文