【记录】20180829系统超时问题回顾

本文记录了一次线上服务因Groovy动态加载类导致的老年代内存持续减少的问题排查过程,并提供了模拟故障的方法及应对策略。

背景:

       8月29日,凌晨4点左右,某服务告警,其中一个节点直接down掉,收到告警的同事让运维重启。

       9点左右,内存监控上发现内存异常,堆内存涨速很快,即便GC也没有什么效果,频繁GC。

       9点38,服务各种超时,影响整个app使用。

处理方式:

       当时由于很想要堆栈数据,所以没有让运维立即新起服务,切换ip,而是先dump后再重启服务,因为这个,对其他服务造成了更大的影响。

场景模拟:

由于已没有当时dump文件,这里用的模拟的dump文件,需要的同学可根据后面链接中的代码生成,

使用Memory Analyzer分析dump文件,使用介绍:https://blog.youkuaiyun.com/Jin_Kwok/article/details/80326088 ,https://www.jianshu.com/p/759e02c1feee

 

从上图1,图2来看,初步怀疑是ThreadGroupContext有问题,有太多的元素,而这个增长只通过java.beans.ThreadGroupContext#putBeanInfo方法触发。

网上搜索ThreadGroupContext,介绍很少,再往上找是Introspector,怀疑是:Introspector持有BeanInfo的引用,无法回收,导致内存泄漏。见:https://www.jianshu.com/p/b167716f9c0c 

但这里有个疑问是ThreadGroupContext中的是weakHashMap,当GC的时候应该是会被回收的。

从第三张图(按Retained Heap倒序)来看,就明显感觉有问题了,加载了过多的类,没有得到释放,从classLoader来看,应该是groovy动态加载类导致的,网上搜索groovy 内存泄漏,一大片。。见:

https://blog.youkuaiyun.com/jinzhencs/article/details/74562973,由于动态加载类无法释放,将会挤用老年代内存,导致老年代可用内存持续减少,虽然一直GC但是效果甚微。

 

(盗图,java8没有Perm区,而是MetaSpace区)

总结:

       1. 以上是针对不容易复现线上问题的情况,如果方便复现,可以通过jconsole观察,很直观。

       2. 或许线上应该指定-XX:MaxMetaspaceSize,提前报OOM: Metaspace,快速失败,把对外服务的影响降小。

       3. 如果再遇到类似问题,正确的处理方式,应该是立马让运维新起节点,随时准备切换。在提前知道,且自己无法处理的情况下,告知上级或者同事一起解决。

模拟代码:

maven配置
<dependency>
 <groupId>org.codehaus.groovy</groupId>
 <artifactId>groovy-all</artifactId>
 <version>2.4.7</version>
</dependency>
   
模拟代码:
public static void main(String[] args) {
      for (int i = 0; i < 1000000; i++) {
            new GroovyShell().evaluate("\"${0..9}-${0..9}\"");
      }
}
   
jvm参数:
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=OOM.hprof
-Dfile.encoding=UTF-8
-Xms200M
-Xmx200M
-Xmn40M
-XX:+UseParNewGC
-XX:+UseConcMarkSweepGC
-XX:MetaspaceSize=30m
   
   
这里没有设置-XX:MaxMetaspaceSize ,如果设置了,会提前报java.lang.OutOfMemoryError: Metaspace
等执行到5分钟左右就可以自己手动dump了,jmap -dump:format=b,file=fileName pid

 

参考:

          https://juejin.im/post/5b85ea54e51d4538dd08f601  (≈ 深入理解Java虚拟机:JVM高级特性与最佳实践(第二版》)

 

