我们都知道 DDM 是华为云分布式数据库中间件,在性能、易用性等方面在业界是遥遥领先的。他的成熟不仅仅体现在具有快速水平平滑扩容、支持多种分布式事物类型等等这些高大上的特性上,也体现在 DDM 诸多的细微之处,今天我和大家分享一个在发展多年的 mycat 上存在,但是在 DDM 中不存在的一个不起眼的细微问题(小问题,大灾难,在 IT 行业的历史上不断重演,我们要警钟长鸣)。这个问题是我在 DDM 上玩了好多 sql 之后,发现 DDM 是一个玩不死的小强,出于好奇也把一些在 DDM 上玩的 sql 放到了 mycat 上,不幸的是,第一条 sql 放到了 mycat 上执行之后,就出现了神奇一幕,下面看看我的排查过程吧。
排查过程
首先,我的测试代码如下,我的 sql 除了加了一段注释之外,好像再普通不过了。但是一执行发现好像是卡主了。
于是赶紧使用 jstack 查看测试应用的线程栈信息,如下:
由上图不难发现是卡在测试代码 TestJDBC 的 25 行上,也就是卡在了“ps.executeQuery()”这行代码上。当然也发现最终是卡在和 mycat 的通信上。那么为啥 mycat 一直没有返回结果呢。我马上到部署 mycat 的测试机上,查看日志,没有发现异常信息。于是顺手看了一下测试机器的资源使用情况,果然有意外发现,如下:
发现有一个 java 进程的 cpu 使用率非常高,在这里,他肯定是 mycat 进程,因为在这个机器上,我只部署了 mycat 这一个 java 应用。不禁要问,mycat 到底在干啥,是哪一个线程出现了问题。于是我执行了一下这样的一条命令:ps -mp 3403 -o THREAD,tid,time,想去看个究竟,命令中的 3403 是 mycat 进程的 id,于是我发现了下图的信息。
发现 3403 进程中的线程 3420 消耗了非常高的 CPU,接下来不难想到的是使用 jstack 命令去调出该 mycat 进程的线程栈信息,在执行 jstack 之前,我们先将线程 id(nid) 3420 转成 16 进制的数字,因为在 jstack 中看到的 nid(native thread id)是 16 进制显示的,转换方式如下:
那好,让我们来看一下 mycat 进程的该线程的栈快照吧,如下:
原来问题出在了 DruidMycatRouteStrategy 这个类的 724 行,于是看一下 mycat 的源码,如下:
看到代码之后,是不是恍然大悟呢,问题就出在这个 while 循环的处理逻辑上。当然这个 bug 的 fix 也不复杂。对该问题解决方式有兴趣的朋友可以在该文章下留言,我们可以交流一下。
结语
通过上面这样的一个问题,我们不难发现,现在业界的分布式数据库中间件在大的特性上基本都能做到对齐,那么为什么华为云分布式数据库中间件 DDM 作为后起之秀,显得更加成熟,给用户留下了更好的印象呢?我想可能跟 DDM 在诸如此类的非常多的细微之处做的非常到位也有原因吧。
本文转载自公众号中间件小哥(ID:huawei_kevin)。
原文链接:
https://mp.weixin.qq.com/s/NEZUorxh5FuxRpIdAA5cCg
评论