问题的发现

最早问题的发现在于用户提的,用户提出他支付时支付失败,过了一会儿再试就好了,于是翻日志,查询到当时duboo调用出现了下类错误:

[TraceID:20200527145701489] DEBUG c.y.c.s.w.s.m.m.a.HandlerMethodAspect - Throw: {}
com.alibaba.dubbo.rpc.RpcException: Forbid consumer 172.17.40.16 access service com.bwton.rpc.account.IAccountBindCardRpc from registry 10.10.2.201:2181 use dubbo version 2.8.4, Please check registry access list (whitelist/blacklist).
at com.alibaba.dubbo.registry.integration.RegistryDirectory.doList(RegistryDirectory.java:579)
at com.alibaba.dubbo.rpc.cluster.directory.AbstractDirectory.list(AbstractDirectory.java:73)
at com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker.list(AbstractClusterInvoker.java:260)
at com.alibaba.dubbo.rpc.cluster.support.AbstractClusterInvoker.invoke(AbstractClusterInvoker.java:219)
at com.alibaba.dubbo.rpc.cluster.support.wrapper.MockClusterInvoker.invoke(MockClusterInvoker.java:72)
at com.alibaba.dubbo.rpc.proxy.InvokerInvocationHandler.invoke(InvokerInvocationHandler.java:52)
at com.alibaba.dubbo.common.bytecode.proxy2.findAccountBindCardList(proxy2.java)
at com.bwton.controller.account.bindcard.BindCardController.findAccountsByUser_aroundBody6(BindCardController.java:212)
at com.bwton.controller.account.bindcard.BindCardController$AjcClosure7.run(BindCardController.java:1)
at org.aspectj.runtime.reflect.JoinPointImpl.proceed(JoinPointImpl.java:149)
at com.qbao.cat.plugin.DefaultPluginTemplate.proxyCollector(DefaultPluginTemplate.java:97)
at com.qbao.cat.plugin.DefaultPluginTemplate.doAround(DefaultPluginTemplate.java:77)
at com.qbao.cat.plugin.spring.SpringControllerPluginTemplate.doAround(SpringControllerPluginTemplate.java:27)
at com.bwton.controller.account.bindcard.BindCardController.findAccountsByUser(BindCardController.java:201)
at com.bwton.controller.account.bindcard.BindCardController$$FastClassBySpringCGLIB$$9f6f4f14.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)
at com.yanyan.core.spring.web.servlet.mvc.method.annotation.HandlerMethodAspect.aroundInvoke(HandlerMethodAspect.java:98)

这明显不科学啊?就算dubbo和zk的连接短时间内出现了问题,但是dubbo本地是有服务端列表缓存的,为什么会直接报这个没有提供者的错误呢?后续在elk上通过日志对问题进行定位,这报错在那段时间内,还真是多,而且各个soa上都出现了,怎么回事呢?通过zabbix监控看,这些服务器的cpu和内存占用并没有异常,流量也没有打满,为什么会大批量出现掉线?dubbo侧看不出来什么问题,于是决定去zk上看看。

zk的情况以及分析

登上几台zk看日志,发现每隔半小时到一小时,在某X5时间,都会出现大量断开连接的日志。

2020-05-27 14:53:20,610 [myid:1] - INFO  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxnFactory@215] - Accepted socket connection from /10.10.1.11:35730
2020-05-27 14:53:20,610 [myid:1] - WARN [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@376] - Unable to read additional data from client sessionid 0x0, likely client has closed socket
2020-05-27 14:53:20,610 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@1040] - Closed socket connection for client /10.10.1.11:35730 (no session established for client)
2020-05-27 14:53:20,917 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxnFactory@215] - Accepted socket connection from /10.10.7.51:60135
2020-05-27 14:53:20,921 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:ZooKeeperServer@938] - Client attempting to establish new session at /10.10.7.51:60135
2020-05-27 14:53:20,977 [myid:1] - INFO [CommitProcessor:1:ZooKeeperServer@683] - Established session 0x102d62c8fbab875 with negotiated timeout 10000 for client /10.10.7.51:60135

