linux 出错 “INFO: task java: xxx blocked for more than 120 seconds.” 的3种解决方案

2023-11-08 20:50

本文主要是介绍linux 出错 “INFO: task java: xxx blocked for more than 120 seconds.” 的3种解决方案,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1 问题描述

最近搭建的一个linux最小系统在运行到241秒时在控制台自动打印如下图信息,并且以后每隔120秒打印一次。 
这里写图片描述

仔细阅读打印信息发现关键信息是“hung_task_timeout_secs”,第一次遇到这样的问题,首先百度…

通过翻看多个网友的博客,发现这是linux kernel的一个bug。大家对这个问题的解释也都比较一致,摘抄一段:

By default Linux uses up to 40% of the available memory for file system caching. 
After this mark has been reached the file system flushes all outstanding data to disk causing all following IOs going synchronous. 
For flushing out this data to disk this there is a time limit of 120 seconds by default. 
In the case here the IO subsystem is not fast enough to flush the data withing 120 seconds. 
This especially happens on systems with a lot of memory. 
The problem is solved in later kernels。

翻译过来就是:一般情况下,linux会把可用内存的40%的空间作为文件系统的缓存。当缓存快满时,文件系统将缓存中的数据整体同步到磁盘中。但是系统对同步时间有最大120秒的限制。如果文件系统不能在时间限制之内完成数据同步,则会发生上述的错误。这通常发生在内存很大的系统上。系统内存大,则缓冲区大,同步数据所需要的时间就越长,超时的概率就越大。

2 解决办法

网友们提供的解决方案大致有3种,分别对3种方案的效果进行验证测试。

2.1 缩小文件系统缓存大小

此种方案是降低缓存占内存的比例,比如由40%降到10%,这样的话需要同步到磁盘上的数据量会变小,IO写时间缩短,会相对比较平稳。

文件系统缓存的大小是由内核参数vm.dirty_ratio 和 vm.dirty_backgroud_ratio控制决定的。

vm.dirty_background_ratio指定当文件系统缓存脏页数量达到系统内存百分之多少时(如5%)就会触发pdflush/flush/kdmflush等后台回写进程运行,将一定缓存的脏页异步地刷入外存。

vm.dirty_ratio则指定了当文件系统缓存脏页数量达到系统内存百分之多少时(如10%),系统不得不开始处理缓存脏页(因为此时脏页数量已经比较多,为了避免数据丢失需要将一定脏页刷入外存),在此过程中很多应用进程可能会因为系统转而处理文件IO而阻塞。

通常情况下,vm.dirty_ratio的值要大于vm.dirty_background_ratio的值。

下面说一下修改这两个参数的流程及效果。

(1)首先查看系统当前的vm.dirty_ratio 和 vm.dirty_ background_ratio的值。

在shell命令行中输入如下指令:

<span style="color:#000000"><code>sysctl -a | grep dirty</code></span>
  • 1

这里写图片描述 
由上图可知,当前环境下,vm.dirty_ratio=20 ,vm.dirty_ background_ratio=10。在此情况下,会出现上述问题。

(2)修改vm.dirty_ratio和vm.dirty_ background_ratio的值。 
把vm.dirty_ratio修改为10 ,vm.dirty_background_ratio修改为5。在命令行输入如下命令:

<span style="color:#000000"><code>./sbin/sysctl -w vm<span style="color:#009900 !important">.dirty</span>_ratio=<span style="color:#006666 !important">10</span>
./sbin/sysctl -w vm<span style="color:#009900 !important">.dirty</span>_background_ratio=<span style="color:#006666 !important">5</span></code></span>
  • 1
  • 2

这里写图片描述 
(3)查看修改是否成功。

在命令行输入(1)中的指令即可。 
这里写图片描述 
由上图可知,参数修改成功。

(4)使参数修改立即生效。

在命令行输入如下指令即可。

<span style="color:#000000"><code>sysctl  <span style="color:#50a14f">-p</span></code></span>
  • 1

(5)观察测试结果。

经过以上操作,缩减文件系统缓存之后,上述问题成功解决。

2.2 修改系统IO调度策略

Linux的IO共有三种调度器:CFQnoopdeadline。每个调度器都有其优点。

CFQ (Completely Fair Scheduler(完全公平调度器))(cfq):它是许多Linux 发行版的默认调度器;它将由进程提交的同步请求放到多个进程队列中,然后为每个队列分配时间片以访问磁盘。

Noop调度器(noop):基于先入先出(FIFO)队列概念的Linux内核里最简单的I/O调度器。此调度程序最适合于SSD。

