tomcat7暂停生成的进程

时间:2017-12-13 15:44:12

标签: java tomcat servlets jruby delayed-job

我有简单的ServletContextListener,它在tomcat启动时运行一个进程,在tomcat关闭时关闭它。

过程:

java -jar application.war -S rake jobs:work

它产生了一个处理队列的ruby delayed_job工作者。但是,当需要处理大量工作或工作需要一段时间时,就会出现问题。它会处理一些然后它就会停止。没有错误被抛出,日志中没有任何内容。它只是暂停执行。

当我重新启动服务器时,会在日志中输入一个已发送关闭信号的条目。工作人员醒来,完成一项工作(如果在执行期间暂停)并退出。

当我在tomcat7之外运行该命令时,它按预期正常工作。

ServletContextListener代码:

public class RakeServlet implements ServletContextListener
{
  private Process workerProcess;

  @Override
  public void contextInitialized(ServletContextEvent event)
  {
    workerProcess = Runtime.getRuntime().exec("java -jar application.war -S rake jobs:work");
  }

  @Override
  public void contextDestroyed(ServletContextEvent event)
  {
    workerProcess.destroy();
  }
}

ps aux输出:

tomcat7   2119  0.5 16.9 3479300 668704 ?      Sl   02:20   2:41 java -jar application.war -S rake jobs:wor

1 个答案:

答案 0 :(得分:0)

问题是,在运行外部进程时,必须从子进程中读取stdoutstderr个流。否则,当输出缓冲区填满时,该进程会在I / O写入块上有效地暂停。

为了正确地执行此操作,您需要启动一些线程来监视这些流并清空它们(可能是对输出执行一些有用的操作而不是简单地丢弃它)。

有关详细信息,请查看Steve Liles's blog post on the subject,其中描述了问题以及解决方案的示例。

如果目标进程实际上是另一个Java进程,则应该考虑在进程中运行Java代码,以避免启动第二个JVM的开销以及与之通信的复杂性(即stdio流)。