最近使用nacos 发现了一个问题,nacos 启动后,大概经过两个半小时就会突然占满cpu。
电脑环境:windows10
nacos 版本:1.2.0,1.2.1,1.3.1 (都是windows 版,这三个版本我都试过了)
操作:开启nacos 之后,等待 大概两个小时到两个半小时。
现象:等到一定时间后,电脑cpu 突然占满。(用了两台电脑都这样测过,都会出现这样的现象)
图:

you can see #3806, same case maybe
我就仅仅启动了nacos ,并没有使用它做任何事情,就只是启动它而已(没有注册服务)。
大概过了两个半小时,它就会突然占满cpu (一瞬间占满)。
提供一下cpu占满时的线程信息呢。
发自我的iPhone
------------------ 原始邮件 ------------------
发件人: xmf1142987374 <[email protected]>
发送时间: 2020年9月24日 07:05
收件人: alibaba/nacos <[email protected]>
抄送: 赵延 <[email protected]>, Comment <[email protected]>
主题: 回复:[alibaba/nacos] window10 下 nacos占满cpu (#3903)
我就仅仅启动了nacos ,并没有使用它做任何事情,就只是启动它而已(没有注册服务)。
大概过了两个半小时,它就会突然占满cpu (一瞬间占满)。
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub, or unsubscribe.
麻烦在高cpu时 dump一下 线程栈, 并用top -Hp 的命令看一下哪几个线程占了高CPU,通过线程id到线程栈中找到这个线程, 看下这个线程的调用堆栈,把这几个信息发到issue里分析下。



我不是太懂分析这些,我发出来你们看看吧
文件没有上传成功,能麻烦把这个线程的运行堆栈给dump出来吗?
https://pmbeefile.oss-cn-beijing.aliyuncs.com/dump.txt
我把文件放在这个上面 你看看吧
解决了吗?
解决了吗?
没有,看不出什么原因
解决了吗?
没有,看不出什么原因
我今天用另一台电脑跑1.3.1的,没有注册任何服务,不会出现cpu 100%;但是我自己那台电脑跑1.3.1或1.3.2,注册了服务,则出现了cpu 100%
解决了吗?
没有,看不出什么原因
我今天用另一台电脑跑1.3.1的,没有注册任何服务,不会出现cpu 100%;但是我自己那台电脑跑1.3.1或1.3.2,注册了服务,则出现了cpu 100%
我没有注册服务,就空开着跑的,前面跑着没什么问题,到了后面一下子就会占满cpu。你大概是过了多久占满了cpu
解决了吗?
没有,看不出什么原因
我今天用另一台电脑跑1.3.1的,没有注册任何服务,不会出现cpu 100%;但是我自己那台电脑跑1.3.1或1.3.2,注册了服务,则出现了cpu 100%
我没有注册服务,就空开着跑的,前面跑着没什么问题,到了后面一下子就会占满cpu。你大概是过了多久占满了cpu
我把服务跑起来后,大概过了半小时就满了
解决了吗?
没有,看不出什么原因
我今天用另一台电脑跑1.3.1的,没有注册任何服务,不会出现cpu 100%;但是我自己那台电脑跑1.3.1或1.3.2,注册了服务,则出现了cpu 100%
我没有注册服务,就空开着跑的,前面跑着没什么问题,到了后面一下子就会占满cpu。你大概是过了多久占满了cpu
我把服务跑起来后,大概过了半小时就满了
那如果用你自己电脑不注册服务去跑呢,你试试会不会cpu占满 (我不管注不注册服务,我开着nacos 大概过了两个小时cpu就会占满)
解决了吗?
没有,看不出什么原因
我今天用另一台电脑跑1.3.1的,没有注册任何服务,不会出现cpu 100%;但是我自己那台电脑跑1.3.1或1.3.2,注册了服务,则出现了cpu 100%
我没有注册服务,就空开着跑的,前面跑着没什么问题,到了后面一下子就会占满cpu。你大概是过了多久占满了cpu
我把服务跑起来后,大概过了半小时就满了
那如果用你自己电脑不注册服务去跑呢,你试试会不会cpu占满 (我不管注不注册服务,我开着nacos 大概过了两个小时cpu就会占满)
下回我试一下
解决了吗?
没有,看不出什么原因
我今天用另一台电脑跑1.3.1的,没有注册任何服务,不会出现cpu 100%;但是我自己那台电脑跑1.3.1或1.3.2,注册了服务,则出现了cpu 100%
我没有注册服务,就空开着跑的,前面跑着没什么问题,到了后面一下子就会占满cpu。你大概是过了多久占满了cpu
我把服务跑起来后,大概过了半小时就满了
那如果用你自己电脑不注册服务去跑呢,你试试会不会cpu占满 (我不管注不注册服务,我开着nacos 大概过了两个小时cpu就会占满)下回我试一下
我发在上面的文件链接信息 ,你有看出什么原因吗
解决了吗?
没有,看不出什么原因
我今天用另一台电脑跑1.3.1的,没有注册任何服务,不会出现cpu 100%;但是我自己那台电脑跑1.3.1或1.3.2,注册了服务,则出现了cpu 100%
我没有注册服务,就空开着跑的,前面跑着没什么问题,到了后面一下子就会占满cpu。你大概是过了多久占满了cpu
我把服务跑起来后,大概过了半小时就满了
那如果用你自己电脑不注册服务去跑呢,你试试会不会cpu占满 (我不管注不注册服务,我开着nacos 大概过了两个小时cpu就会占满)下回我试一下
我发在上面的文件链接信息 ,你有看出什么原因吗
看不太出来,不过之前找了一篇博客,不知道是不是版本兼容问题https://blog.csdn.net/weixin_30783629/article/details/96637747
解决了吗?
没有,看不出什么原因
我今天用另一台电脑跑1.3.1的,没有注册任何服务,不会出现cpu 100%;但是我自己那台电脑跑1.3.1或1.3.2,注册了服务,则出现了cpu 100%
我没有注册服务,就空开着跑的,前面跑着没什么问题,到了后面一下子就会占满cpu。你大概是过了多久占满了cpu
我把服务跑起来后,大概过了半小时就满了
那如果用你自己电脑不注册服务去跑呢,你试试会不会cpu占满 (我不管注不注册服务,我开着nacos 大概过了两个小时cpu就会占满)下回我试一下
我发在上面的文件链接信息 ,你有看出什么原因吗
看不太出来,不过之前找了一篇博客,不知道是不是版本兼容问题https://blog.csdn.net/weixin_30783629/article/details/96637747
前面我也以为是不是其他的原因,所以后来我下了一个新版本的nacos ,什么都不做 ,就仅仅干跑着,完全扯不上其他的东西,还是占满cpu。
解决了吗?
没有,看不出什么原因
我今天用另一台电脑跑1.3.1的,没有注册任何服务,不会出现cpu 100%;但是我自己那台电脑跑1.3.1或1.3.2,注册了服务,则出现了cpu 100%
我没有注册服务,就空开着跑的,前面跑着没什么问题,到了后面一下子就会占满cpu。你大概是过了多久占满了cpu
我把服务跑起来后,大概过了半小时就满了
那如果用你自己电脑不注册服务去跑呢,你试试会不会cpu占满 (我不管注不注册服务,我开着nacos 大概过了两个小时cpu就会占满)下回我试一下
我发在上面的文件链接信息 ,你有看出什么原因吗
看不太出来,不过之前找了一篇博客,不知道是不是版本兼容问题https://blog.csdn.net/weixin_30783629/article/details/96637747
前面我也以为是不是其他的原因,所以后来我下了一个新版本的nacos ,什么都不做 ,就仅仅干跑着,完全扯不上其他的东西,还是占满cpu。
如果解决不了,我都想用apollo了
文件没有上传成功,能麻烦把这个线程的运行堆栈给dump出来吗?
看看文件信息啊
文件没有上传成功,能麻烦把这个线程的运行堆栈给dump出来吗?
看看文件信息啊
用这个命令看一下是哪个线程号占用了cpu呢。
ps -mp pid -o THREAD,tid,time
然后麻烦再发一下现在的堆栈信息
文件没有上传成功,能麻烦把这个线程的运行堆栈给dump出来吗?
看看文件信息啊
用这个命令看一下是哪个线程号占用了cpu呢。
ps -mp pid -o THREAD,tid,time然后麻烦再发一下现在的堆栈信息
我这是windows 环境 我再想想怎么定位吧
@horizonzy cpu 占用就是图中的这几个线程。然后堆栈信息放在最后的链接上面

@horizonzy @KomachiSion 这些线程内部都有 这个 at sun.nio.ch.WindowsSelectorImpl 类 的调用
@horizonzy @KomachiSion 这些线程内部都有 这个 at sun.nio.ch.WindowsSelectorImpl 类 的调用
看了下stack信息,没有死锁。在网上搜索了下相关的问题。目前有人在window机器下解决这个问题,因为病毒问题导致文件句柄占用过多。这个和nacos没什么关系,你尝试一下杀一下机器的病毒呢
@horizonzy @KomachiSion 这些线程内部都有 这个 at sun.nio.ch.WindowsSelectorImpl 类 的调用
看了下stack信息,没有死锁。在网上搜索了下相关的问题。目前有人在window机器下解决这个问题,因为病毒问题导致文件句柄占用过多。这个和nacos没什么关系,你尝试一下杀一下机器的病毒呢
杀过毒了,电脑没有病毒。
@horizonzy @KomachiSion 这些线程内部都有 这个 at sun.nio.ch.WindowsSelectorImpl 类 的调用
看了下stack信息,没有死锁。在网上搜索了下相关的问题。目前有人在window机器下解决这个问题,因为病毒问题导致文件句柄占用过多。这个和nacos没什么关系,你尝试一下杀一下机器的病毒呢
我也看了网上的相关解决,说是病毒的都是在 tomcat占cpu 的情况下,和现在场景不一样啊。我的电脑杀过毒了,没有发现任何病毒,然后我等下启动一下tomcat看会不会占满cpu吧。 tomcat 堆栈信息中找到 nio 的工作线程,发现 它并没有进行 channel 运算(tomcat 版本:8.5)。
@horizonzy 跑tomcat 并不会有任何问题
老铁,你的jdk版本是多少啊。
@horizonzy 跑tomcat 并不会有任何问题
我跟了一下,可能是由于nio在windos下的bug有关。你自己跑tomcat的时候用的是nio模型吗。nacos跑起来用的tomcat9.0.38,默认用的nio
jetty服务器中有个issue关于这个问题。https://github.com/eclipse/jetty.project/issues/2205
这个pr解决了这个问题。https://github.com/eclipse/jetty.project/pull/2335
在windos在,调用selector.select(),当没有连接进来时,selector.select()也被唤醒了,只是返回值为0。这种情况下,没有请求连接进来,也会导致cpu一直消耗,这导致cpu占用高。
这个可能是jdk的一个bug导致的该问题。https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6778476
那nacos只能迁环境了呀
这个可能是jdk的一个bug导致的该问题。https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6778476
那nacos只能迁环境了呀
也许是安装了一些其他程序的问题。@xmf1142987374 老铁安装了iboss代理没得
还有就是过了两个小时才会出现这个问题,我怀疑和TCP的keepAlive有关,windos下默认应该是两个小时。两个小时没有数据传输,这个时候就是发心跳包,可能你本机的机器安装了什么代理软件,在发心跳包的时候。触发了nio的bug,导致没有连接上来时,也让selector.select()唤醒了,这样导致了cpu的飙升
还有就是过了两个小时才会出现这个问题,我怀疑和TCP的keepAlive有关,windos下默认应该是两个小时。两个小时没有数据传输,这个时候就是发心跳包,可能你本机的机器安装了什么代理软件,在发心跳包的时候。触发了nio的bug,导致没有连接上来时,也让selector.select()唤醒了,这样导致了cpu的飙升
不知道你说的代理软件具体是什么,我并没有安装什么代理软件。然后我的jdk 版本:

我在netty 的 issues 看到这样的一段话

我看了一下,这个是jdk nio的一个bug。netty通过这个参数来判断。如果设置了这个参数。当调用了selector.select()时,没有事件进来,但是却立即返回了。一旦这个情况连续发生了1024次,就会重新构造一个selector,避免原来那个有问题的selector.select()一直持续消耗cpu,导致cpu飙升。这个是jvm的nio存在的一个bug,netty通过判断发生这种情况,重新new一个selector来规避它
相关代码:


我在netty 的 issues 看到这样的一段话
对于nacos而言,我所能想到的是nio可能就在tomcat中可能会用到。在某种情况下,tomcat的nio也导致了这个bug的发生,导致你的机器cpu飙升。现在据我看到的信息,这个问题可能在windos下发生。
我在netty 的 issues 看到这样的一段话
这个nio的bug很可能是因为你的机器的网络问题导致的。请问一下你的机器是否安装过一些什么和网络相关的软件吗,还有你的机器是操作系统是什么
我在netty 的 issues 看到这样的一段话
这个nio的bug很可能是因为你的机器的网络问题导致的。请问一下你的机器是否安装过一些什么和网络相关的软件吗,还有你的机器是操作系统是什么
图片挂了
Refer to #3854

罪魁祸首或许找到了,可能不是tomcat导致的,而是项目中引入的org.apache.httpcomponents:httpcore-nio:jar:4.4.13包中的AbstractIOReactor导致的。在项目启动时,AbstractIOReactor的execute方法中就会调用selector.select(1000)。而在windows环境下,java nio的selector.select()存在bug。没有连接也会被唤醒,导致cpu一直空转,结果cpu飙升。
org.apache.httpcomponents:httpcore-nio:jar:4.4.13在org.apache.httpcomponents:httpasyncclient:jar:4.1.3中被引入。先尝试给apache反馈下这个问题。然后看看这个包在我们项目中是否是必须要的,如果可以不要的话,剔除这个依赖。
相关代码:

@Maijh97 麦老哥,我们在这里这个方法里面com.alibaba.nacos.common.http.AbstractHttpClientFactory#createNacosAsyncRestTemplate构造CloseableHttpAsyncClient时,会去创建org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor#AbstractMultiworkerIOReactor. 这里面后续会初始化Worker,Worker这个Runable里面BaseIOReactor.execute()时,就会用nio的方式去阻塞。这个在windos下有问题,我基于这个问题fix了一下,不知道有没有问题,能check一下吗. refer https://github.com/apache/httpcomponents-core/pull/226
@horizonzy 老哥,可以添加一下钉钉吗?和你沟通一下这个问题 钉钉号:maijh97
我在自己的windows机器上面成功复现。代码中selector.select(1000).如果没有连接的话,本应该阻塞一秒。但是却直接返回了,而且返回的readyCount = 0,这是windows机器下nio存在的一个bug,这显然会导致cpu一直进行空转,从而cpu占用升高。以下是cpu占用截图,以及复现视频。

windows_nio_bug.mp4.zip
我在自己的windows机器上面成功复现。代码中selector.select(1000).如果没有连接的话,本应该阻塞一秒。但是却直接返回了,而且返回的readyCount = 0,这是windows机器下nio存在的一个bug,这显然会导致cpu一直进行空转,从而cpu占用升高。以下是cpu占用截图,以及复现视频。
windows_nio_bug.mp4.zip
兄弟,我这边在docker版本下面也有这个cpu的问题。
之前的在mac上运行的docker版本时候,情况跟问题描述情况类似,只是开着什么服务都没有连接,cpu就超100%(多核)了。
后来在centos7服务器上运行docker,也是会有这问题。
我这边使用的版本,一直是docker版本,从1.2.0,到现在的1.3.2都有这个问题。
以前我用单机测试的时候发现这问题,后来用3台集群的情况下,也是跑着跑着cpu就起来了。
我在自己的windows机器上面成功复现。代码中selector.select(1000).如果没有连接的话,本应该阻塞一秒。但是却直接返回了,而且返回的readyCount = 0,这是windows机器下nio存在的一个bug,这显然会导致cpu一直进行空转,从而cpu占用升高。以下是cpu占用截图,以及复现视频。
windows_nio_bug.mp4.zip兄弟,我这边在docker版本下面也有这个cpu的问题。
之前的在mac上运行的docker版本时候,情况跟问题描述情况类似,只是开着什么服务都没有连接,cpu就超100%(多核)了。
后来在centos7服务器上运行docker,也是会有这问题。
我这边使用的版本,一直是docker版本,从1.2.0,到现在的1.3.2都有这个问题。
以前我用单机测试的时候发现这问题,后来用3台集群的情况下,也是跑着跑着cpu就起来了。
当你的cpu飙升时,能否发下堆栈信息。看下占用cpu的线程在干什么
我在自己的windows机器上面成功复现。代码中selector.select(1000).如果没有连接的话,本应该阻塞一秒。但是却直接返回了,而且返回的readyCount = 0,这是windows机器下nio存在的一个bug,这显然会导致cpu一直进行空转,从而cpu占用升高。以下是cpu占用截图,以及复现视频。
windows_nio_bug.mp4.zip兄弟,我这边在docker版本下面也有这个cpu的问题。
之前的在mac上运行的docker版本时候,情况跟问题描述情况类似,只是开着什么服务都没有连接,cpu就超100%(多核)了。
后来在centos7服务器上运行docker,也是会有这问题。
我这边使用的版本,一直是docker版本,从1.2.0,到现在的1.3.2都有这个问题。
以前我用单机测试的时候发现这问题,后来用3台集群的情况下,也是跑着跑着cpu就起来了。当你的cpu飙升时,能否发下堆栈信息。看下占用cpu的线程在干什么

我的nacos端口是8844,从图中,可以看到,占用cpu资源较多的是,http-nio-8844-e等线程。说明解决问题的方向是正确的。
@xiaojun207 看一下堆栈信息呢。
@xiaojun207 看一下堆栈信息呢。
这是我打印的堆栈信息
jstack.log
@xiaojun207 看一下堆栈信息呢。
这是我打印的堆栈信息
jstack.log
嗯。明确一下nacos进程中占用cpu多的线程id呢。
@xiaojun207 看一下堆栈信息呢。
这是我打印的堆栈信息
jstack.log嗯。明确一下nacos进程中占用cpu多的线程id呢。

主线程pid是21,图中是top -H 的子线程情况
嗯。看了一下,你这个不是nio问题导致的。从堆栈看起来程序没什么大问题,这个进程消耗的CPU总的有多少,你那边怎么使用的
嗯。看了一下,你这个不是nio问题导致的。从堆栈看起来程序没什么大问题,这个进程消耗的CPU总的有多少,你那边怎么使用的
nacos我这边,cpu消耗,一般都会占到190%左右,占总机器的90%。
我使用,一般都使用docker的默认启动参数,mysql做存储。一般来说开启NACOS_AUTH_ENABLE=true,单机MODE和集群(3台)都使用过。注册服务的个数也不算多,大概20~30个。
使用的时候,注册和配置同时使用。
这个吞吐量,基本上不太会有什么压力。
嗯。看了一下,你这个不是nio问题导致的。从堆栈看起来程序没什么大问题,这个进程消耗的CPU总的有多少,你那边怎么使用的
nacos我这边,cpu消耗,一般都会占到190%左右,占总机器的90%。
我使用,一般都使用docker的默认启动参数,mysql做存储。一般来说开启NACOS_AUTH_ENABLE=true,单机MODE和集群(3台)都使用过。注册服务的个数也不算多,大概20~30个。
使用的时候,注册和配置同时使用。
这个吞吐量,基本上不太会有什么压力。
嗯。nacos-client用的哪个版本。
嗯。看了一下,你这个不是nio问题导致的。从堆栈看起来程序没什么大问题,这个进程消耗的CPU总的有多少,你那边怎么使用的
nacos我这边,cpu消耗,一般都会占到190%左右,占总机器的90%。
我使用,一般都使用docker的默认启动参数,mysql做存储。一般来说开启NACOS_AUTH_ENABLE=true,单机MODE和集群(3台)都使用过。注册服务的个数也不算多,大概20~30个。
使用的时候,注册和配置同时使用。
这个吞吐量,基本上不太会有什么压力。嗯。nacos-client用的哪个版本。
nacos-client分两类,
1、java springboot部分,使用的是:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
2、golang部分,使用的是:
github.com/nacos-group/nacos-sdk-go v1.0.0
你那边能检查一下access.log吗,看一下CPU高的这台机器每秒收到多少请求。我刚才看了一下堆栈信息,发现在请求过来的时候认证登陆信息的时候消耗了不少cpu,我现在推测是客户端的http请求次数太多导致的cpu飙升。
你那边能检查一下access.log吗,看一下CPU高的这台机器每秒收到多少请求。我刚才看了一下堆栈信息,发现在请求过来的时候认证登陆信息的时候消耗了不少cpu,我现在推测是客户端的http请求数据太多导致的cpu飙升。
从access.log看,go版本的客户端sdk,请求频率确实很高。这个应该是go版本客户端的问题。稍后,我把go部分的暂停了,再试试看。
你那边能检查一下access.log吗,看一下CPU高的这台机器每秒收到多少请求。我刚才看了一下堆栈信息,发现在请求过来的时候认证登陆信息的时候消耗了不少cpu,我现在推测是客户端的http请求数据太多导致的cpu飙升。
从access.log看,go版本的客户端sdk,请求频率确实很高。这个应该是go版本客户端的问题。稍后,我把go部分的暂停了,再试试看。
嗯。可以的话单独提一个issue来跟进吧。你的问题和现在和issue关系不大
oracle jdk team is tracing https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8255627
oracle jdk team is tracing https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8255627
那目前我自己的nacos 只能过两个小时重启了?才能玩的起来?
目前是,不方便的话可以通过docker来进行部署,后续问题有推进我会在这个issue里面反馈。
Most helpful comment
我在自己的windows机器上面成功复现。代码中selector.select(1000).如果没有连接的话,本应该阻塞一秒。但是却直接返回了,而且返回的readyCount = 0,这是windows机器下nio存在的一个bug,这显然会导致cpu一直进行空转,从而cpu占用升高。以下是cpu占用截图,以及复现视频。

windows_nio_bug.mp4.zip