java - 由 tomcat7 暂停产生的进程

标签 java tomcat servlets jruby delayed-job

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

过程:

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

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

当我重新启动服务器时,一个条目被放入日志中,表明发送了关闭信号。 Worker 醒来,完成一项工作(如果它在执行期间暂停)并退出。

当我在 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

最佳答案

问题在于,当运行外部进程时,您必须从子进程中读取stdoutstderr 流。否则,当输出缓冲区填满时,进程实际上会在 I/O 写入 block 上暂停。

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

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

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

关于java - 由 tomcat7 暂停产生的进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47797038/

相关文章:

java - 我的 JavaCC 文本解析器中缺少什么?

java - 如何在 jar 文件中使用 ClassLoader.getResources()

java - 调试问题关闭 Apache Tomcat

jsp - Tomcat 超时?

java - 在一个项目中放置 4 个 servlet

java - 处理ajax请求并发送响应java servlet

java - 尝试在空对象引用上调用接口(interface)方法 'boolean java.util.Set.addAll(java.util.Collection)'

java - jackson JsonNode 到带有排序键的字符串

java - 无法在 Tomcat 服务器上创建文件

java - 无法转发。响应已提交。错误