Linux 线程(进程)数限制分析

栏目: Linux · 发布时间: 6年前

内容简介:公司线上环境出现MQ不能接受消息的异常,原因是一个新同学的代码没有Review直接上线,里面有一个BUG触发了异常创建大量线程。问题解决了,工作之余研究了下Linux 线程数限制

1.问题来源

公司线上环境出现MQ不能接受消息的异常,运维和开发人员临时切换另一台服务器的MQ后恢复。同时运维人员反馈在出现问题的服务器上很多基本的命令都不能运行,出现如下错误:

Linux 线程(进程)数限制分析

2.   初步原因分析和解决

让运维的兄弟在服务上查看内存、CPU、网络、IO等基本信息都正常。于是自己到运维的服务器上看了一下,下面是slabtop –s c的运行结果,问题初步原因貌似出现了:

Linux 线程(进程)数限制分析

如果看到这个截图你看不出什么异常的话,下面的内容你可能不感兴趣,哈哈。。。

task_struct是内核对进程的管理单位,通过slub(slab的升级版,如果你对slub不了解也不影响下面的内容,只要了解slab就行了)进行节点的管理,正常负载的服务不应该出现task_struct的slub结构体占用内存最大的情况,这说明这台服务器上开启了大量的进程(Linux内核态对进程和线程都是一个单位,不要纠结这个,后面可能会进程、线程混用)。

通过这个信息,兄弟们发现这台服务器上有近3万个线程,同时也定位到出问题的网元(一个新同学的代码没有Review直接上线,里面有一个BUG触发了异常创建大量线程)。

问题貌似到这里就结束了,但是作为一个有情怀的程序员,这只是一个开始(哥的情怀白天都被繁琐的工作磨没了,只能在这深夜独享了。。。)

3.   Linux线程数的限制

3.1     应用层测试代码

通过strace跟踪,发现问题出现在copy_process函数,那剩下的工作就是分析copy_process返回异常的原因了。

3.2     逆向分析

这个时候逆向分析最简单直接,可以直接定位到问题原因。

首先通过strace分析,查找出问题的系统调用是clone函数。

SYS_clone—>do_fork—>copy_process。内核态函数的分析 工具 这次试用了systemtap,下面就是没有任何美感的stap代码了,将就着看看吧

发现问题出在alloc_pid失败,分析内核代码,这个受限于kernel.pid_max参数。

Linux 线程(进程)数限制分析
将参数调大到100000后,再次运行。

Linux 线程(进程)数限制分析

继续通过strace跟踪,这次发现问题出在了mprotect函数

Linux 线程(进程)数限制分析

这个问题是由于当个线程的mmap个数限制,受限于vm.max_map_count参数。

Linux 线程(进程)数限制分析

将参数调大到100000后,再次运行,线程数明显增加了。

其实这里面还有一个参数kernel.threads-max限制,由于系统默认将这个参数设置为800000,非常大,所以这个参数的影响一直没有保留出来。

后面又犯贱把相关的参数都设置成800000,结果内存耗尽,系统直接没响应了。。。。

3.3     正向分析

直接分析copy_process代码

copy_process

3.3.1  内存限制

dup_task_struct–>alloc_task_struct_node/alloc_thread_info_node/arch_dup_task_struct–>kmme_cache_alloc_node(slub.c)–>slab_alloc_node–>

“CONFIG_MEMCG_KMEM” //这里也是一个坑,docker这种基于cgroup的也会影响,可能会因为分配给slub的内存不够用出现线程限制

具体函数:

alloc_pages—->__memcg_kmem_newpage_charge–>memcg_charge_kmem–>__res_counter_charge–>res_counter_charge_locked

3.3.2  Threads-max参数限制

if (nr_threads >= max_threads) // threads-max 参数影响

3.3.3  Pid_max参数限制

alloc_pid–>alloc_pidmap //pid_max参数影响

3.3.4  单进程内存限制

单个进程的线程数,受限于vm.max_map_count限制

4.   总结

/proc/sys/kernel/pid_max #操作系统线程数限制

/proc/sys/kernel/thread-max  #操作系统线程数

max_user_process(ulimit -u) #系统限制某用户下最多可以运行多少进程或线程

/proc/sys/vm/max_map_count #单进程mmap的限制会影响当个进程可创建的线程数

/sys/fs/cgroup/memory/${cgroup}/memory.kmem #单个 docker 内核内存的限制,可以影响task_struct等slab节点的申请,间接影响可创建的线程数


以上所述就是小编给大家介绍的《Linux 线程(进程)数限制分析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Introduction to Computation and Programming Using Python

Introduction to Computation and Programming Using Python

John V. Guttag / The MIT Press / 2013-7 / USD 25.00

This book introduces students with little or no prior programming experience to the art of computational problem solving using Python and various Python libraries, including PyLab. It provides student......一起来看看 《Introduction to Computation and Programming Using Python》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具