我们在tomcat中部署了一个Java Web服务应用程序。服务器是3核和7GB RAM。 它在云端,自动扩展,最多可启用20个实例。 在任何给定的时间点,至少1000名用户将同时访问此Web服务。
现在进入Web服务代码,它需要并行处理15种不同的方法(每种方法平均需要3秒),等待所有方法返回响应,处理所有响应并返回输出主叫客户。我们使用带有FixedThreadPool的Java Executor服务。
问题:
最好在Servlet init()方法启动FixedThreadPool执行程序并在servlet destroy中将其关闭,以便线程池初始化一次,应用程序使用此池中的线程
固定线程池大小应该是什么?它是否应该是1k或2k范围内的非常高的数字,因为有多个客户端同时调用Web服务?或者它应该是一个较小的数字?我们应该如何设置一个线程池大小,以便访问Web服务的所有1000个客户端都可以毫不拖延地等待回复响应。
我们应该为我们的场景寻找缓存线程池而不用担心池大小吗?
请帮助。
答案 0 :(得分:1)
最好在Servlet init()方法启动FixedThreadPool执行程序并在servlet destroy中将其关闭,以便线程池初始化一次并且应用程序使用此池中的线程
您当然可以这样做,但更常见的是初始化全局线程池,然后让每个请求共享同一个池。如果优化池中的线程数(见下文),如果每个请求都有自己的池,则很难协调并行执行的请求。
也就是说,如果你需要分叉一些线程然后等待它们完成,那么每个请求使用一个池可能更容易 - 特别是如果这些请求需要很长时间才能运行,这意味着池的创建是整体工作的一小部分。
固定线程池大小应该是什么?
如果没有关于相关工作的更多信息,这是一个非常难以回答的问题。通常,如果请求非常IO绑定,则增加线程数 - 例如,等待网络连接。 1-2k线程可能有效,但如果目标是排队 none ,那么我当然会使用缓存的线程池。
如果要最大化服务器的CPU,那么应该减少线程数,因为您可能同时运行太多作业,这可能会降低整体吞吐量。如果所有15个工作必须同时运行,也应该考虑到这一点。
我们应该如何设置一个线程池大小,以便访问Web服务的所有1000个客户端都能及时回复响应。
添加更多线程并不一定会让事情变得更快。这是关于吞吐量。如果可能,您应该对请求进行建模,或者在生产中尝试一些设置,然后比较每秒的请求等,以确定哪个线程池设置可以产生最高的总吞吐量。
我们应该为我们的场景寻找一个缓存线程池而不用担心池大小吗?
然而,您当然可以担心的是,您将会遇到导致大量线程启动的请求数量的增加。同样,服务器中将运行最佳线程数并处理请求。太多线程不会使作业更快完成,并且由于它们占用资源并增加上下文切换频率,因此可以轻松降低整体吞吐量。