当前位置: 首页 > 科技观察

MySQL-CommunicationsException的三种典型场景及解决方法

时间:2023-03-12 02:43:10 科技观察

我们在使用MySQL数据库的时候,偶尔会遇到com.mysql.jdbc.exceptions.jdbc4.CommunicationsException。下面总结一下出现异常的场景和解决方法,希望能起到抛砖引玉的作用。场景一场景描述wait_timeout异常根源分析原因是数据库连接空闲时间超过MySQL服务器配置的wait_timeout,即上图中【2.3数据库操作】的时间【减去][1.5放入连接池]时间[大于]wait_timeout。解决方法一对于mysql5之前的版本,可以直接在jdbcurl的配置中加上“autoReconnect=true”。方法二:将mysql全局变量wait_timeout的值修改为最大。显示全局变量,如“wait_timeout”;方法三【建议解决】当前项目使用的数据库连接池是druid,用于解决该异常的配置项如下:配置默认值表示使用validationQuery检测连接是否有效。SQL,要求是一条查询语句,一般选择'x'。如果validationQuery为null,则testOnBorrow、testOnReturn、testWhileIdle将不起作用。testWhileIdlefalse建议配置为true,不影响性能,保证安全。申请连接时勾选。如果空闲时间大于timeBetweenEvictionRunsMillis,则执行validationQuery检查连接是否有效。timeBetweenEvictionRunsMillis1分钟有两个含义:1)Destroy线程会检测连接间隔,如果连接空闲时间大于等于minEvictableIdleTimeMillis,则关闭物理连接。2)testWhileIdle的判断依据,详见testWhileIdle属性的描述。minEvictableIdleTimeMillis连接保持空闲不被逐出的最短时间场景二场景二描述应用阻塞无响应根本原因分析客户端发送select语句后,服务端向客户端写入大量数据,客户端需要等待超过1分钟再继续写入,服务器会直接关闭等待写入超过1分钟(默认值)的连接。为什么超过1分钟?根本原因是jdbc程序在接收大量数据时消耗了大量的CPU和内存资源,同时还需要不断的做GC,导致接收卡顿。一旦GC时间超过net_write_timeout,mysql就会关闭连接。根本原因解决方法1根据业务场景增加net_write_timeoutGLOBALnet_write_timeout=180;选择@@global.net_write_timeout;选择@@session.net_read_timeout;showvariableslike'%timeout%'方法二【建议方案】根据业务场景,优化应用。优化方向:优化SQL,通过分页减少查询返回数据量,优化应用,减少应用停顿时间场景三种场景描述SSL问题分析MySQL服务器版本如5.6.25及之前或5.7.5及之前,客户端连接属性useSSL默认为false;对于5.6.25+或5.7.5+等MySQL服务器版本,客户端连接属性useSSL默认为true。默认MySQL服务器版本useSSL=true,客户端连接属性还需要配置其他附加连接属性,如果不配置,会抛出CommunicationsException。解决方法一在不需要SSL连接的场景下,显示并设置useSSL=false方法二在需要SSL连接的场景下,客户端和服务端都需要正确配置。具体配置请参考官网文档:ConnectingSecurelyUsingSSL:https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-using-ssl.html