<think> 嗯,用户的问题是关于在Linux系统下配置看门狗超时时间的方法。首先,我需要回顾一下之前提供的引用内容,看看有没有相关信息。 根据引用[1],其中提到可以通过内核参数watchdog_timeout在启动时修改超时时间,单位是秒,且值不受限制。引用[4]中的示例代码展示了在程序中通过ioctl设置超时时间为30秒,同时喂狗周期为29秒。这些是配置的关键点。 接下来,我需要确定用户的使用场景。用户可能在嵌入式系统或服务器环境中工作,需要确保系统的高可用性。看门狗用于监控系统状态,一旦任务失效,系统会自动复位。用户可能是系统管理员或嵌入式开发人员,负责维护系统的稳定性。 用户的真实需求是明确配置超时时间的具体步骤。但深层需求可能包括如何确保配置持久化,避免系统重启后失效,以及如何验证设置是否生效。用户可能还关心不同方法的适用场景,比如动态调整和启动参数的区别。 引用[2]和[3]提到实时系统和多任务环境下的看门狗应用,用户可能需要在复杂环境中部署,因此需要考虑任务调度和喂狗策略,避免因某个任务阻塞导致误复位。此外,引用[4]中的代码示例说明用户可能需要编程层面的指导,比如在C程序中操作看门狗设备。 需要综合这些方法,分步骤说明不同配置方式。同时要强调测试的重要性,比如使用sleep命令触发超时复位,确保配置正确。还要提醒用户喂狗周期的设置必须小于超时时间,否则会导致意外重启。 最后,用户可能没有意识到看门狗在系统dmesg日志中的记录,因此需要包含检查内核日志的步骤,帮助用户确认超时时间是否生效。此外,多任务环境下的喂狗机制设计也是潜在需求,应给出建议,比如独立喂狗任务或分布式喂狗策略。 </think>在Linux系统中配置看门狗超时时间主要有以下三种方法,根据使用场景选择: ### 🔧 方法一:内核启动参数(永久生效) 1. **修改GRUB配置** 编辑配置文件(以Ubuntu为例): ```bash sudo nano /etc/default/grub ``` 2. **添加超时参数** 在`GRUB_CMDLINE_LINUX`行追加: ```bash watchdog_timeout=30 # 单位:秒,此处设为30秒 ``` 3. **更新并重启** ```bash sudo update-grub sudo reboot ``` 4. **验证设置** ```bash cat /proc/cmdline | grep watchdog_timeout ``` > ✅ 此方法需重启系统,适用于需要持久化配置的场景[^1] ### ⚙ 方法二:运行时动态配置(临时生效) 1. **加载看门狗驱动** ```bash sudo modprobe softdog # 以软件看门狗为例 ``` 2. **写入超时值** ```bash echo 30 | sudo tee /sys/class/watchdog/watchdog0/timeout # 设为30秒 ``` 3. **立即生效验证** ```bash cat /sys/class/watchdog/watchdog0/timeout ``` > 💡 此方法无需重启,但系统重启后失效 ### 🖥 方法三:程序控制(开发层面) 通过C程序调用`ioctl`接口(需包含`<linux/watchdog.h>`): ```c #include <fcntl.h> #include <sys/ioctl.h> #include <linux/watchdog.h> int main() { int fd = open("/dev/watchdog", O_WRONLY); int timeout = 45; // 45秒超时 // 设置超时 ioctl(fd, WDIOC_SETTIMEOUT, &timeout); // 喂狗循环(需小于45秒) while(1) { write(fd, "\0", 1); // 喂狗操作 sleep(40); // 喂狗间隔需小于超时时间[^4] } close(fd); return 0; } ``` ### ⚠️ 关键注意事项 1. **喂狗周期** 用户态喂狗间隔**必须小于**超时时间(建议≤80%),例如超时30秒则喂狗间隔≤24秒[^4] 2. **硬件差异** 不同硬件看门狗支持的最大超时值可能不同,需查阅设备文档 3. **多任务系统** 分布式任务需设计协同喂狗机制,避免单任务阻塞导致误复位[^3] 4. **日志监控** 通过`dmesg | grep watchdog`查看看门狗事件记录 > 📌 **操作风险提示**:修改超时时间后务必同步调整喂狗策略,否则可能导致系统意外重启!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值