? ? ? ? ?线上突然告警,zk集群不可用。随机看了zk节点挂了前的的机器的CPU与内存,内存100%,如下图所示。
? ? ? ? ?首先我看了日志,由于线上配置的问题,所有的日志全部扔掉了。基于日志没有发现有价值的内容,接着又看了节点的网络,TCP连接数,磁盘IO,线程数,这些都是在正常范围内。? ??
? ? ? ? 接着想着尝试启动一个节点,启动成功。但是通过top命令查看zk线程CPU利用率在30%左右,在正常情况下zk一般不耗内存(除非异常了)。
下面是最耗CPU的堆栈信息:
"NIOServerCxn.Factory:0.0.0.0/0.0.0.0:22288" daemon prio=10 tid=0x00007ff25c22e000 nid=0x9b24b runnable [0x00007ff17dab6000] ? ?java.lang.Thread.State: RUNNABLE ?? ?at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) ?? ?at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:210) ?? ?at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65) ?? ?at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69) ?? ?- locked <0x0000000601b704e8> (a sun.nio.ch.Util$2) ?? ?- locked <0x0000000601b71370> (a java.util.Collections$UnmodifiableSet) ?? ?- locked <0x0000000601b70de8> (a sun.nio.ch.EPollSelectorImpl) ?? ?at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80) ?? ?at org.apache.zookeeper.server.NIOServerCnxnFactory.run(NIOServerCnxnFactory.java:178) ?? ?at java.lang.Thread.run(Thread.java:662)
通过netstat命令查看连接状态,发现有许多TIME_WAIT
[root@host-x-x-x-x bin]# netstat -pano | grep 22288
tcp 0 0 ::ffff:127.0.0.1:15298 ::ffff:127.0.0.1:22288 TIME_WAIT - timewait (15.34/0/0)
tcp 0 0 ::ffff:x.x.x.x:22288 ::ffff:x.x.x.x:39904 TIME_WAIT - timewait (30.02/0/0)
查看zk的启动状态,结果如下(当然,集群要全部启动后才能看到是master/follower):
????????当然过了几分钟,该节点也挂了。只好继续查找原因,当节点启动后,虽然集群不可用,但是还是在尝试建立TCP连接,至于为啥是TCP四次挥手中的TIME_WAIT状态,我猜测是由于在zk集群节点挂后,我马上建立重启,但集群未生效,节点通过TIME_WAIT允许老的重复分节在网络中消逝 (端口号还是保持不变)。
?????????该节点启动不一会儿(有正常的端口号),端口又挂了。查看内存,发现内存使用率陡增(集群不可用,为啥内存还陡增了?虽然zk集群不可用,但是客户端与该ip在尝试建立socket连接,不断分配端口文件描述符……期望有更好的理由[吃瓜])。首先想到的是调整内存。
确实调整内存后很有效果 ,不再出现内存陡增情况。
? ? 接着继续看zk配置的节点列表,总共有11个docker,但有6个docker不可用。这就很明显了,过半的节点不可用,当然集群不可用了。因此将server保留最新的5个节点,启动zk节点,集群可用。
????????虽然问题解决了,但遗留了一个问题:在集群不可用时,启动其中一个zk节点,为啥短时间内内存使用率很高??
|