剧情需要剧本。该脚本显示您负责技术部门的链接跟踪系统和数据库中间件。剧情是你日常工作中的排错体验……刚刚看了这么多,导演大喊:“男主,请就位……准备!行动!你:哇,我要开始行动了现在?”1.问题开始记得那是一个阳光明媚的下午...突然把你拉进了一个临时工作组,窗口里飞快的跳出一条信息:@老张binlog字段更新,读db时却不能阅读。记得你作为男主,在剧本的这一章里叫老张。看到这条消息后,你的大脑开始对这些关键词进行拆解:应用A将MySQL中x记录中的y字段更新为canal(canal是什么?下面介绍)监听DB中的订单记录变更事件,发送到MQ应用B消费这个MQ,收到这个消息后,从MySQL中查询这条x记录但是!!!没有读到y字段的更新值同时,你大脑的另一个区域也勾勒出如下数据流图:当你对这个问题有了初步的了解后,脑子里就冒出一连串的问题条件反射,赶紧在群里发出来:对业务有严重影响吗?系统最近有变化吗?这是个人创纪录的现象吗?以前发生过吗?什么是traceId?我得到的答复是:问题并不严重。最近没有变化。这是个人创纪录的现象。好像没遇到过。我没有连接过SkyWalking(什么是SkyWalking,下面会介绍),现有的日志也没有什么猫腻。看完前4个答案,你松了一口气,没有什么大的影响,紧张的情绪也有所缓解;但同时你也意识到没有直观的链接跟踪数据,想弄清楚这个问题有点麻烦。1.1Canal知识补充:官方介绍:canal[k?'n?l],译为水路/管道/沟渠,主要用于提供基于MySQL数据库增量日志解析的增量数据订阅和消费。早期由于杭州和美国双机房的部署,有跨机房同步的业务需求。实现方式主要是基于业务触发器获取增量变化。从2010年开始,业务逐渐尝试解析数据库日志获取增量变化进行同步,并由此衍生出大量的增量数据库订阅消费业务。canal官网icon.pnggithub地址:https://github.com/alibaba/canal1.2SkyWalking知识补充:SkyWalking是一个可观察性平台(ObservabilityAnalysisPlatform(OAP)andapplicationperformancemanagement(APM))。提供分布式链路跟踪、ServiceMesh遥测分析、Metric聚合和可视化的一体化解决方案。下图是其linktracking的展示效果。通过它可以直观的看到一个请求的完整执行轨迹,经过了哪些应用,访问了哪些中间件,请求的关键信息是什么,每个环节的执行时间是多少,是否异常,etc.github地址:https://skywalking.apache.org/2.查询调查2.1整理数据流由于应用没有接入SkyWalking,缺乏直观完整的trace信息的帮助,只能通过低效的整理和人工查询。哪些应用,什么类型的DB,数据流向,经过一番沟通,了解到情况如下:,并从binlog中感知到x记录变化信息后,发送给MQ应用B来消费这个MQ。收到这条消息后,会在处理流程中请求应用A的Dubbo接口查询一些信息。应用A收到Dubbo请求后,也会从MySQL中查询这条x订单记录,但是!!!读出的status字段还是cccDB,读写分离。MySQL主从同步采用的异步同步方式2.2锁定可疑链接可以看出读取数据有3种方式:6.1读取缓存6.2读取从库6.3读取主库想了想,你推测是6.1或6.2这两种方式很可能读取到旧值,所以你开始检查。2.3排查Mybatis缓存问题根据经验可以猜到6.1读取新数据失败的可能性最大。缓存通常包括进程内缓存、Redis缓存、Mybatis缓存。经过进一步沟通,确认应用A没有使用内存缓存和Redis缓存。同事甚至怀疑数据库中间件是否有缓存。这个怀疑被你直接排除了(数据库中间件没有缓存),然后Mybatis缓存就可疑了,于是你赶紧从大脑的知识库中找出Mybatis二级缓存的机制原理。2.3.1排除一级缓存的嫌疑。默认启用一级缓存。是不是一级缓存的问题?你继续分析:按照现有的mapper用法,一个request中的所有CRUD操作都在同一个sqlSession中,一个sqlSession中的所有查询操作都会保存在这个sqlSession中的缓存中,即每个请求都有一个专门的一级缓存对每个请求都是隔离的,互不干扰。在x记录更新之前,应用A的查询请求中的一级缓存数据不会被x记录更新后的应用A的查询请求访问到。.经过这样的梳理分析,你已经排除了Mybatis一级缓存可能导致这个问题的可能性。2.3.2排除二级缓存的嫌疑那你继续查看是不是二级缓存导致的。你的知识库显示,二级缓存在sqlSession之外,由sqlSession共享,即多个请求可以共享同一个二级缓存,一级缓存和二级缓存的配合机制如下:缓存的数据通过sqlSession首先放入一级缓存,当sqlSession会话提交或关闭时,一级缓存数据会同步到二级缓存。去二级缓存里找,找不到就去一级缓存里搜索,读取二级缓存.png好像时间差匹配的话,疑似二级缓存很高。是不是二级缓存的问题?这时候一个知识点正狠狠地敲你的脑子【需要手动开启二级缓存】,于是你连忙问应用A是否开启了二级缓存,同事却想不通暂时不知道这个开关的知识,所以大家把如何开启二级缓存的说明发出来:打开单个mapper在需要开启二级缓存的XXXmapper.xml文件中添加如下配置