截止时间调度器(deadline):尝试保证请求的开始服务时间。

Linux发行版的默认采用的是cfq调度器。此方案就是把cfq调度器修改为最简单的noop调度器

下面说一下修改调度器的流程。

(1)查看当前采用的调度器。

在命令行中输入如下指令:

<span style="color:#000000"><code>cat /sys/<span style="color:#000088 !important">block</span>/sda/queue/scheduler</code></span>
  • 1

这里写图片描述 
由内核返回信息可知,当前采用的是cfq调度器。

(2)修改调度器。

在命令行中输入如下指令:

<span style="color:#000000"><code>echo noop ><span style="color:#008800 !important">/sys/block</span><span style="color:#008800 !important">/sda/queue</span><span style="color:#008800 !important">/scheduler</span></code></span>
  • 1

这里写图片描述 
(3)查看修改是否成功。

在命令行中输入如(1)的指令。 
这里写图片描述 
由内核返回信息可知,调度器修改成功。

调度器的修改是立即生效的,不必重启内核。

(4)观察测试结果。

修改完成后,让系统继续运行一段时间。上述问题依然存在。所以此方案对本文的案例不起作用。对于其他案例是否起作用需要自己按照上述方式测试才能得知。

2.3 取消120秒时间限制

此方案就是不让系统有那个120秒的时间限制。文件系统把数据从缓存转到外存慢点就慢点,应用程序对此延时不敏感。就是慢点就慢点,我等着。实际上操作系统是将这个变量设为长整形的最大值。

下面说一下内核hung task检测机制由来。我们知道进程等待IO时,经常处于D状态,即TASK_UNINTERRUPTIBLE状态,处于这种状态的进程不处理信号,所以kill不掉,如果进程长期处于D状态,那么肯定不正常,原因可能有二:

1)IO路径上的硬件出问题了,比如硬盘坏了(只有少数情况会导致长期D,通常会返回错误);

2)内核自己出问题了。

这种问题不好定位,而且一旦出现就通常不可恢复,kill不掉,通常只能重启恢复了。 
内核针对此种情况开发了一种hung task的检测机制,基本原理是:定时检测系统中处于D状态的进程,如果其处于D状态的时间超过了指定时间(默认120s,可以配置),则打印相关堆栈信息,也可以通过proc参数配置使其直接panic。

如何修改或者取消120秒的时间限值呢。120秒的时间限值由内存参数kernel.hung_task_timeout_secs决定的。直接像方案一那样修改此内核参数的值就可。如果kernel.hung_task_timeout_secs的值设置为0,那就是把此种设置为长整型的最大值。

下面说一下修改调度器的流程。

(1)查看当前hung_task_timeout_secs值。

在命令行中输入如下指令:

<span style="color:#000000"><code>sysctl -a | grep hung_task_timeout_secs</code></span>
  • 1

这里写图片描述

有内核返回信息,可知当前设置的hung_task超时时间为120秒。

(2)修改hung_task_timeout_secs值。

把hung_task_timeout_secs的值修改为0,在命令行中输入如下指令:

<span style="color:#000000"><code><span style="color:#50a14f">
./sbin/sysctl -w kernel.hung_task_timeout_secs</span>=<span style="color:#009900 !important">0</span></code></span>
  • 1
  • 2

这里写图片描述

(3)查看修改是否成功。

在命令行输入(1)中的指令即可。 
这里写图片描述

(4)使参数修改立即生效。

在命令行输入如下指令即可。

<span style="color:#000000"><code>sysctl  <span style="color:#50a14f">-p</span></code></span>
  • 1

(5)观察测试结果。 
经过以上操作,取消120秒时间限值之后,上述问题成功解决。

2.4 总结 
经过上边的测试,可知对与本案例缩减文件系统缓冲大小和取消120秒时间限值均可以解决问题。但是取消120秒的时间限值会允许系统不可切换任务的出现。综合考虑决定采用方案1,即缩减文件系统的缓冲区大小。

3 永久修改内核参数

在上述方案中采用sysctl可以修改内核参数,但是这只是临时修改,上电重启后又会恢复回之前的参数。那么如何才能够永久修改内核参数呢?

可以修改系统信息配置文件sysctl.conf,此配置文件在/etc目录下。打开配置文件在最后添加如下两行代码:

<span style="color:#000000"><code>vm<span style="color:#009900 !important">.dirty</span>_background_ratio=<span style="color:#006666 !important">5</span>
vm<span style="color:#009900 !important">.dirty</span>_ratio=<span style="color:#006666 !important">10</span></code></span>
  • 1
  • 2

