华为云服务器fork失败,无法创建新的线程怎么办?_云淘科技

问题描述

Linux操作系统的ECS,在执行命令或者日志打印时,出现如下报错信息:

错误信息1:

root@localhost:~# free -g
            total       used       free     shared     buffers   cached 
Mem:         94          43         51        0           0        0
Swap:        19          0         19
root@localhost:~# uname -a
-bash: fork: Cannot allocate memory

错误信息2:

xxxxsshd2[23985]: fatal: setresuid 20054: Resource temporarily unavailable
xxxxsshd2[28377]: Disconnecting: fork failed: Resource temporarily unavailable
xxxxsshd2[4484]: Disconnecting: fork failed: Resource temporarily unavailable

错误信息3:

[root@ecs-xxxx ~]$ sudo docker info
runtime/cgo: pthread_create failed: Resource temporarily unavailable
SIGABRT: abort

根因分析

通常情况,出现上述错误由于创建线程失败,可能原因是ECS系统内存不足,系统当前的线程数达到了配置的最大值。

处理方法

登录管理控制台。
通过ECS的主机监控功能的“内存使用率”指标,查看云服务器内存使用情况确认云服务器内存情况,详细操作,请参见查看监控指标。

如果内存不足,建议建议扩容内存或者优化内存的使用,扩容内存可参考变更规格通用操作。
否则,执行步骤3。

以root用户登录云服务器,执行以下命令,排查message和dmesg日志。

dmesg -T

cat /var/log/messages

如果出现如图1所示的cgroup相关报错打印,执行步骤8。
否则,执行步骤4。

图1 日志报错

执行以下命令,查看当前系统线程总数。

ps -efL | wc -l

执行以命令,将得到的两个值与步骤4查到的当前系统线程总数进行对比。

sysctl -a | grep pid_max

sysctl -a | grep threads-max

如果当前系统线程总数接近这两个值其中一个,那么就需要对这pid_max、threads-max这两个参数进行调优。调优步骤请参考调优pid_max、threads-max参数。
否则,执行步骤6。

执行以下命令,确定报错进程的pid。

ps -ef | grep 报错进程名

执行以下命令,根据得到的pid检查该进程的limits配置:

cat /proc/pid/limits

图2 确定进程limits配置

查看Max processes行,如果当前用户创建的所有线程数接近该值,那么需要对limits参数进行调优,调优步骤请参考调优limits参数。
否则,执行步骤8。

执行以下命令,根据日志的cgroup报错可以得到当前报错的具体的cgroup目录。

cat /sys/fs/cgroup/pids/拼接日志中报错目录/pids.max

cat /sys/fs/cgroup/pids/拼接日志中报错目录/pids.current

图3 cgroup目录

示例如下:

执行以下命令,根据进程的pid查找对应的cgroup目录。

cat /proc/pid/cgroup

图4 根据pid查找对应的cgroup目录

返回结果中的pids行为“/user.slice/user-0.slice/session-5.scope/”,与/sys/fs/cgroup/pids/拼接,可得进程对应的cgroup目录为“/sys/fs/cgroup/pids/user.slice/user-0.slice/session-5.scope/”。

执行以下命令,根据日志的cgroup报错可以得到当前报错的具体的cgroup目录。

cat /sys/fs/cgroup/pids/user.slice/user-0.slice/session-5.scope/pids.max

cat /sys/fs/cgroup/pids/user.slice/user-0.slice/session-5.scope/pids.current

如果pids.current接近pids.max,那么需要对cgroup参数进行调优,调优步骤请参考调优cgroup参数。
否则,请提交工单联系技术支持处理。

相关命令

调优pid_max、threads-max参数

由于不同操作系统发行版默认参数不一致,执行以下命令,查询当前配置参数。

sysctl -a | grep pid_max

sysctl -a | grep threads-max

执行以下命令,修改pid_max、threads-max参数。

echo ‘kernel.pid_max = 4194304’ >> /etc/sysctl.conf

echo ‘kernel.threads-max = 4194304’ >> /etc/sysctl.conf

执行以下命令,使配置生效。

sysctl -p

调优limits参数

以启动报错业务进程的用户登录云服务器,执行以下命令查询当前配置参数。

ulimit -u

执行以下命令,根据业务需求和当前值评估,配置合适的nproc上限。

以root用户nproc配置100000为例:

echo ‘root soft nproc 100000’ >> /etc/security/limits.conf

echo ‘root hard nproc 100000’ >> /etc/security/limits.conf

重新登录云服务器,执行以下命令确认配置是否生效。

ulimit -u

回显值如果是步骤2配置的值,表示配置已经生效,在该session重启业务进程即可。
否则,请提交工单联系技术支持处理。

调优cgroup参数

临时修改方案:

执行以下命令,以将相关cgroup临时修改上限为最大为例,修改当前超出限制的cgroup目录。

echo max > /sys/fs/cgroup/pids/user.slice/user-0.slice/session-25.scope/pids.max

永久修改方案:

执行以下命令,以将相关cgroup设置到无穷大为例,修改当前超出限制的cgroup目录。

该值可以根据需要调整,修改完成后需要重启云服务器使配置生效。

echo DefaultTasksMax=infinity >>/etc/systemd/system.conf

echo DefaultTasksMax=infinity >>/etc/systemd/user.conf

echo UserTasksMax=infinity >>/etc/systemd/logind.conf

父主题: 操作系统类(Linux)

内容没看懂? 不太想学习?想快速解决? 有偿解决: 联系专家