Apache jsvc无法停止守护程序。

10

我正在使用本地编译的jsvc来启动Java守护程序,这在一个openSUSE 32位虚拟机上运行。该代码实现了Apache的守护程序接口,并且我正在使用以下命令执行守护进程。

./jsvc -home jre -errfile logs/jsvc.err -pidfile daemon.pid -cp <my_classpath> com.loader.loaderservice.LoaderDaemon

程序可以正常启动和运行。我可以使用普通用户和root用户启动守护进程。但是,当我尝试终止守护进程时,jsvc杀死了该进程而不是发出停止命令。

./jsvc -stop -home jre -outfile logs/jsvc.err -errfile logs/jsvc.err -pidfile daemon.pid -cp <my_classpath> com.loader.loaderservice.LoaderDaemon

守护进程终止,但没有执行任何关闭步骤(例如,记录日志、在数据库中标记记录等)。我在日志/jsvc.err文件中看到以下内容,它不会写入任何其他日志:

Service exit with return value 143
在 Google 了错误之后,我发现许多人都遇到了同样的问题,但是没有找到好的解决方法 (http://mail-archives.apache.org/mod_mbox/commons-dev/200401.mbox/%3CPine.GSO.3.96.1040105133739.23375A-100000@merlot.tel.uva.es%3E, http://www.tek-tips.com/viewthread.cfm?qid=1014679, http://threebit.net/mail-archive/tomcat-users/msg03832.html)。
更新:使用 Apache 的 Windows 服务启动器 (procrun),我可以在没有任何问题的情况下启动和停止服务。问题似乎只与 jsvc 相关,并且仅在停止守护程序时出现。
更新 2:在仔细阅读了http://commons.apache.org/daemon/jsvc.html#Starting_jsvc之后,我注意到我正在使用的 stop 标签通过我指定的 pid 文件向进程发出 kill 命令。看起来 jsvc 实际上并没有设计优雅地停止守护程序。这与我所看到的行为一致,因为非常详细的 stop 方法没有输出任何消息。
-stop        stop the service using the file given in the -pidfile option

新问题:

  • 如果我的Java Main实现了Apache Daemon接口,那么我该如何在运行的守护程序上发出“停止”命令?
  • 除了jsvc(似乎只有启动或杀死守护进程时才有用),我还需要其他东西吗?
1个回答

5
啊,好的。原来jsvc stop命令表现正常。我必须深入了解Linux/Unix中进程通过kill命令接收终止消息的方式。Jsvc在守护程序上发出kill -15(软杀)命令。参见:http://commons.apache.org/daemon/http://en.wikipedia.org/wiki/Kill_(command)以了解unix进程如何接收消息的描述。
真正的问题在于守护程序的构建。在我的启动方法中,守护程序循环直到发出关闭命令,这阻止了守护程序作为守护程序子进程放弃控制。
我有这个:
@Override
public void start() 
{
    doStartWork();
    while (isAlive()) 
    {
        Thread.sleep(1000); 
    }
}

我本应该有以下内容,这样我就可以返回并允许守护线程接收来自操作系统的信号。请参见http://commons.apache.org/daemon/jsvc.html#How_jsvc_works,特别是“受控进程”下的部分。
@Override
public void start() 
{
    doStartWork();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接