我知道,这个问题听起来很模糊,但我试图理解和解决这个问题已经有一段时间了,也就是说,没有简单地自动重启pod(应用程序在K8中运行)定期。
在(Kotlin,Sping Boot )应用程序运行了几天之后,我突然得到了很多这样的两个:
Failed to start thread - pthread_create failed (EAGAIN) for attributes: stacksize: 256k, guardsize: 0k, detached.
Failed to start thread - pthread_create failed (EAGAIN) for attributes: stacksize: 256k, guardsize: 0k, detached.
个
监控截图:
- K8单元资源:https://i.imgur.com/BqKT9om.png
- 内存并没有耗尽。但是我也试过使用更大数量的RAM,例如,24 GB,仍然有同样的问题。
- JVM(执行器)度量:https://i.imgur.com/Jpdv2F4.png
- 将鼠标悬停在文件描述符图形上有助于澄清图例:https://i.imgur.com/wBdu5RE.png
- 既未达到最大线程数,也未达到最大文件描述符数
其他信息:
ulimit -n
:1048576
- 第一个月第四个月第一个月:第一个月第五个月
cat /proc/[...]/limits
(使用我的进程ID):gist.github.com/Dobiasd/c6e38668b36f8eb97ff69e15a45cf635cat /proc/sys/kernel/threads-max
得到2060488
/etc/security/limits.conf
为空(仅限#
-注解行)java -XX:+PrintFlagsFinal -version | grep -i thread
看起来也不可疑:https://gist.github.com/Dobiasd/01623e9066889c8fd059bd387a15fafa- 堆栈大小(每个线程)减少到256 K(
-Xss256K
,默认值为1 M)。 - 从运行正常的pod(即,在问题发生之前)进行线程转储(使用
jcmd
),已有约2k个线程:gist.github.com/Dobiasd/391488295e6ffd05ecc5134450cd723d-它们中的大多数都是ThreadPoolExecutors中的守护线程,正在等待工作。(用于BigQuery插入)。稍后可能会跳转到更多线程,因为在某些错误情况下,我正在重新示例化WriteStreams / JsonStreamWriters。不过,这应该没问题。过一段时间后,旧的示例应该被垃圾回收,线程也会死亡。2所以6 k线程应该只是暂时存在(如果一切正常的话)。3是的,当然,可能有一些方法可以避免这种情况,但是根据现有的限制,6 k线程仍然不应该是一个问题。
有什么想法可能是什么原因和/或如何修复它?
2022年6月1日更新:我现在实现了一个线程更少的解决方案,也避免了从~2k线程到~ 6 k线程的大跳跃,如上面的执行器图所示。这个解决方案帮助我解决了问题,但我对~ 6 k线程为什么太多的好奇心仍然存在。)
2条答案
按热度按时间mrfwxfqh1#
虽然
cat /proc/sys/kernel/threads-max
显示系统范围内允许2M线程,但也可能存在用户级限制。实际上,这个简单的测试程序可以创建31k线程:
这比我们预期的
ulimit -u
结果要少。首先,您应该检查容器中的
ulimit -u
。ovfsdjhp2#
我不知道我是否正确地阅读了你的图表,但在这里:https://i.imgur.com/Jpdv2F4.png“文件描述符”图表显示“最大:1.0 Mil电流:1.0 Mil”所以看起来你已经达到了打开文件的最大数量限制。
通过
ulimit -n
检查命令行上的限制是值得的。你也可以检查进程限制cat /proc/$(pgrep java)/limits
。