一个MySQL JDBC驱动bug引起的血案

 

    1. 问题背景

公司是做电商系统的,整个系统搭建在华为云上。系统设计的时候,考虑到后续的用户和订单数量比较大,需要使用一些大数据库的组件。关系型数据库这块,考虑到后续数据量的快速增长,不是直接写入MySQL,而是使用了华为云的分布式数据库中间件DDM。

使用了DDM之后,可以在业务不感知的情况下,直接增加MySQL读实例的个数,线性提升读性能。也支持中间件层面的分库分表,提供海量关系型数据库的操作。简直是为电商系统贴身定制的。

DDM自身是以集群形式提供服务的,对业务开放的是多个连接IP地址。需要有一层负载均衡。如果使用传统的加LB的形式做负载均衡,会多一层中转,有性能损耗。所以,直接使用了MySQL-JDBC提供的客户端负载均衡能力。逻辑结构如下图所示:

 

业务通过MySQL-JDBC的Loadbalance能提访问多个DDM节点。MySQL-JDBC提供负载均衡能力。

    1. 问题说明

使用MySQL客户端负载均衡力能,一直运行得好好,性能嗷嗷叫。可是前一阵子,无故出现了业务请求失败。我是负责电商订单模块的,涉及到真实的Money,这个问题吓了宝宝一身冷汗。。赶紧查看后台日志,发现是访问DDM出现了异常,二话不说直接提了工单给华为云DDM服务。

[WARN] [2018-07-08 23:11:29] [MySqlValidConnectionChecker:isValidConnection()] [DubboServerHandler-172.31.0.146:8080-thread-64-txId=00000000657615aa] Unexpected error in ping

java.lang.reflect.InvocationTargetException

         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

         at java.lang.reflect.Method.invoke(Method.java:498)

         at com.alibaba.druid.pool.vendor.MySqlValidConnectionChecker.isValidConnection(MySqlValidConnectionChecker.java:98)

         at com.alibaba.druid.pool.DruidAbstractDataSource.testConnectionInternal(DruidAbstractDataSource.java:1252)

         at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:981)

 

不得不说,华为云的服务还是很好的,不到半个小时就联系了我,还跟我一起排查问题。

将我们业务的日志取下来,和DDM的支撑人员一起分析,发现报错如下:

根本原因竟然是MySQL驱动的bug,导致StackOverflow本地栈溢出导致,真是误会了DDM服务,抱歉了。

Caused by: java.lang.StackOverflowError

         at com.mysql.jdbc.StringUtils.getBytes(StringUtils.java:2360)

         at com.mysql.jdbc.StringUtils.getBytes(StringUtils.java:2344)

         at com.mysql.jdbc.StringUtils.getBytes(StringUtils.java:568)

         at com.mysql.jdbc.StringUtils.getBytes(StringUtils.java:626)

         at com.mysql.jdbc.Buffer.writeStringNoNull(Buffer.java:670)

         at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2636)

     &

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值