更新时间:2022-08-12 gmt 08:00
如何解决jdbc驱动方式连接ddm异常问题-凯发k8国际娱乐官网入口
mysql驱动( jdbc)通过loadbalance方式连接ddm,在某些场景下连接切换时会陷入死循环,最终导致栈溢出。
问题定位
- 查看app日志,定位异常原因。
例如,从以下日志中分析出异常最终原因为栈溢出。
caused by: java.lang.stackoverflowerror at java.nio.heapbytebuffer.
(heapbytebuffer.java:57) at java.nio.bytebuffer.allocate(bytebuffer.java:335) at java.nio.charset.charsetencoder.encode(charsetencoder.java:795) at java.nio.charset.charset.encode(charset.java:843) at com.mysql.jdbc.stringutils.getbytes(stringutils.java:2362) 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) - 分析溢出源。
例如,从以下日志可以分析出,溢出原因为驱动内部陷入死循环。
at com.mysql.jdbc.loadbalancedconnectionproxy.picknewconnection(loadbalancedconnectionproxy.java:344) at com.mysql.jdbc.loadbalancedautocommitinterceptor.postprocess(loadbalancedautocommitinterceptor.java:104) at com.mysql.jdbc.mysqlio.invokestatementinterceptorspost(mysqlio.java:2885) at com.mysql.jdbc.mysqlio.sqlquerydirect(mysqlio.java:2808) at com.mysql.jdbc.connectionimpl.execsql(connectionimpl.java:2483) at com.mysql.jdbc.connectionimpl.setreadonlyinternal(connectionimpl.java:4961) at com.mysql.jdbc.connectionimpl.setreadonly(connectionimpl.java:4954) at com.mysql.jdbc.multihostconnectionproxy.syncsessionstate(multihostconnectionproxy.java:381) at com.mysql.jdbc.multihostconnectionproxy.syncsessionstate(multihostconnectionproxy.java:366) at com.mysql.jdbc.loadbalancedconnectionproxy.picknewconnection(loadbalancedconnectionproxy.java:344)
- 查看使用的mysql版本,为5.1.44。
查看该版本源代码,发现获取连接时,loadbalance会根据负载均衡策略更新连接,并将老连接的配置复制给新连接,在新连接autocommit为true,新连接部分参数和老连接不一致,loadbalanceautocommitstatementthreshold参数没有配置的场景下,会陷入死循环,更新连接函数调用同步参数函数,同步参数又调用更新连接,最终导致栈溢出。
解决方法
在连接ddm的url添加loadbalanceautocommitstatementthreshold=5&retriesalldown=10参数。
//使用负载均衡的连接示例 //jdbc:mysql:loadbalance://ip1:port1,ip2:port2..ipn:portn/{db_name} string url = "jdbc:mysql:loadbalance://192.168.0.200:5066,192.168.0.201:5066/db_5133?loadbalanceautocommitstatementthreshold=5&retriesalldown=10";
- loadbalanceautocommitstatementthreshold:表示连接上执行多少个语句后会重新选择连接。
假设loadbalanceautocommitstatementthreshold设为5,则当执行5个sql后(queries或者updates等),将会重新选择连接。若为0表示“粘性连接,不重新选择连接”。关闭自动提交时(autocommit=false)会等待事务完成再考虑是否重新选择连接。
父主题:
意见反馈
文档内容是否对您有帮助?
提交成功!非常感谢您的反馈,我们会继续努力做到更好!
您可在查看反馈及问题处理状态。
系统繁忙,请稍后重试
如您有其它疑问,您也可以通过华为云社区问答频道来与我们联系探讨
more