共计 1459 个字符,预计需要花费 4 分钟才能阅读完成。
自动写代码机器人,免费开通
这篇文章给大家分享的是有关 MySQL-JDBC 驱动引起 bug 问题的示例的内容。丸趣 TV 小编觉得挺实用的,因此分享给大家做个参考,一起跟随丸趣 TV 小编过来看看吧。
问题背景
公司是做电商系统的,整个系统搭建在华为云上。系统设计的时候,考虑到后续的用户和订单数量比较大,需要使用一些大数据库的组件。关系型数据库这块,考虑到后续数据量的快速增长,不是直接写入 MySQL,而是使用了华为云的分布式数据库中间件 DDM。使用了 DDM 之后,可以在业务不感知的情况下,直接增加 MySQL 读实例的个数,线性提升读性能。也支持中间件层面的分库分表,提供海量关系型数据库的操作。简直是为电商系统贴身定制的。
DDM 自身是以集群形式提供服务的,对业务开放的是多个连接 IP 地址。需要有一层负载均衡。如果使用传统的加 LB 的形式做负载均衡,会多一层中转,有性能损耗。所以,直接使用了 MySQL-JDBC 提供的客户端负载均衡能力。
逻辑结构如下图所示:
▲业务通过 MySQL-JDBC 的 Loadbalance 能提访问多个 DDM 节点。MySQL-JDBC 提供负载均衡能力。
问题说明
MySQL JDBC 驱动的客户端负载均衡能力,一直运行得好好,性能嗷嗷叫。可是前一阵子竟无故出现业务请求失败。我是负责电商订单模块的,涉及到真实的 Money,这个问题可吓了宝宝一身冷汗……
于是赶紧查看了后台日志,发现是访问 DDM 出现了异常,二话不说直接提了工单给华为云 DDM 服务。
不得不说,华为云的服务还是很好的,不到半个小时就有专门的工作人员联系了我,还跟我一起排查问题。
将我们业务的日志取下来,和 DDM 的支撑人员一起分析,发现报错如下:根本原因竟然是 MySQL 驱动的 bug,导致 StackOverflow 本地栈溢出导致……原来是一个 Bug 引发的血案,误会了 DDM 服务,真是抱歉了
从堆栈可以看出来,某个异常,触发了 MySQL-JDBC 的 bug,导致循环调用,直至栈溢出。在华为 DDM 支撑人员的建议下,对驱动代码进行了反编译,从反编译的情况下,可以看到的确是存在循环嵌套的可能。
Loadbalance 轮询连接 – 同步新老连接的状态 – 发送 sql 给服务端 – Loadbalance 轮询连接。
相关代码如下:
这么明显的 bug,不太相信 MySQL 会没有发现。当前我们使用的是 5.1.44 版本的驱动,查看了下最新的 5.1.66 的代码,发现的确是修复了这个问题的,代码如下:
通过过滤掉 SET 和 SHOW 语句,避免了循环嵌套的发生。
但是 5.1.66 又引入了新的 bug,由于并不是每个调用 postProcess 的地方都有 SQL,这里的代码会抛空指针异常。MySQL JDBC 的开发者都不做测试的吗……
没办法,分析了下 5.1.44 的代码,发现通过适当的调整 loadBalanceAutoCommitStatementThreshold 这个参数的数值,也可以避免循环嵌套的发生。我们的环境改成了 5,修改之后,平稳运行 1 周,没再出现过问题。
修改方案
loadBalanceAutoCommitStatementThreshold 修改成了 5,但是引入的问题是,如果业务包含一些比较耗时的 SQL,可能会导致 DDM 的负载不均衡。不过,就目前情况来看,DDM 的性能还是比较强劲的~
感谢各位的阅读!关于“MySQL-JDBC 驱动引起 bug 问题的示例”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!
向 AI 问一下细节