Java 什么时候穿线,什么时候打仗?

Java 什么时候穿线,什么时候打仗?,java,multithreading,tomcat,web-applications,Java,Multithreading,Tomcat,Web Applications,我正在设计/开发一个web应用程序,它最终将作为一场战争部署到Tomcat。此应用程序的一个功能是用户能够将图像上传到我们的服务器并编辑它们(生成缩略图等)。在引擎盖下,我们将使用ImageMagick及其Java适配器库IM4Java 最初的原型显示,每次重新部署应用程序时,ImageMagick都需要一些时间在服务器上“预热”。这促使我们考虑以下两种可能性之一: 创建一个ImageService.warweb服务,该服务与主应用程序一起部署,基本上在后台处理对IM4Java的所有调用(例如

我正在设计/开发一个web应用程序,它最终将作为一场战争部署到Tomcat。此应用程序的一个功能是用户能够将图像上传到我们的服务器并编辑它们(生成缩略图等)。在引擎盖下,我们将使用
ImageMagick
及其Java适配器库
IM4Java

最初的原型显示,每次重新部署应用程序时,ImageMagick都需要一些时间在服务器上“预热”。这促使我们考虑以下两种可能性之一:

  • 创建一个
    ImageService.war
    web服务,该服务与主应用程序一起部署,基本上在后台处理对
    IM4Java
    的所有调用(例如,公开一个RESTful服务,在收到请求时只运行ImageMagick;然后主web应用程序无法在同一本地文件系统上找到编辑的文件);或
  • 只需创建一个
    Thread
    子类(即
    ImageServiceThread
    ),在部署时启动并运行它,并确保在Tomcat取消部署应用程序时关闭它
这两个前景让我从更抽象的意义上思考这个问题:什么时候应该将工作简单地委托给一个单独的线程,什么时候制作一个全面的、单独的应用程序(在我们的例子中是一场战争)

我们的主要应用程序将是这个“图像服务”的唯一用户,这让我认为单独的战争是过分的,没有必要的。但我以前从未在Tomcat内部处理过线程,也不确定是否有可能生成和杀死线程,使其生命周期与主/主应用程序线程的生命周期一致

什么样的因素应被视为此类决策的一部分?提前谢谢

ImageMagick需要一些时间来“预热”

最好将内存/cpu密集型操作卸载到servlet容器之外。实际上,在单独的JVM中启动映像服务


由于应用程序将在内存中加载图像并对其进行编辑,您可以预期频繁的垃圾收集会影响web应用程序其他部分的性能,从而影响servlet容器的性能。

一定要在web应用程序中保留ImageMagick的预加载,这需要它正常运行。这样,您永远不会忘记这两个webapp应该一起部署

将特定Web应用程序所需的所有内容放在一个地方是一个好主意:这就是为什么创建WAR格式以及存在
ServletContextListener
s等内容的原因


老实说,我不确定我是否会费心去“线程化”IM的预加载——只需从
ServletContextListener
运行一些示例命令,并同步加载即可。

您希望在生产中实际重新部署的频率是多少?在开发过程中,为了避免一些不必要的麻烦,似乎需要进行大量的维护。4周的冲刺,因此每月发布一次生产版本,通常为每个生产版本进行2-3次QA构建,就像对最后一部分的评论一样,生成一个线程或类似的线程并在ContextListener中终止它非常容易——您几乎总是希望在上下文侦听器中管理tomcat内部的线程(在contextDestroyed中终止它,并在contextInitialized方法中启动它)。最后,使用执行器来代替创建自己的线程。奇怪的是,IM“需要一些时间来‘预热’”,因为IM4Java总是为IM任务启动单独的进程,所以我能想到的任何延迟的唯一原因是操作系统的内存交换。谢谢@Chris-你能详细说明关于操作系统“内存交换”的最后一条评论吗? 你这是什么意思?如果我没弄错的话,你是在信任一个单独的线程来预加载IM,但这个线程仍然和我的主web应用处于同一场战争中,对吧?我会在你的“主”web应用中这样做,而且我根本不需要使用单独的线程:只需从
ServletContextListener
中启动一些简单的IM任务,并等待它完成,然后再允许webapp完全启动。