可以看到,zk的日志大量刷屏,并且都是认为是远端没有了心跳,或者心跳超时,所以主动断开了连接,这也就解释了为什么明明dubbo在消费者端是有服务列表缓存的,但是还是会报上面的异常,原来是zk认为这些提供者下线了,所以通过通知,主动把整体服务的列表都刷新了,并不是提供者和zk之间单方面的问题,那么zk为什么会出现这样的问题呢?说实话,查了非常久,也是查了好几天,最后定位在:问题暴露在每五分钟的单位时间,即最短5分钟间隔,最长60分钟间隔,都会出现大量的批量下线后再批量上线的问题,虽然过程转瞬即逝,但是还是有部分业务会被影响到。于是查看有什么东西是5分钟的,查阅资料,zk和dubbo并没有什么缺省的5分钟或者更小整数倍数是5分钟的配置,我们也没有做类似配置,最后锁定到了一个嫌疑者:

*/5 * * * * /usr/sbin/ntpdate X.X.X.X  && hwclock -w >/dev/null 2>&1

熟悉linux的同学都知道,这个是一个定时任务,用来同步服务器时钟的,每五分钟触发一次,后续经过测试发现,zk第三台机器与时钟同步机器的网络连接状况很差,所以第三台机器的时间在时钟同步后会出现波动,导致心跳机制出现问题,认为大量dubbo节点失效,所以主动踢除了这些被认为下线的节点,所以出现了如上bug。后续找网络工程师排查了服务器的网络问题后,该问题成功解决。

总结

在排查时,是真的有些乍一看让人摸不着头脑的问题,只能通过排除法以及相关信息去做推测并验证,并且客观反映了,AP较之CP,确实有其优越性,因为CP本身虽然可以保证一致性,但是谁有能保证CP自身的正确,如果CP因为某些原因自身出现了问题,那么风险也是不可承受的。这也是为什么eureka采用AP而不是CP的原因。

工作记录:记一次线上ZK掉线问题排查的更多相关文章

  1. 记一次线上频繁fullGc的排查解决过程

    发生背景 最近上线的一个项目几乎全是查询业务,并且都是大表的慢查询,sql优化是做了一轮又一轮,前几天用户反馈页面加载过慢还时不时的会timeout,但是我们把对应的sql都优化一遍过后,前台响应还是 ...

  2. 记一次线上bug排查-quartz线程调度相关

    记一次线上bug排查,与各位共同探讨. 概述:使用quartz做的定时任务,正式生产环境有个任务延迟了1小时之久才触发.在这一小时里各种排查找不出问题,直到延迟时间结束了,该任务才珊珊触发.原因主要就 ...

  3. 线上zk节点报org.apache.zookeeper.server.NIOServerCnxnFactory.run(NIOServerCnxnFactory.java:187) at java.lang.Thread.run(libgcj.so.10)

    线上zk做配置管理,最近突然发现两个节点一直在刷下边 java.nio.channels.CancelledKeyException    at gnu.java.nio.SelectionKeyIm ...

  4. 解Bug之路-记一次线上请求偶尔变慢的排查

    解Bug之路-记一次线上请求偶尔变慢的排查 前言 最近解决了个比较棘手的问题,由于排查过程挺有意思,于是就以此为素材写出了本篇文章. Bug现场 这是一个偶发的性能问题.在每天几百万比交易请求中,平均 ...

  5. 记一次线上gc调优的过程

           近期公司运营同学经常表示线上我们一个后台管理系统运行特别慢,而且经常出现504超时的情况.对于这种情况我们本能的认为可能是代码有性能问题,可能有死循环或者是数据库调用次数过多导致接口运行 ...

  6. 【MySQL】记一次线上重大事故:二狗子竟然把线上数据库删了!!

    写在前面 估计二狗子这几天是大姨夫来了,心情很郁闷,情绪也很低落,工作的时候也有点心不在焉.让他发个版本,结果,一行命令下去把线上的数据库删了!你没听错:是删掉了线上的数据库!运营那边顿时炸了锅:怎么 ...

  7. 记录一次linux线上服务器被黑事件

    1.原因:本来在家正常休息了,我们放在上海托管机房的线上服务器突然蹦了远程不了,服务启动不了,然后让上海机房重启了一次,还是直接挂了,一直到我远程上才行. 2.现象:远程服务器发现出现这类信息 Hi, ...

  8. 记一次线上Curator使用过程JVM栈溢出解决

       为了同学们看起来一目了,特按如下思路进行讲解. 1.出现的场景    2.分析及解决的过程    3.总结 最近公司要使用zookeeper做配置管理(后面简称ZK),然后自己就提前用虚拟机进行 ...

  9. 记一次线上coredump事故

    1.事故背景 上周三凌晨,我负责的某个模块在多台机器上连续发生coredump,幸好发生在业务低峰期,而且该模块提供的功能也不是核心流程功能,所以对线上业务影响比较小.发生coredump后,运维收到 ...

