当前位置:网站首页>MySQL使用ReplicationConnection導致的連接失效分析與解决
MySQL使用ReplicationConnection導致的連接失效分析與解决
2022-06-23 12:41:00 【InfoQ】
問題背景

涉及的主要配置如下:
if (testWhileIdle) {
final DruidConnectionHolder holder = poolableConnection.holder;
long currentTimeMillis = System.currentTimeMillis();
long lastActiveTimeMillis = holder.lastActiveTimeMillis;
long lastExecTimeMillis = holder.lastExecTimeMillis;
long lastKeepTimeMillis = holder.lastKeepTimeMillis;
if (checkExecuteTime
&& lastExecTimeMillis != lastActiveTimeMillis) {
lastActiveTimeMillis = lastExecTimeMillis;
}
if (lastKeepTimeMillis > lastActiveTimeMillis) {
lastActiveTimeMillis = lastKeepTimeMillis;
}
long idleMillis = currentTimeMillis - lastActiveTimeMillis;
long timeBetweenEvictionRunsMillis = this.timeBetweenEvictionRunsMillis;
if (timeBetweenEvictionRunsMillis <= 0) {
timeBetweenEvictionRunsMillis = DEFAULT_TIME_BETWEEN_EVICTION_RUNS_MILLIS;
}
if (idleMillis >= timeBetweenEvictionRunsMillis
|| idleMillis < 0 // unexcepted branch
) {
boolean validate = testConnectionInternal(poolableConnection.holder, poolableConnection.conn);
if (!validate) {
if (LOG.isDebugEnabled()) {
LOG.debug("skip not validate connection.");
}
discardConnection(poolableConnection.holder);
continue;
}
}
}
本質原因
原因分析
mysql-jdbc中,數據庫驅動對連接的處理過程

public static ReplicationConnection createProxyInstance(List<String> masterHostList, Properties masterProperties, List<String> slaveHostList,
Properties slaveProperties) throws SQLException {
ReplicationConnectionProxy connProxy = new ReplicationConnectionProxy(masterHostList, masterProperties, slaveHostList, slaveProperties);
return (ReplicationConnection) java.lang.reflect.Proxy.newProxyInstance(ReplicationConnection.class.getClassLoader(), INTERFACES_TO_PROXY, connProxy);
}
ReplicationConnectionProxy的重要組成

ReplicationConnection代理對象處理過程

