最近上线遇到一个问题,线上服务有一半能提供服务,有一半不能提供服务,如果是一个service有些用户有问题,那说明是有一部分用户例如活跃用户某些数据特别大导致,但现在情况不是。否定掉了是有大key或者大value导致超时异常。
线上异常代码层面都进行了捕获,并且下游请求来了,没有返回就直接不见了也没有异常信息。经分析应该是两种情况:一种是修改代码影响了微服务框架导致流量异常,另一种是修改代码本身影响了线上服务。
从影响微服务角度去看的话,分析存在一种可能就是影响了负载均衡算法,微服务负载均衡算法受影响,打到机器上的量减少导致不变,很快被否定掉,通过加上微服务调用次数监控,发现有问题机器进入调用次数和其他机器一样,那么能够确认负载均衡算法未被影响。那么进一步也缩小了范围,还是我们逻辑变化导致线上问题。
一个新的比较复杂复杂情况,经过分析发现是有些机器有问题,并且调整逻辑后仍然是那部分机器有问题,那就说明问题本身是和机器相关的,并且把服务撤回以前版本,服务是没有问题的。能够在这台机器上稳定出现,这是很神奇的一点,说明是和做在机器有一定关系的,单具体是什么关系不能确定。
经过服务本身监控,请求量与其他正常机器一样,说明是我们服务本身吞噬了请求。再次缩小了范围,说明还是我们服务本身存在问题。
经过上边一系列排除法,能够确认,它是一种我们修改程序引入的,并且和机器存在一定关系的bug,通过分析这次上线与前一次上线的差异,定位一个jar包两个版本可能存在冲突,去掉老的版本上线,线上服务调用量恢复正常,基本定位了问题,为什么不是所有机器都有问题,二是一部分机器有问题,需要在进行定位确认。
问题是jvm加载jar包导致,有的加载成功有的加载失败,说明jar加载在不同机器上是不同的,那么下一步的问题就是,jvm加载jar包原理机制是什么?
jvm加载jar包顺序问题,然后又深入下去发现是jvm在不同机器上加载jar包顺序与文件系统存在关系,基本就能确定问题。jvm在linux通过jar文件在文件系统中生成顺序来进行加载,在linux底层是inode数据机构,详见Jvm加载jar包的顺序,这篇文章有详细记录,介绍了jvm在linux下加载jar方式。文章作者与笔者遇到类似问题。
问题从发生到定位花了较长时间,这个bug确实很神奇。现在复盘来看,主要是我们对于jvm、类加载机制,缺少深入了解,导致bug定位时间较长,后续要加强对于底层jvm各种机制原理理解,以方便快速定位线上问题。
再有就是要加强代码review,设计实现review,通过审查避免一些问题,也是我们需要加强的方面。
这样一个问题本身也说明了对于技术进行深挖的价值,对整个链条越理解,越是能找到薄弱点优化点,而不是为了轮子而轮子,为了架构而架构,进行合理并且不浪费的设计,才是合理的设计,过少或者过于复杂过多设计都不是好设计。
其实对于我们用的每一个东西,每一个技术都应该去花时间、花心思去理解,去深挖,一是有更多收获,一是能避免更多问题。也能快速提升我们能力,与自身价值,深入下去越深越美。
最近也在指定kpi考核,kpi也进行了很多思索怎样不沦为一个形式化的东西,真正能衡量技术、技术人员价值,给技术研发带来正向效果,在这次设定kpi的时候也做了更多的思考,研发人员,一是给出简洁清晰的架构与设计,再有就是给出优美容易懂的代码实现,良好的沟通表达能力,再有就是新技术使用认知以及新技术探索,基础能力,技术人最终要最有价值还是给出优秀架构简洁有力的实现,就是对于业务最大的价值,也能给技术人员本身带来大的提升。