随机推荐

  1. Mysql锁机制--悲观锁和乐观锁

    1. 悲观锁简介 悲观锁(Pessimistic Concurrency Control,缩写PCC),它指的是对数据被外界修改持保守态度,因此,在整个数据处理过程中, 将数据处于锁定状态.悲观锁的实 ...

  2. mysql-创建用户报错ERROR 1396 (HY000): Operation CREATE USER failed for 'XXXX'@'XXXX'

    创建用户: create user 'test'@'%' identified by 'test'; 显示ERROR 1396 (HY000): Operation CREATE USER faile ...

  3. 阿里不允许使用 Executors 创建线程池!那怎么使用,怎么监控?

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 五常大米好吃! 哈哈哈,是不你总买五常大米,其实五常和榆树是挨着的,榆树大米也好吃, ...

  4. 个人微信公众号搭建Python实现 -开发配置和微信服务器转入-配置说明(14.1.2)

    @ 目录 1.查看基本配置 2.修改服务器配置 3.当上面都配置好,点击提交 4.配置如下 1.查看基本配置 登录到微信公众号控制面板后点击基本配置 这里要讲的就是订阅号 前往注册微信公众号 2.修改 ...

  5. Spring Cloud Alibaba基础教程-Nacos(三)

    在Spring Cloud Alibaba基础教程-Nacos(二)当中学习了,如何使用 nacos图形化界面操作 ,使用Nacos部署集群,下面我们开始Nacos最后一篇的学习 ,如果对你有帮助,记 ...

  6. Python进行拉勾网数据爬取框架与思路

    爬取内容 用交互式的方式输入想查询的职位并循环输出职位简要信息,为了方便阅读,本文使用到的变量并不是以目标变量的英文来命名,而是为了方便而取的变量名,各位大牛请谅解.(因贵网站爬取一定量数据后需要登陆 ...

  7. 纯Python绘制艺术感满满的山脊地图,创意满分

    1 简介 下面的这幅图是英国摇滚乐队 Joy Division 在1979年发行的其第一张录音室专辑 Unknown Pleasures 的封面,由艺术家 Peter Saville 基于射电脉冲星信 ...

  8. Arduino PROGMEM 从程序空间读取float值的方法

    方法: 使用avr-libc提供的宏定义: #define pgm_read_float_near(address_short) __LPM_float((uint16_t)(address_shor ...

  9. MySQL优化索引

    1.  MySQL如何使用索引 索引用于快速查找具有特定列值的行.如果没有索引,MySQL必须从第一行开始,然后遍历整个表以找到相关的行.表越大,花费越多.如果表中有相关列的索引,MySQL可以快速确 ...

  10. 发起一个开源项目:基于 .NET 的博客引擎 fluss

    今天我们发起一个开源项目,它的名字叫 fluss,fluss 是 river 的德语. 百川归海,每一个博客就如一条河流,输入的是文字,流出的是知识,汇入的是知识的汪洋大海. 川流不息,fluss 是 ...