druid數據源對MySQ連接的檢查
public boolean isValidConnection(Connection conn, String validateQuery, int validationQueryTimeout) throws Exception {
if (conn.isClosed()) {
return false;
}
if (usePingMethod) {
if (conn instanceof DruidPooledConnection) {
conn = ((DruidPooledConnection) conn).getConnection();
}
if (conn instanceof ConnectionProxy) {
conn = ((ConnectionProxy) conn).getRawObject();
}
if (clazz.isAssignableFrom(conn.getClass())) {
if (validationQueryTimeout <= 0) {
validationQueryTimeout = DEFAULT_VALIDATION_QUERY_TIMEOUT;
}
try {
ping.invoke(conn, true, validationQueryTimeout * 1000);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
if (cause instanceof SQLException) {
throw (SQLException) cause;
}
throw e;
}
return true;
}
}
String query = validateQuery;
if (validateQuery == null || validateQuery.isEmpty()) {
query = DEFAULT_VALIDATION_QUERY;
}
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conn.createStatement();
if (validationQueryTimeout > 0) {
stmt.setQueryTimeout(validationQueryTimeout);
}
rs = stmt.executeQuery(query);
return true;
} finally {
JdbcUtils.close(rs);
JdbcUtils.close(stmt);
}
}
public MySqlValidConnectionChecker(){
try {
clazz = Utils.loadClass("com.mysql.jdbc.MySQLConnection");
if (clazz == null) {
clazz = Utils.loadClass("com.mysql.cj.jdbc.ConnectionImpl");
}
if (clazz != null) {
ping = clazz.getMethod("pingInternal", boolean.class, int.class);
}
if (ping != null) {
usePingMethod = true;
}
} catch (Exception e) {
LOG.warn("Cannot resolve com.mysql.jdbc.Connection.ping method. Will use 'SELECT 1' instead.", e);
}
configFromProperties(System.getProperties());
}
@Override
public void configFromProperties(Properties properties) {
String property = properties.getProperty("druid.mysql.usePingMethod");
if ("true".equals(property)) {
setUsePingMethod(true);
} else if ("false".equals(property)) {
setUsePingMethod(false);
}
}
解决方式
調整依賴版本
修改讀寫分離實現
拓展mysql-jdbc驅動
基於druid,拓展MySQL連接檢查
public class MySqlReplicationCompatibleValidConnectionChecker extends MySqlValidConnectionChecker {
private static final Log LOG = LogFactory.getLog(MySqlValidConnectionChecker.class);
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public boolean isValidConnection(Connection conn, String validateQuery, int validationQueryTimeout) throws Exception {
if (conn.isClosed()) {
return false;
}
if (conn instanceof DruidPooledConnection) {
conn = ((DruidPooledConnection) conn).getConnection();
}
if (conn instanceof ConnectionProxy) {
conn = ((ConnectionProxy) conn).getRawObject();
}
if (conn instanceof ReplicationConnection) {
try {
((ReplicationConnection) conn).ping();
LOG.info("validate connection success: connection=" + conn.toString());
return true;
} catch (SQLException e) {
LOG.error("validate connection error: connection=" + conn.toString(), e);
throw e;
}
}
return super.isValidConnection(conn, validateQuery, validationQueryTimeout);
}
}
边栏推荐
- Qt5 knowledge: DNS query
- 状态机框架
- Install rstudio desktop and rstudio server free version
- How should enterprises conduct efficient IT operation and maintenance management?
- R语言dplyr包mutate_all函数将dataframe中的所有数值数值列(变量)乘以某一固定值并生成新的数据列,为新的数据列(变量)指定自定义后缀名称
- UI framework
- &lt;Sicily&gt;1000. 数字反转
- 解决“Thread 1: “-[*.CollectionNormalCellView isSelected]: unrecognized selector sent to instance 0x7f”
- QT knowledge: detailed explanation of view frame qgraphicswidget
- Wallys/DR6018-S/ 802.11AX MU-MIMO OFDMA / 2* GE PORTS/WIFI 6e / BAND DUAL CONCURRENT
猜你喜欢
![Halcon principle: one dimensional function_ 1D type [1]](/img/ab/c0aee923fd0a9dd8a52b8cf31a6cd7.png)
Halcon principle: one dimensional function_ 1D type [1]

Ros2 knowledge (6): principle and practice of coordinate object TF

2D laser Slam (using laser scan matcher)

「开发者说」钉钉连接器+OA审批实现学校学生假勤场景数字化

HMS core video editing service has the ability to open templates, helping users get the same cool video with one click

Qt5 knowledge: string list qstringlistmodel

SQL adds the problem of duplicate table records.

冷板式、浸没式、喷淋式液冷散热能否引领高性能计算发展?

ROS察微【57】:配置手臂机器人来抓东西

华为云GaussDB重磅发布HTAP商用,定义云原生数据库2.0新范式
随机推荐
Unity小需求——简单实现仿王者钻石夺宝(单抽)
[no title] 2022 pressure pipeline patrol inspection and maintenance test questions and online simulation test
QT knowledge: using the qgraphicspixmapitem class
企业该如何进行高效IT运维管理?
项目测试一半,需求要变更,测试人员怎么办?
首次曝光!唯一全域最高等级背后的阿里云云原生安全全景图
HMS core video editing service has the ability to open templates, helping users get the same cool video with one click
Voice module: pyttsx sound change project
The project experience of resume and several problems that testers should pay attention to in writing
How to test the third-party payment interface?
Network foundation and framework
The median annual salary exceeds 300000, and the salary of the first AI major graduate of Nanjing University is exposed
Huawei cloud gaussdb heavily released HTAP for commercial use, defining a new paradigm of cloud native database 2.0
What should I do if a serious bug occurs within the scope of my own test and I am about to go online?
kubernetes comfig subpath
The list of open source summer winners has been publicized, and the field of basic software has become a hot application this year
R语言dplyr包arrange函数排序dataframe数据、通过多个数据列排序dataframe数据(默认是升序排序)
Deep thinking: in-depth analysis of some scenes in Gaia Altman and the philosophy and perception reflected
深入思考:《盖亚奥特曼》中部分情景深度分析及反射出的哲理与感悟
协程