【问题标题】:start-stop-daemon and java - how to do it right?start-stop-daemon 和 java - 怎么做?
【发布时间】:2015-05-14 17:22:35
【问题描述】:

我正在尝试将 java 程序作为服务运行。 我的要求是:

1)在机器启动时启动一个java程序

2)如果java程序崩溃,重启

3)以特殊用户身份在特殊目录下执行

旁注:我不能假设这是唯一运行的 java 进程,并且意外运行该服务两次是很危险的。

到目前为止,我已经尝试使用 start-stop-daemon 来实现它。但是,应用程序在崩溃时不会自动重新启动(即以非零退出代码终止)。我想这有关系,我需要使用 --background ,因此 start-stop-daemon 无法确定退出代码?我对么?如何正确解决此问题? (我更喜欢只有系统功能的解决方案,由于安全限制,没有第三方工具会更容易)

我当前的脚本(Dummy 是一个永远休眠的虚拟 Java 应用程序)

#!/bin/sh
### BEGIN INIT INFO
# Provides:          CI Master
# Required-Start:    $all
# Required-Stop:     $all
# Should-Start:      $portmap
# Should-Stop:       $portmap
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# X-Interactive:     false
# Short-Description: CI Master
# Description:       CI Master
### END INIT INFO

SERVICE_NAME="CI Master"
PIDFILE=/var/run/CI_master.pid
USER=ci
DIRECTORY=./master/
EXECUTABLE=/usr/bin/java
ARGUMENTS="Dummy"

. /lib/lsb/init-functions

case "$1" in
start)
    log_daemon_msg "Starting $SERVICE_NAME" "$SERVICE_NAME"
    start-stop-daemon --pidfile $PIDFILE --make-pidfile --background --chuid $USER --chdir /home/$USER/$DIRECTORY/ --startas $EXECUTABLE --start -- $ARGUMENTS
    log_daemon_msg "$SERVICE_NAME started" "$SERVICE_NAME"
;;
stop)
    log_daemon_msg "Stopping $SERVICE_NAME" "$SERVICE_NAME"
    start-stop-daemon --pidfile $PIDFILE --remove-pidfile --stop
    log_daemon_msg "$SERVICE_NAME stopped" "$SERVICE_NAME"
;;
restart|reload|force-reload)
    $0 stop
    sleep 1
    $0 start
;;
status)
    start-stop-daemon --pidfile $PIDFILE --status
    case $! in
        0)
            log_daemon_msg "$SERVICE_NAME is running" "$SERVICE_NAME"
        ;;
        1)
            log_daemon_msg "$SERVICE_NAME is not running (pid file exists)" "$SERVICE_NAME"
        ;;
        2)
            log_daemon_msg "$SERVICE_NAME is not running" "$SERVICE_NAME"
        ;;
        3)
            log_daemon_msg "unable to determine status of $SERVICE_NAME" "$SERVICE_NAME"
        ;;
    esac
;;
esac
exit 0

提前致谢!

【问题讨论】:

  • 您是否知道您尝试并作为守护进程启动的该程序是否尝试从标准输入读取任何内容/将任何内容写入标准输出和标准错误?我不知道 start-stop-daemon 在这方面是如何工作的,但如果是这种情况,您可能希望将它们全部从 /dev/null 重定向到 /dev/null,除非这些消息对您很重要
  • 它将一堆日志消息写入标准错误。这会在未来引起问题吗?但是,我不认为这会导致我上面描述的这个问题,因为 Dummy 应用程序既不写入也不读取,并且如果我杀死它仍然不会重新启动。
  • 如果默认的stderr是阻塞的,这肯定会导致问题,是的;尝试将 stdout 和 stderr 重定向到专用日志文件。
  • 完成,感谢您的建议。但是,原来的问题仍然存在。

标签: java ubuntu


【解决方案1】:

我建议 DaemonTools + service/chkconfig。

DaemonTools 可能已经安装在您的平台上,或者您可以尝试 apt-get。它会在最多 5 秒内自动重启你的守护进程。

有关 service/chkconfig 的更多信息,您可以查阅 linux 用户手册 8。

希望这有帮助。

【讨论】:

    【解决方案2】:

    我为此使用 Apache Commons Daemon Tools...

    JSvc 将为您重新生成 Java 服务进程...

    Jsvc 使用 3 个进程:一个启动器进程、一个控制器进程和一个受控进程。受控进程也是主java线程,如果JVM崩溃控制器将在下一分钟重新启动它。 Jsvc 是一个守护进程,因此它应该以 root 身份启动,并且 -user 参数允许降级为非特权用户。使用-wait参数时,launcher进程一直等待,直到控制器说“我准备好了”,否则在创建控制器进程后返回。

    JSvc 将写入一个 PID 文件。所以 -stop 命令也可以停止你正在运行的服务。

    JSvc -user 将允许您在启动后将您的服务降级为权限较低的用户。

    它还兼容 ProcRun.exe,在 Windows 上运行良好。

    【讨论】:

      【解决方案3】:

      我可以推荐另一个解决方案 - Java Service Wrapper http://wrapper.tanukisoftware.com/doc/english/introduction.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-25
        • 2012-06-23
        • 2013-04-14
        • 1970-01-01
        • 1970-01-01
        • 2016-07-03
        • 2013-07-24
        • 1970-01-01
        相关资源
        最近更新 更多