我有一个 Jenkins 服务器,它一直用完内存并且无法创建本机线程。我增加了内存并安装了监控插件。
服务器上大约有 150 个项目,我整天都在看着线程数不断增加。现在大约是 990。我预计当它达到 1024(线程的用户限制)时,Jenkins 将再次耗尽内存。
[edit]: I have hit 1016 threads and am now getting the out of memory error
这是 Jenkins 运行的适当数量的线程吗?我如何告诉詹金斯在完成线程后销毁它们?
tl;博士:
有一个运行 bash 脚本的构建后操作没有通过 stderr 或 stdout 向 Jenkins 返回任何内容。因此,每次构建运行时,都会创建线程并卡住wait。我通过让 bash 脚本返回exit状态解决了这个问题。
长答案
我在 CentOS 上运行 Jenkins,并通过 RPM 安装。在修改 Winstone servlet 容器方面,您可以在/etc/sysctrl/jenkins. 但是,上面的选项仅控制创建的 HTTP 线程数,而不是总体线程数。
如果我的线程挂在访问 Jenkins 的 HTTP API 作为提交后操作的一部分,那将是一个解决方案。但是,使用我的问题中提到的非常方便的监控插件,我检查了卡住的线程。
线卡在com.trilead.ssh2.channel包裹里的东西上。该getChannelData方法有一个while(true)循环,用于查找ssh 流的stderror的输出。stdout线程在那个循环中变得很糟糕,因为没有任何东西通过。我在GrepCode上学到了这一点。
这是因为构建后的操作是通过 SSH 向服务器执行命令并执行一个 bash 脚本来检查 git 存储库。但是,git repo 配置错误,git 命令会出错,但exit 1状态没有通过 bash 脚本冒泡(部分原因是 if-elif-else 语句格式错误)。
脚本完成并且构建被认为是成功的,但是由于这个 git 错误,处理来自 Jenkins 的 SSH 连接的线程不知何故被挂起。
但是感谢您对这个问题的帮助!
如果您“开箱即用”地运行 Jenkins,它将使用 Winstone servlet 容器。您可以将命令行参数传递给它,如此处所述。其中一些参数可以限制线程数:
--handlerCountStartup = set the no of worker threads to spawn at startup. Default is 5
--handlerCountMax = set the max no of worker threads to allow. Default is 300
--handlerCountMaxIdle = set the max no of idle worker threads to allow. Default is 50
现在,我前段时间尝试过,但并不是 100% 相信它有效,所以不能保证,但值得一试。