k8s的pod容器中微服务无法创建新线程unable to create new native thread

问题

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

这是困扰了我们一个很久的OOM问题,经常在一个节点上面多服务压力上来时出现,表面上是一个程序OOM,但具体又是里面的一个分支 线程问题。

出现的症状是不只是说一个服务,是跑在同一个节点上的所有服务而且是需要创建新线程的服务都出现无法创建新线程的异常日志,从节点的资源上看CPU和内存资源都还比较充足,只使用到了一半。

我们查看这个节点上的总线程数如下图趋势:

经常性出现,从经验上来看节点的总线程数到达32000后无不例外就有服务出现了unable to create new native thread的异常,而且比较坑的是此异常对服务的/actuator/health 健康检测接口无法探测,即此接口状态返回UP,导致服务不会重启,但服务又无法接收新请求。

接下来查看节点的总线程数设置(未设置之前)。

Bash 复制代码
# 宿主机上执行
# 内核级最大线程数,如果不文件不存在,则手动加一个
cat /proc/sys/kernel/threads-max          
返回32768

# 最大PID值
cat /proc/sys/kernel/pid_max             
返回32768

# 当前用户可创建的最大进程/线程数(nproc)
ulimit -u                                 
返回32768

#查看最大线程数内核参数 通常 32768
sysctl kernel.pid_max                     
返回32768

cat /etc/security/limits.conf(设置之后的)

从以上几个指令查看结果来看确实是总线程数限制到了32000。

解决

用户可创建的最大线程数 = min (max user processes, threads-max, pid_max);

当然先止血,先调大宿主机节点的总线程数都拉到最大655350

Markdown 复制代码
# 提升系统级线程数上限(当前 32768 可能不够)
sysctl -w kernel.threads-max=655350
sysctl -w kernel.pid_max=655350

# 持久化
echo "kernel.threads-max = 655350" >> /etc/sysctl.conf
echo "kernel.pid_max = 655350" >> /etc/sysctl.conf
sysctl -p

调整用户级 nproc 限制 /etc/security/limits.conf 追加

sql 复制代码
root soft nofile 655350
root hard nofile 655350
* soft nofile 655350
* hard nofile 655350

调整系统进程数配置,在/etc/sysctl.conf添加最大进程和线程数量配置:

Java 复制代码
kernel.pid_max=655350
kernel.threads-max=655350

执行sysctl -p加载并应用内核参数,执行sysctl -a |grep threads-max和sysctl -a |grep pid_max进行验证。

目前根据运维提供的资料将系统里面能改的参数都改了,但......将服务启动过了不久,仍然还有服务报无法创建新线程的异常。

至此开始怀疑是不是配置没生效,但从ulimit -a的一些指令来看都是没问题的,那就唯一一条路:重启大法。也许是需要将服务器重启才能生效。

于是建议将服务器进行了重启,结果总线程数终于能突破32000,至此配置生效。

当然 也要同时优化程序代码,从宿主机上统计应用时发现有多个java应用线程数达到4000以上甚至到了8000多,多个服务加一起总数肯定会超32000。

相关推荐
蜀道山老天师20 小时前
一文吃透 K8s:Deployment 滚动更新与版本回滚
云原生·容器·kubernetes
kylin-运维20 小时前
k8s可视化看板嵌入AI助手(悬浮对话球)
人工智能·容器·kubernetes·aicoding
Zhu7581 天前
在k8s环境部署ApacheGuacamole,分别对接MySQL和PG数据库
数据库·mysql·kubernetes
摇滚侠1 天前
云原生 Java 架构师的第一课 K8s+Docker+KubeSphere+DevOps 76-78
java·云原生·kubernetes
欢醉2 天前
k8s调用服务异常cannot allocate memory
kubernetes·k8s
扶疏5252 天前
Kubernetes Dashboard、动态卷供应、StatefulSet
容器·kubernetes
云烟成雨TD2 天前
Kubernetes 系列【14】对象元数据:标签、标签选择器、命名空间、字段选择器
云原生·容器·kubernetes
SLD_Allen2 天前
K8s+Ray:大模型时代AI Workload调度的通用范式
人工智能·容器·kubernetes