Skip to content

Commit 4e8050f

Browse files
committed
feat: optimize health schedule task
1 parent 8c44c03 commit 4e8050f

File tree

3 files changed

+107
-12
lines changed

3 files changed

+107
-12
lines changed

lb-driver/src/main/java/com/netease/nim/lbd/ConnectionManager.java

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22

33
import com.netease.nim.lbd.util.AdjustCount;
44
import com.netease.nim.lbd.util.AutoAdjustQueue;
5+
import com.netease.nim.lbd.util.CloseUtils;
56
import com.netease.nim.lbd.util.NamedThreadFactory;
67
import org.slf4j.Logger;
78
import org.slf4j.LoggerFactory;
89

10+
import java.sql.ResultSet;
911
import java.sql.SQLException;
12+
import java.sql.Statement;
1013
import java.util.*;
1114
import java.util.concurrent.ConcurrentHashMap;
1215
import java.util.concurrent.Executors;
@@ -316,8 +319,6 @@ private AtomicInteger getConnectErrorCount(SqlProxy sqlProxy) {
316319
return count;
317320
}
318321

319-
320-
321322
//定时检查所有的sql-proxy是否可达
322323
private void checkReachable() {
323324
if (healthCheckStatus.compareAndSet(false, true)) {
@@ -331,7 +332,7 @@ private void checkReachable() {
331332
if (!pool.isOnline()) {
332333
continue;
333334
}
334-
boolean reachable = checkReachable0(sqlProxy);
335+
boolean reachable = checkReachable0(sqlProxy, pool);
335336
lock.lock();
336337
try {
337338
if (reachable && !pool.isReachable()) {
@@ -354,17 +355,44 @@ private void checkReachable() {
354355
}
355356

356357
//检查sql proxy是否可达
357-
private boolean checkReachable0(SqlProxy sqlProxy) {
358-
RealConnection realConnection = new RealConnection(sqlProxy, LBDriverEnv.getRealDriver(), lbDriverUrl);
358+
private boolean checkReachable0(SqlProxy sqlProxy, SqlProxyConnectionPool pool) {
359+
RealConnection connection;
360+
if (pool == null) {
361+
connection = new RealConnection(sqlProxy, LBDriverEnv.getRealDriver(), lbDriverUrl);
362+
} else {
363+
connection = pool.checkReadableConnection;
364+
if (connection == null) {
365+
connection = new RealConnection(sqlProxy, LBDriverEnv.getRealDriver(), lbDriverUrl);
366+
pool.checkReadableConnection = connection;
367+
}
368+
}
369+
ResultSet rs = null;
370+
Statement stmt = null;
371+
boolean reachable;
372+
boolean exception = false;
359373
try {
360-
realConnection.syncCreating();
361-
return true;
374+
connection.syncCreating();
375+
stmt = connection.getPhysicalConnection().createStatement();
376+
rs = stmt.executeQuery(Constants.VALIDATION_QUERY);
377+
reachable = rs.next();
362378
} catch (Exception e) {
379+
exception = true;
380+
reachable = false;
381+
}
382+
if (!reachable) {
363383
logger.warn("sql proxy = {} not reachable", sqlProxy);
364-
return false;
365-
} finally {
366-
realConnection.close();
367384
}
385+
CloseUtils.close(rs);
386+
CloseUtils.close(stmt);
387+
if (pool == null) {
388+
CloseUtils.close(connection);
389+
} else {
390+
if (exception) {
391+
CloseUtils.close(connection);
392+
pool.checkReadableConnection = null;
393+
}
394+
}
395+
return reachable;
368396
}
369397

370398
//定时检查是否连接数均衡
@@ -474,21 +502,33 @@ private void checkSqlProxyListFromProvider() {
474502
private void removeOfflineSqlProxy() {
475503
try {
476504
Set<SqlProxy> set = new HashSet<>(poolMap.keySet());
505+
Set<RealConnection> toClosedConnection = new HashSet<>();
506+
Set<SqlProxy> offlinedSqlProxySet = new HashSet<>();
477507
for (SqlProxy sqlProxy : set) {
478508
lock.lock();
479509
try {
480510
SqlProxyConnectionPool pool = poolMap.get(sqlProxy);
481511
if (pool != null && !pool.isOnline() && pool.isConnectionZero()) {
482512
poolMap.remove(sqlProxy);
483513
connectErrorCountMap.remove(sqlProxy);
484-
logger.info("offline sql proxy = {} removed for connection 0", sqlProxy);
514+
RealConnection removed = pool.checkReadableConnection;
515+
if (removed != null) {
516+
toClosedConnection.add(removed);
517+
}
518+
offlinedSqlProxySet.add(sqlProxy);
485519
}
486520
} catch (Exception e) {
487521
logger.error("remove offline sql proxy error, sql proxy = {}", sqlProxy, e);
488522
} finally {
489523
lock.unlock();
490524
}
491525
}
526+
for (SqlProxy sqlProxy : offlinedSqlProxySet) {
527+
logger.info("offline sql proxy = {} removed for connection 0", sqlProxy);
528+
}
529+
for (RealConnection realConnection : toClosedConnection) {
530+
CloseUtils.close(realConnection);
531+
}
492532
} catch (Exception e) {
493533
logger.error("remove offline sql proxy error", e);
494534
}
@@ -500,7 +540,7 @@ private void addSqlProxy(List<SqlProxy> list) {
500540
return;
501541
}
502542
for (SqlProxy sqlProxy : list) {
503-
boolean reachable = checkReachable0(sqlProxy);
543+
boolean reachable = checkReachable0(sqlProxy, null);
504544
lock.lock();
505545
try {
506546
SqlProxyConnectionPool pool = poolMap.get(sqlProxy);
@@ -613,6 +653,9 @@ private class SqlProxyConnectionPool {
613653
private final AtomicLong closeCount = new AtomicLong(0);
614654
private final AtomicLong reuseCount = new AtomicLong(0);
615655

656+
//用于检测健康检查的链接
657+
private RealConnection checkReadableConnection;
658+
616659
//空闲的连接
617660
private final Deque<RealConnection> idleConnections = new ArrayDeque<>();
618661
//使用中的连接

lb-driver/src/main/java/com/netease/nim/lbd/Constants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ public class Constants {
1414

1515
public static final String MYSQL_DRIVER_URL_PREFIX = "jdbc:mysql://";
1616

17+
public static final String VALIDATION_QUERY = "/* ping */ SELECT 1";
18+
1719
public static final UnsupportedMethodBehavior UNSUPPORTED_METHOD_BEHAVIOR = UnsupportedMethodBehavior.ThrowException;
1820
public static final boolean LOG_STATS = false;
1921
public static final int CHECK_BALANCE_INTERVAL_SECONDS = 10;
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.netease.nim.lbd.util;
2+
3+
import com.netease.nim.lbd.RealConnection;
4+
import org.slf4j.Logger;
5+
import org.slf4j.LoggerFactory;
6+
7+
import java.sql.ResultSet;
8+
import java.sql.Statement;
9+
10+
/**
11+
* Created by caojiajun on 2026/1/9
12+
*/
13+
public class CloseUtils {
14+
15+
private static final Logger logger = LoggerFactory.getLogger(CloseUtils.class);
16+
17+
public static void close(Statement statement) {
18+
if (statement == null) {
19+
return;
20+
}
21+
try {
22+
statement.close();
23+
} catch (Exception e) {
24+
logger.debug("close statement error", e);
25+
}
26+
}
27+
28+
public static void close(ResultSet resultSet) {
29+
if (resultSet == null) {
30+
return;
31+
}
32+
try {
33+
resultSet.close();
34+
} catch (Exception e) {
35+
logger.debug("close result set error", e);
36+
}
37+
}
38+
39+
public static void close(RealConnection connection) {
40+
if (connection == null) {
41+
return;
42+
}
43+
try {
44+
connection.close();
45+
} catch (Exception e) {
46+
logger.debug("close real connection error", e);
47+
}
48+
}
49+
50+
}

0 commit comments

Comments
 (0)