问题的发现

最早问题的发现在于用户提的,用户提出他支付时支付失败,过了一会儿再试就好了,于是翻日志,查询到当时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. rman恢复实践

    1) Loss of system DATAFILE 2) Loss of non-system DATAFILE 3) Loss of a DATAFILE without Backup 4) Lo ...

  2. feign代码自动生成插件

    简介 feign对微服务之间的http调用做了一层封装,如果B项目想调用A项目的一个web服务,只需要编写对应的接口并标注FeignClient注解.但如果接口发生了变更,对应的Feign代码往往会忘 ...

  3. DRF框架笔记

    序列化器类的定义格式? 继承serializers.Serializer:字段 = serializers.字段类型(选项参数) 序列化器类的基本使用? 序列化器类(instance=None, da ...

  4. CSS3全览_动画+滤镜

    CSS3全览_动画+滤镜 目录 CSS3全览_动画+滤镜 1. 列表和生成的内容 2. 变形 3. 过渡 4. 动画 5. 滤镜, 混合, 裁剪和遮罩 6. 针对特定媒体的样式 作者: https:/ ...

  5. js第二次作业——2019.10.16

    第一题:完成省城市的三级联动(包括湖南省),附代码和效果图. 1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 </head> ...

  6. javaScript继承的几种实现方式?

    js继承总共分成5种,包括构造函数式继承.原型链式继承.组合式继承.寄生式继承和寄生组合式继承. 构造函数式继承 首先来看第一种,构造函数式继承,顾名思义,也就是利用函数去实现继承:构造函数继承,使用 ...

  7. Python面向对象:封装和多态

    一.封装 封装是隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读取和修改的访问级别. 封装就是将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进 ...

  8. matplotlib学习日记(七)---误差棒图

    (一)误差棒图----误差置信区间的表示 import matplotlib.pyplot as plt import numpy as np x = np.linspace(0.1, 0.6, 10 ...

  9. python序列(三)列表元素访问与计数

    1.使用下标直接访问列表元素,如果指定下标不存在,则抛出异常. >>> alist[3] 1 >>> alist[3]=5.5 >>> alist ...

  10. 实验1 C语言开发环境使用和编程初体验

    #include <stdio.h> #include <stdlib.h> int main() { printf ("202083290273\n2020 ,wh ...