Multithreading 长时间运行的后台线程导致HTTP请求超时

Multithreading 长时间运行的后台线程导致HTTP请求超时,multithreading,tomcat,Multithreading,Tomcat,我有一个在Tomcat7上运行的Spring3.0WebMVC应用程序。在应用程序启动时,我启动一个后台线程来加载内存缓存,其中包含来自数据库的记录。该线程从数据库加载所有数据通常需要一个多小时。在同一个应用程序中,我有一个@Controller注释类,它公开了一个REST接口,客户端可以通过该接口从加载的缓存中获取对象 我们的要求之一是,在数据加载完成之前发出的任何REST请求都将立即向客户端返回一个SERVICE_UNAVAILABLE(503)HTTP代码。为了实现这一点,我设置了一个简单

我有一个在Tomcat7上运行的Spring3.0WebMVC应用程序。在应用程序启动时,我启动一个后台线程来加载内存缓存,其中包含来自数据库的记录。该线程从数据库加载所有数据通常需要一个多小时。在同一个应用程序中,我有一个@Controller注释类,它公开了一个REST接口,客户端可以通过该接口从加载的缓存中获取对象

我们的要求之一是,在数据加载完成之前发出的任何REST请求都将立即向客户端返回一个SERVICE_UNAVAILABLE(503)HTTP代码。为了实现这一点,我设置了一个简单的布尔标志检查,控制器中的每个请求方法在执行任何工作之前都会进行布尔标志检查。如果该值为false,则该方法应立即返回503代码。加载程序线程将在加载完成后将标志设置为true,以允许请求方法正常工作


问题是,后台线程似乎导致发送到我的控制器的所有HTTP请求在30秒后超时,而不是点击该标志并立即向客户端返回503代码。我不是Tomcat线程问题的专家,我想知道我在创建长时间运行的后台线程时是否做错了什么?我基本上是使用“implements Runnable”方法创建线程,如前面所述,并在包含bean的初始化上启动线程。有没有更好的方法在Tomcat内部启动一个长时间运行的后台线程而不干扰请求处理?还是我还缺少什么?

如果我是你,我会做一些不同的事情:

  • 查看是否要使用外部缓存。在过去,我在使用伏地魔项目()方面取得了一些成功,还有其他的选择
  • 如果将缓存外部化,则重新启动Tomcat将不需要重新加载缓存
  • 构建一个单独的应用程序,其任务是加载缓存
  • 如果要查找的条目在缓存中不可用,请通过直接从数据库中查找来查看是否要处理该请求
  • 不要在像Tomcat这样的应用程序容器中使用自己的线程。Tomcat内置了自己的线程管理逻辑,创建用户线程是个大问题

  • 如何同步对布尔标志的访问?@DavidSchwartz该标志是内存缓存中的一个值,请求方法通过缓存DAO对象检查该值。加载程序线程只是在通过同一个缓存DAO对象完成时更新这个缓存值,我认为它是线程安全的(不是100%确定);它不会在加载完成之前访问它,所以我认为这不是一个问题?与其污染每一个服务,仅仅实现一个过滤器不是更容易和更好地维护吗?诚然,这并不能解决您所问的问题,但可能会将问题简化为一个单一的交互位置。我很好奇您是否有参考资料支持您在#5中的说法……在运行Tomcat的web应用程序中创建用户线程不是一个好主意?我记得读过Rod Johnson的书,不幸的是,我无法追踪它。此外,我在我们的项目中也看到,作为请求处理的一部分启动的线程导致系统停止生产。我找到了讨论此主题的链接: