java - Spring 应用程序消耗所有 CPU 然后崩溃

标签 java spring garbage-collection

我有一个 Spring 应用程序,最近已从测试环境转移到生产环境。大多数时间 CPU 使用率为 %2-3。但有时(每天 1 或 2 次)它突然达到 %400(有 4 个 CPU)的峰值,然后我的应用程序崩溃了。问题发生时,我无法观察到任何异常情况(例如额外的流量)。

关于我的应用的一些信息是,

  • 它有一些由 android 客户端调用的 REST 端点。
  • 其中一个 Service 中有 3 个 ScheduledTask。他们制作了一些 HttpUrlConnection
  • 我的流量不是很大,例如每分钟 300-400 个请求并且它大部分是稳定的,即在网络调用中没有观察到峰值。
  • 此流量的 CPU 使用率达到最大值 %3,出现问题的次数除外。这是过去 24 小时 CPU 利用率的可视化: enter image description here
  • 我的服务器有 4 核 cpu、12 GB RAM 和 300GB 全固态硬盘。 Linux 版本 4.4.0-93-generic (buildd@lgw01-03) (gcc 版本 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4) )
  • 内存设置:-d64 -Xms6g -Xmx10g -XX:MaxPermSize=512m
  • 我使用 sysstat 进行日志记录。我不仅在观察整个系统的 cpu 和 ram 使用情况,而且还在观察我的应用程序的使用情况。我还想指出,ram 使用率最高可达 %60。
    An example from CPU logs GC 日志和线程转储: 我以 2 分钟的间隔记录了 GC 和线程转储 (jstack)。正常时间、崩溃前和崩溃时没有显示差异。
  • 记录时间:20:30 - 06:26
  • 服务器崩溃时间:06:26
  • GC Analysis
  • Thread dumps ( 线程转储 1 (05:40) .. 线程转储 14 (06:24) ) (其他线程转储在 05:40 之前)
  • GC 分析评论:“97.14% 的时间是由于分配失败。但它的时间是崩溃前 9 小时的 21:12:22。”
  • 日志文件中的最后错误
    • 2017-10-09 06:26:19.393 ERROR 5986 --- [XNIO-2 task-1] t.o.m.w.rest.errors.ExceptionTranslator:发生意外错误:读取输入消息时出现 I/O 错误;嵌套异常是 java.io.InterruptedIOException: XNIO000808: I/O 操作被中断
    • 2017-10-09 06:26:19.396 ERROR 5986 --- [XNIO-2 task-25] io.undertow.request:UT005022:异常生成错误页面/error

我找不到问题的原因。有什么建议吗?感谢任何形式的帮助。

最佳答案

正如宝贵的评论所指出的,这个问题并非源于垃圾回收。原因完全不同。花了大约一周的时间才弄明白,所以我把它写在这里,以防其他人遇到同样的问题。

首先,我没有在问题中包含(因为我认为它不重要)我使用了 JHipster ,最近切换到 Undertow 作为应用程序服务器。

深入了解后,我观察到消耗CPU的线程是XNIO线程。我在一些站点上看到,一些使用由 XNIO 提供支持的应用程序服务器的人也遇到了同样的问题。由于Undertow使用的是XNIO,所以我把Undertow改成了Tomcat,问题就解决了。

关于java - Spring 应用程序消耗所有 CPU 然后崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46648242/

相关文章:

node.js - 在高负载下,Node.js 的可伸缩性是否会因为垃圾收集而受到影响?

Java解密加密兼容SJCL?

java - Spring 启动 : switch between embedded and postgresql datasources by changing a flag

spring - 使用@RequestParam 时出错但用作参数 Java/Spring 时不出错

Java Spring Controller 未被映射

java - 在没有 -XX 的情况下卸载标准输出日志中的类消息 :+CMSClassUnloadingEnabled

java - 为什么我不能设置不同包中类似类的对象列表

java - 使用 Java 应用程序打开文件

java - Robocode 中的单例模式

使用应用程序在密集内存中进行 C# 垃圾收集