Tomcat 的 Catalina 实用程序线程定期使用高 CPU 和内存

Tomcat's Catalina utility threads are periodically using high CPU and memory

我们有一个网络应用程序,在空闲时平均使用 20% CPU,没有网络流量或任何类型的请求。 它在 Java 11、Tomcat 9、Spring Framework 5.3、Hibernate 5.4 上 运行。 然而,我将在下面描述的问题在 Java 8、Tomcat 8.5、Spring 4.3 和 Hibernate 4 上也是如此。 我尝试使用 JFR 和 JMC 来分析应用程序,并尝试了很多配置。 在上图中,catalina-utility-1 和 catalina-utility-2 线程似乎会周期性地唤醒,并在几秒钟内使用大量 CPU。 此外,这些线程似乎进行了大量内存分配,在采样的 5 分钟间隔内总共分配了 30+ GB。

对于此分析,我已将 JFR 配置为最多记录所有内容,并启用所有选项。

当我试图通过查看 Method Profiling 详细信息来深入了解细节时,我观察到它似乎与 org.apache.catalina.webresources.Cache.getResource().

有关

所以我开始阅读有关 Tomcat 缓存的内容,并尝试通过 context.xml 文件来调整不同的参数,如下所示:

<Context>
  <!-- Default set of monitored resources. If one of these changes, the    -->
  <!-- web application will be reloaded.                                   -->
  <WatchedResource>WEB-INF/web.xml</WatchedResource>
  <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
  <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
  <!-- Uncomment this to disable session persistence across Tomcat restarts -->
  <!--
    <Manager pathname="" />
    -->
  <Resources cachingAllowed="true" cacheMaxSize="3024000" cacheObjectMaxSize="10240" cacheTtl="10000"/>
</Context>

在这个用于 JFR 分析的特定示例中,我将缓存大小增加到 3GB,cacheTtl 增加到 10 秒。我认为更大的缓存和更大的 TTL 会影响 CPU 尖峰的间隔,因为我怀疑 Tomcat 每 5 秒检查一次缓存(最初大小为 1G),这是默认设置。 但是,无论我为缓存大小或 ttl 设置什么值,周期性 CPU 尖峰都是相同的。 缓存大小足以容纳 Tomcat 想要放入其中的任何内容,因为在我们看到日志中的警告后我增加了该值。无论如何,1GB 足以摆脱警告。

我还尝试了 1 到 5GB 的堆大小,上面的分析是使用 5GB 的堆大小完成的。如果不开始达到物理内存限制,我真的不能超过这个值。

从 Java 8 天开始,我们就使用 G1GC 作为我们的垃圾收集器。调整其参数不会影响 CPU 的使用。 我还尝试了 ParallelGC 和 SerialGC,但 CPU 使用模式保持不变。

搜索 Google 此类问题没有结果,我完全陷入了我还能尝试什么或我还应该看什么的问题。

欢迎提出任何建议。谢谢。


更新 1:

似乎我最初遇到了格式问题,并且在解析时 context.xml 中缺少起始 <context> 标记。已修复。

我也尝试过,按照 <Context reloadable="false"> 的建议,将 reloadable 明确设置为 false。完全没有效果。

是否可以从其他地方设置可重新加载标志?我推测即使在 context.xml 中它被设置为 false.

也可能有其他文件或设置应用它

图像中的堆栈跟踪包含对 Loader#modified 的调用,并且只有在将上下文的 reloadable 属性 设置为 true 时才有可能:

<Context reloadable="true">
...
</Context>

Tomcat's documentation所述:

Set to true if you want Catalina to monitor classes in /WEB-INF/classes/ and /WEB-INF/lib for changes, and automatically reload the web application if a change is detected. This feature is very useful during application development, but it requires significant runtime overhead and is not recommended for use on deployed production applications. That's why the default setting for this attribute is false.

(强调我的)。

reloadable 设置为 false(或删除该属性)以消除开销。