记一次排查与解决服务器线程/进程数超限的问题

1、问题复现

1.1 执行docker-compose报错

docker-compose logs -f jdk8

runtime: failed to create new OS thread (have 3 already; errno=12)
fatal error: newosproc

runtime stack:
runtime.throw({0x1f65c1c?, 0x7ffc37e00af0?})
	runtime/panic.go:1047 +0x5d fp=0x7ffc37e00ac8 sp=0x7ffc37e00a98 pc=0x43811d
runtime.newosproc(0xc00009a400)
	runtime/os_linux.go:195 +0x176 fp=0x7ffc37e00b30 sp=0x7ffc37e00ac8 pc=0x4345d6
runtime.newm1(0xc00009a400)
	runtime/proc.go:2253 +0xcf fp=0x7ffc37e00b70 sp=0x7ffc37e00b30 pc=0x43ea4f
runtime.newm(0x745c91f94079f5?, 0xc00006a500, 0x2b97428?)
	runtime/proc.go:2228 +0x12c fp=0x7ffc37e00ba0 sp=0x7ffc37e00b70 pc=0x43e90c
runtime.startm(0xc00006a500, 0x1)
	runtime/proc.go:2411 +0xf3 fp=0x7ffc37e00bf0 sp=0x7ffc37e00ba0 pc=0x43eeb3
runtime.wakep()
	runtime/proc.go:2541 +0xf6 fp=0x7ffc37e00c20 sp=0x7ffc37e00bf0 pc=0x43f496
runtime.newproc.func1()
	runtime/proc.go:4251 +0x53 fp=0x7ffc37e00c48 sp=0x7ffc37e00c20 pc=0x4433d3
runtime.systemstack()
	runtime/asm_amd64.s:496 +0x49 fp=0x7ffc37e00c50 sp=0x7ffc37e00c48 pc=0x469d49

1.2 执行docker info报错

docker info

runtime/cgo: pthread_create failed: Resource temporarily unavailable
runtime/cgo: pthread_create failed: Resource temporarily unavailable
SIGABRT: abort
PC=0x7f28ec617387 m=0 sigcode=18446744073709551610

1.3 执行系统提示报错

1.4 java服务报错

java.lang.OutOfMemoryError: unable to create new native thread

2、问题定位

  1. 查看系统当前【线程/进程】总数

    [root@localhost ~]# ps -eLf | wc -l
    32065
    
    [root@localhost ~]# pstree -p | wc -l
    32040
    
  2. 查看系统进程数限制

    [root@localhost ~]# sysctl kernel.pid_max
    kernel.pid_max = 32768
    
    [root@localhost ~]# cat  /etc/sysctl.conf | grep pid
    kernel.core_uses_pid = 1
    kernel.pid_max = 32768
    
    [root@localhost ~]# cat /proc/sys/kernel/pid_max
    32768
    
  3. 查看当前线程数占用前5的进程信息

    [root@localhost ~]# ps -eo pid,ppid,nlwp,cmd --sort=-nlwp  | head -n 5
    
      PID  PPID NLWP CMD
    27547 27395 7115 java -jar xxx.jar
    27562 27416 6894 java -jar xxx.jar
    27548 27394 6846 java -jar xxx.jar
    45213 45189  345 java -jar xxx.jar
    
  4. 使用 ps -L 查看具体进行的线程使用情况

    [root@VM-0-44-centos translation]# ps -L -p 45213
      PID   LWP TTY          TIME CMD
    45213 45213 ?        00:00:00 java
    45213 45290 ?        00:00:06 java
    45213 45291 ?        00:00:03 java
    45213 45292 ?        00:00:03 java
    45213 45293 ?        00:00:03 java
    45213 45294 ?        00:00:03 java
    45213 45295 ?        00:00:03 java
    45213 45296 ?        00:00:03 java
    45213 45297 ?        00:00:03 java
    45213 45298 ?        00:00:03 java
    45213 45299 ?        00:00:03 java
    45213 45300 ?        00:00:03 java
    45213 45301 ?        00:00:03 java
    45213 45302 ?        00:00:03 java
    45213 45303 ?        00:00:03 java
    45213 45304 ?        00:00:12 VM Thread
    45213 45305 ?        00:00:00 Reference Handl
    45213 45306 ?        00:00:00 Finalizer
    45213 45307 ?        00:00:00 Signal Dispatch
    45213 45308 ?        00:00:21 C2 CompilerThre
    45213 45309 ?        00:00:19 C2 CompilerThre
    

3、问题原因

根据上述步骤得知,是系统的线程资源达到了上限,但是线程资源为什么会占用pid资源呢,下面的deepseek的回答:

  1. Linux 线程的本质:Linux 通过 轻量级进程(LWP, Light Weight Process) 实现线程,线程与进程共享相同的底层机制:

    • 线程是共享地址空间的进程:每个线程拥有独立的 task_struct(内核中的进程描述符),但与其他线程共享内存、文件描述符等资源。
    • 线程占用独立的 PID 和 LWP ID:
      • PID(进程ID):所有线程共享主进程的 PID。
      • LWP(线程ID):每个线程有一个独立的 LWP ID(在用户态显示为 TID,可通过 gettid() 获取),内核视其为独立的调度单元。
  2. 线程如何占用 PID 资源?

    • 每个线程消耗一个内核 PID 槽位:
      虽然用户态看到的线程属于同一个进程(共享 PID),但在内核中,每个线程会占用一个独立的 PID 编号(通过 ps -eLf 的 LWP 列可见)。
      • 例如:一个进程有 100 个线程 → 内核需要分配 100 个 PID 槽位(即使 ps -ef 只显示 1 个 PID)。
    • 受系统级 pid_max 限制:
      线程数受 /proc/sys/kernel/pid_max 限制(默认通常为 32768 或更高)。
      • 如果系统有 1000 个进程,每个进程创建 100 个线程 → 需要 100,000 个 PID 槽位,可能触发 fork: Cannot allocate memory 错误。

4、问题解决

在 Linux 中,kernel.pid_max 参数决定了系统允许的最大进程/线程数,所以修改上限值可以解决上述问题:

  1. 临时设置 kernel.pid_max,但重启后失效

     sysctl -w kernel.pid_max=65535
    
  2. 永久设置 kernel.pid_max

    vim /etc/sysctl.conf
    

    在文件末尾添加:

    kernel.pid_max = 65535
    

    应用配置

    sysctl -p
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

L-960

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值