这里写图片描述 
保存后重启系统,查看配置是否成功。

如果系统没有sysctl.conf文件,就像我的最小linux系统一样,则可以自己创建sysctl.conf。

在/etc目录下,采用vi指令:vi sysctl.conf新建sysctl.conf文件,然后输入如下代码后保存退出。

重启之后查看vm.dirty_ratio和vm.dirty_background_ratio的值,发现又恢复成之前的了。

这是因为开机启动时系统没有读取sysctl.conf文件进行配置。可以通过修改启动文件来解决。

以我使用的linux系统为例,启动文件是/etc/init.d/rcS。采用指令vi /etc/init.d/rcS打开rcS文件,在最末尾添加如下代码:./sbin/sysctl -p 
这里写图片描述

保存后退出。reboot重启可以看到内核打印信息中有如下信息: 
这里写图片描述 
进入控制台后,查看vm.dirty_ratio和vm.dirty_background_ratio的值,可知内核参数永久修改成功。

【参考】 
1、Linux Kernel Crash–hung_task_timeout_secs 作者:李子无为 
http://blog.csdn.net/napolunyishi/article/details/17576739 
2、How to fix hung_task_timeout_secs and blocked for more than 120 seconds problem 作者:skate 
http://blog.csdn.net/wyzxg/article/details/44236263 
3、关于修改 sysctl.conf,如何使该文件在系统重启之后生效 作者:dagebudagegeda 
http://blog.csdn.net/u010616985/article/details/44563931 
4、文件系统缓存dirty_ratio与dirty_background_ratio两个参数区别 作者:vincent 
http://blog.sina.com.cn/s/blog_448574810101k1va.html 
5、一次内核hung task分析 作者:humjb_1983 
http://blog.chinaunix.net/uid-14528823-id-4406510.html

 

转自:https://blog.csdn.net/electrocrazy/article/details/79377214  以做记录

这篇关于linux 出错 “INFO: task java: xxx blocked for more than 120 seconds.” 的3种解决方案的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/372442

相关文章

Spring boot整合dubbo+zookeeper的详细过程

《Springboot整合dubbo+zookeeper的详细过程》本文讲解SpringBoot整合Dubbo与Zookeeper实现API、Provider、Consumer模式,包含依赖配置、... 目录Spring boot整合dubbo+zookeeper1.创建父工程2.父工程引入依赖3.创建ap

Linux线程之线程的创建、属性、回收、退出、取消方式

《Linux线程之线程的创建、属性、回收、退出、取消方式》文章总结了线程管理核心知识:线程号唯一、创建方式、属性设置(如分离状态与栈大小)、回收机制(join/detach)、退出方法(返回/pthr... 目录1. 线程号2. 线程的创建3. 线程属性4. 线程的回收5. 线程的退出6. 线程的取消7.

Linux下进程的CPU配置与线程绑定过程

《Linux下进程的CPU配置与线程绑定过程》本文介绍Linux系统中基于进程和线程的CPU配置方法,通过taskset命令和pthread库调整亲和力,将进程/线程绑定到特定CPU核心以优化资源分配... 目录1 基于进程的CPU配置1.1 对CPU亲和力的配置1.2 绑定进程到指定CPU核上运行2 基于

SpringBoot结合Docker进行容器化处理指南

《SpringBoot结合Docker进行容器化处理指南》在当今快速发展的软件工程领域,SpringBoot和Docker已经成为现代Java开发者的必备工具,本文将深入讲解如何将一个SpringBo... 目录前言一、为什么选择 Spring Bootjavascript + docker1. 快速部署与

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

Linux下删除乱码文件和目录的实现方式

《Linux下删除乱码文件和目录的实现方式》:本文主要介绍Linux下删除乱码文件和目录的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下删除乱码文件和目录方法1方法2总结Linux下删除乱码文件和目录方法1使用ls -i命令找到文件或目录

Spring Boot spring-boot-maven-plugin 参数配置详解(最新推荐)

《SpringBootspring-boot-maven-plugin参数配置详解(最新推荐)》文章介绍了SpringBootMaven插件的5个核心目标(repackage、run、start... 目录一 spring-boot-maven-plugin 插件的5个Goals二 应用场景1 重新打包应用

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控

Linux在线解压jar包的实现方式

《Linux在线解压jar包的实现方式》:本文主要介绍Linux在线解压jar包的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux在线解压jar包解压 jar包的步骤总结Linux在线解压jar包在 Centos 中解压 jar 包可以使用 u