在会话到期之前,在HttpSession中启动一个进程并将其交给另一个“所有者”?

时间:2012-03-06 13:21:48

标签: java session runtime.exec

我(正在尝试)开发一个Web应用程序系统,它处理用户请求和计算,并通过扩展Threads和Runtime.exec()(在Linux和/或Windows上)将它们传递给服务器上的(定制的)可执行文件)。这些计算可能非常耗时,并且可能超过HttpSession的持续时间。如果发生这种情况,并且会话到期,则线程/进程也会与HttpSession一起消失(对吗?)。

我的问题:例如,有没有办法在会话中启动进程并将其切换到与会话无关的进程?

如果我无法跟踪进程ID并不重要,我只搜索在Web服务器上启动进程并让它们运行的​​方法,即使用户的会话到期也是如此。

我很感谢任何想法和提示!

2 个答案:

答案 0 :(得分:1)

您应该使用像Quartz这样的作业调度库,这样您的作业就完全不依赖于Http Session

答案 1 :(得分:1)

我不建议通过Runtime.exec启动进程或从Web服务器内部创建新线程。虽然技术上通常是可行的,但这不是一个好主意。基本上,您启动的线程不会受Web容器控制(它有许多工作线程来处理您的请求)。通过启动自己的线程,Web服务器无法再管理自己的负载,最终可能会产生一系列意想不到的后果。

我将做的是以下内容:

  • 当有新计算的请求进入时,我会创建一个唯一的ID,并将其作为“计算待定”存储在数据库中,并带有用户ID。
  • 然后我会打包请求的数据并将其放在JMS队列上以便计划进行计算。
  • 您的网络容器可以将该ID返回到网络浏览器。
  • 网络浏览器可以使用该ID返回到“是否已完成计算ID?”的Web服务器。服务器可以检查数据库并查看状态是否仍处于“挂起”状态。
  • 在您的网页上,您可以显示一些“处理...”消息和一个进度条,它会定期刷新并检查计算是否仍在进行(比如每10秒刷新一次)。这样可以保持你的HttpSession活着(虽然没有必要,因为用户可以再次登录并检查ID,或者如果你在DB记录中存储了用户名,可以看到所有用户的“待定”计算)。
  • 计算将由一个单独的应用程序执行,该应用程序基本上侦听JMS / MQ队列上的传入消息,然后创建一个新线程。现在,这可以在同一台机器或不同的机器上(使用JMS可以灵活地使用JMS配置,或者多个“工人”机器监听JMS消息来执行计算。
  • 计算完成后,“worker”将打包结果并发送JMS响应消息(包括ID)。
  • 回到您的服务器上,您就可以拥有一个消息驱动的bean,它将结果插入到数据库中,并将数据库的状态更改为“已完成”并使结果可用。
  • 现在,当网页刷新时,由于结果可用,您可以重定向到结果页面(并从数据库中获取结果)。

使用JMS的优点:

  • 如果出现问题,可以保留消息,重新发送消息。
  • 符合Java EE规范

将计算结果存储在DB中的优点:

  • 查看历史计算
  • 如果计算是幂等的,您可以查看以前计算的结果。

希望有所帮助。