流程图
详细流程
ConnectionPool#add(ClientConnectonsEntry entry)链接池新增链接逻辑如下
public RFuture<Void> add(final ClientConnectionsEntry entry) {
//新建一个RedissonPromise
final RPromise<Void> promise = connectionManager.newPromise();
//订阅完成后把entry放入entries
promise.addListener(new FutureListener<Void>() {
@Override
public void operationComplete(Future<Void> future) throws Exception {
entries.add(entry);
}
});
//初始化链接
initConnections(entry, promise, true);
return promise;
}
看下主要初始化的逻辑,即initConnections方法
private void initConnections(final ClientConnectionsEntry entry, final RPromise<Void> initPromise, boolean checkFreezed) {
//获取连接池中的最小空闲连结数
final int minimumIdleSize = getMinimumIdleSize(entry);
if (minimumIdleSize == 0 || (checkFreezed && entry.isFreezed())) {
initPromise.trySuccess(null);
return;
}
final AtomicInteger initializedConnections = new AtomicInteger(minimumIdleSize);
int startAmount = Math.min(50, minimumIdleSize);
final AtomicInteger requests = new AtomicInteger(startAmount);
for (int i = 0; i < startAmount; i++) {
createConnection(checkFreezed, requests, entry, initPromise, minimumIdleSize, initializedConnections);
}
}
上面的逻辑会循环创建最小空闲链接数的connection
private void createConnection(final boolean checkFreezed, final AtomicInteger requests, final ClientConnectionsEntry entry, final RPromise<Void> initPromise,
final int minimumIdleSize, final AtomicInteger initializedConnections) {
if ((checkFreezed && entry.isFreezed()) || !tryAcquireConnection(entry)) {
Throwable cause = new RedisConnectionException(
"Can't init enough connections amount! Only " + (minimumIdleSize - initializedConnections.get()) + " from " + minimumIdleSize + " were initialized. Server: "
+ entry.getClient().getAddr());
initPromise.tryFailure(cause);
return;
}
acquireConnection(entry, new Runnable() {
@Override
public void run() {
RPromise<T> promise = connectionManager.newPromise();
createConnection(entry, promise);
promise.addListener(new FutureListener<T>() {
@Override
public void operationComplete(Future<T> future) throws Exception {
if (future.isSuccess()) {
T conn = future.getNow();
releaseConnection(entry, conn);
}
releaseConnection(entry);
if (!future.isSuccess()) {
Throwable cause = new RedisConnectionException(
"Can't init enough connections amount! Only " + (minimumIdleSize - initializedConnections.get()) + " from " + minimumIdleSize + " were initialized. Server: "
+ entry.getClient().getAddr(), future.cause());
initPromise.tryFailure(cause);
return;
}
int value = initializedConnections.decrementAndGet();
if (value == 0) {
log.info("{} connections initialized for {}", minimumIdleSize, entry.getClient().getAddr());
if (!initPromise.trySuccess(null)) {
throw new IllegalStateException();
}
} else if (value > 0 && !initPromise.isDone()) {
if (requests.incrementAndGet() <= minimumIdleSize) {
createConnection(checkFreezed, requests, entry, initPromise, minimumIdleSize, initializedConnections);
}
}
}
});
}
});
}
acquireConnection的实际逻辑是使用传入entry的freeConnectionsCounter调用acquire方法
public class ClientConnectionsEntry {
private final Queue<RedisPubSubConnection> freeSubscribeConnections = new ConcurrentLinkedQueue<RedisPubSubConnection>();
private final AsyncSemaphore freeSubscribeConnectionsCounter;
private final Queue<RedisConnection> freeConnections = new ConcurrentLinkedQueue<RedisConnection>();
private final AsyncSemaphore freeConnectionsCounter;
private ConnectionManager connectionManager;
private final AtomicInteger failedAttempts = new AtomicInteger();
public ClientConnectionsEntry(RedisClient client, int poolMinSize, int poolMaxSize, int subscribePoolMinSize, int subscribePoolMaxSize,
ConnectionManager connectionManager, NodeType serverMode) {
this.client = client;
//定义一个poolMaxSize的semaphore
this.freeConnectionsCounter = new AsyncSemaphore(poolMaxSize);
this.connectionManager = connectionManager;
this.freeSubscribeConnectionsCounter = new AsyncSemaphore(subscribePoolMaxSize);
if (subscribePoolMaxSize > 0) {
connectionManager.getConnectionWatcher().add(subscribePoolMinSize, subscribePoolMaxSize, freeSubscribeConnections, freeSubscribeConnectionsCounter);
}
connectionManager.getConnectionWatcher().add(poolMinSize, poolMaxSize, freeConnections, freeConnectionsCounter);
}
public int getFreeAmount() {
return freeConnectionsCounter.getCounter();
}
//将获取connection的逻辑放入counter队列
public void acquireConnection(Runnable runnable) {
freeConnectionsCounter.acquire(runnable);
}