当前位置:网站首页>2、 Hikaricp source code analysis of connection acquisition process II
2、 Hikaricp source code analysis of connection acquisition process II
2022-06-25 19:10:00 【User 1422411】
Welcome to my blog , Synchronize updates : Fengshan bieyuan
Source code version 2.4.5-SNAPSHOT
HikariPool Of getConnection() Method
In the last article 《HikariCP Get the connection process source code analysis 1 》 in , We analyzed HikariDataSource Of getConnection() Method , And this method , In fact, the detailed implementation details are HikariPool Of getConnection() In the method , Let's analyze HikariPool Of getConnection() Method .
The code is as follows :
public final Connection getConnection() throws SQLException {
return getConnection(connectionTimeout);
} Here we call a parameter getConnection() Method , But we didn't pass the parameters connectionTimeout, Where did this come from ? This is actually the parameter set by the user when initializing the connection pool connectionTimeout, It indicates the timeout time for obtaining the connection , If not configured, the default value is 30 second . Let's keep looking getConnection(connectionTimeout); The implementation of the :
public final Connection getConnection(final long hardTimeout) throws SQLException {
//①
// Apply for a token when getting a connection , This is mainly used when the connection pool is suspended , Control user cannot get connection
// When the connection pool is suspended , Semaphore Of 10000 Each token will be occupied , Here the thread will be blocked all the time waiting for the token
suspendResumeLock.acquire();
// Record the start time of getting the connection , For timeout judgment
final long startTime = clockSource.currentTime();
try {
long timeout = hardTimeout;
do {
//②
// Get connection from connection pool , Timeout time timeout
final PoolEntry poolEntry = connectionBag.borrow(timeout, MILLISECONDS);
//borrow Method returns only when it times out null
if (poolEntry == null) {
break; // We timed out... break and throw exception
}
final long now = clockSource.currentTime();
//③
// When you get the connection , Determine whether the connection has been marked for removal
if (poolEntry.isMarkedEvicted() || (clockSource.elapsedMillis(poolEntry.lastAccessed, now) > ALIVE_BYPASS_WINDOW_MS && !isConnectionAlive(poolEntry.connection))) {
// If the connection exceeds maxLifetime, Or the connection test fails , Just close the connection
closeConnection(poolEntry, "(connection is evicted or dead)"); // Throw away the dead connection (passed max age or failed alive test)
// Time out remaining
timeout = hardTimeout - clockSource.elapsedMillis(startTime);
} else {
//④
// Record connection borrowing
metricsTracker.recordBorrowStats(poolEntry, startTime);
// establish ProxyConnection, ProxyConnection yes Connection Packaging , At the same time, it also creates a scheduled task for leak detection
return poolEntry.createProxyConnection(leakTask.schedule(poolEntry), now);
}
} while (timeout > 0L);
} catch (InterruptedException e) {
throw new SQLException(poolName + " - Interrupted during connection acquisition", e);
} finally {
// Release the lock
suspendResumeLock.release();
}
//⑤
// The following code will not be executed until the connection timeout is obtained
logPoolState("Timeout failure ");
metricsTracker.recordConnectionTimeout();
String sqlState = null;
final Throwable originalException = getLastConnectionFailure();
if (originalException instanceof SQLException) {
sqlState = ((SQLException) originalException).getSQLState();
}
final SQLException connectionException = new SQLTransientConnectionException(poolName + " - Connection is not available, request timed out after " + clockSource.elapsedMillis(startTime) + "ms.", sqlState, originalException);
if (originalException instanceof SQLException) {
connectionException.setNextException((SQLException) originalException);
}
throw connectionException;
}①Semaphore
suspendResumeLock.acquire();
// Record the start time of getting the connection , For timeout judgment
final long startTime = clockSource.currentTime();getConnection The first step , The first is to get the token . We start with the name of the variable suspendResumeLock Look at , May hang up (suspend) of , So hang up something ? If you have read it before HikariCP Documents , Or used HikariCP Suspend function of , Then you must have guessed , This is related to suspending the entire connection pool .
- Hang up HikariCP
HikariCP Suspend function of , In fact, it is to pause the user to obtain the connection , in other words , After suspending the entire connection pool , If a thread wants to get a connection from the connection pool , Then it will be blocked all the time , Until the connection pool is restored .
What's the use of hanging ?
author brett Mention how to use the hang :
- Suspend connection pool
- Change the database connection pool configuration , Or change DNS To configure ( Point to the new master server )
- The floppy drive drives the existing connections in the connection pool
- Restore connection pool
HikariCP Can be passed during operation JMX Modify some configuration ( Not all configurations ), Yes :connectionTimeout( Get connection timeout ),leakDetectionThreshold( Connection leak detection time ),maxPoolSize( Maximum number of connections in connection pool ),minIdle( Minimum number of idle connections ),maxLifetime( Maximum connection lifetime ),idleTimeout( Maximum connection idle time ), common 7 term .
For example, I suspended the connection pool , And then modified maxLifetime, The existing connections in the connection pool are still the previous configurations , I will evict all connections from the connection pool , Then restore the connection pool , At this time, the connection pool will use the new configuration to create new connections .
besides , You can also use connection pool suspend , The thread has been blocked and cannot get the connection , To simulate a database connection failure , To test the application .
- How to achieve
OK, We know that the purpose of this code is to suspend the connection pool , Prevent users from getting connected . So how did it come true ?
Actually ,suspendResumeLock The class is com.zaxxer.hikari.util.SuspendResumeLock, Its interior is made of Semaphore Realized .Semaphore yes java Of concurrent Under bag Concurrent tool class , It uses the method of issuing tokens to threads , Control the number of concurrent threads .
Take a scenario , If it is a second kill : We know that the maximum concurrent processing capacity of the server is simultaneous processing 1000 A request , exceed 1000 Request servers may be down , Without expansion , Try to ensure that the service is available . This is the time , We need to control that the number of user requests cannot exceed 1000 Right .
Now we can use Semaphore Realization ,Semaphore Like a token bucket , The bucket can hold a specified number of tokens , In concurrency , Each thread takes one from the bucket ( It can be multiple ) token , Only those who get the token can continue to execute , If you can't get the token, just wait ( Depending on the strategy , It may also be throwing exceptions, etc ), Until another thread releases the token , Get the token and continue to execute .
Scene above , We can use Semaphore initialization 1000 A token , Each thread takes a token , In this way, we can control the number of requests processed at the same time not to exceed 1000 Is that right .
Same thing , Let's look at the method of suspending the connection pool :
public void suspend() {
//MAX_PERMITS = 10000
acquisitionSemaphore.acquireUninterruptibly(MAX_PERMITS);
}HikariCP It's initialized here 1 Ten thousand tokens , If the user calls suspend() Suspend connection pool , It's actually called Semaphore Single acquisition 1 Ten thousand tokens , In this way, other threads have no tokens to take , Just keep waiting , Until the user restores the thread pool , Release this 1 Ten thousand tokens into the bucket .
It should be noted that , To use the suspended connection pool function , You have to configure isAllowPoolSuspension=true, Otherwise, an error will be reported when using the suspend function .
We mentioned isAllowPoolSuspension Actually, I have to say suspendResumeLock An optimization point of .
When initializing the connection pool , This suspendResumeLock Depending on whether you have enabled the suspend function , There will be different implementations ,this.suspendResumeLock = config.isAllowPoolSuspension() ? new SuspendResumeLock() : SuspendResumeLock.FAUX_LOCK;.
If the suspend function is not enabled , that suspendResumeLock It's a FAUX_LOCK.
FAUX_LOCK What is it? ? Look at the code :
public static final SuspendResumeLock FAUX_LOCK = new SuspendResumeLock(false) {
@Override
public void acquire() {}
@Override
public void release() {}
@Override
public void suspend() {}
@Override
public void resume() {}
};You're not mistaken , It's an empty implementation , There is nothing in the method .
What's the advantage of doing this ? It's actually , When the suspend function is not enabled , It will provide an empty implementation , hope JIT It can be optimized . in other words , Each token request actually calls an empty method , Do nothing , After running the code many times ,JIT It may be optimized , No calls at all . such , Every time we get a connection , It will save the extra cost of applying for tokens , Improve performance .
The fastest is usually not to gain a false reputation , There must be something worth learning ...... Have you learned ?
We continue to analyze .
clockSource Is a time tool class , Used to get the current time , Calculate the time difference and so on . The current time is recorded here , Used for later time difference calculation , Used to determine whether the connection timed out .
② Get the connection
//②
// Get connection from connection pool , Timeout time timeout
final PoolEntry poolEntry = connectionBag.borrow(timeout, MILLISECONDS);
//borrow Method returns only when it times out null
if (poolEntry == null) {
break; // We timed out... break and throw exception
} The code here , We can see , from connectionBag Got a poolEntry object .poolEntry It is actually a wrapper class for database connection ,connectionBag It's just HikariCP The container that actually holds the database connection in , Inside is a CopyOnWriteArrayList. because connectionBag It's very important , We will analyze it separately later , I won't go deep here .
But from connectionBag When you get the connection , I can see that a parameter is passed timeout, This timeout That's what we configured connectionTimeout, Get connection timeout , If at specified timeout Within time , No connection returned , So go back to one null.
It has already timed out , So the following judgment is to jump out of the loop , No more trying to get a connection .
Because it is too long in an article , What's not yet done , The next part continues !
边栏推荐
- Paddleocr learning (II) paddleocr detection model training
- R语言plotly可视化:plotly可视化二维直方图等高线图(Basic 2D Histogram Contour)
- 为什么生命科学企业都在陆续上云?
- 一晚上做了一个xpath终结者:xpath-helper-plus
- Electronic basic project construction & communication between main thread and rendering thread
- JS some small problems about adding and accessing values to arrays
- QQ机器人:群成员自我禁言管理【最新beta2版本】
- 广州华锐互动打造VR展厅全景在线虚拟展厅
- Network security detection and prevention test questions (I)
- One night I worked as an XPath Terminator: XPath Helper Plus
猜你喜欢

Ali vision AI training camp-day01
![Current situation and trend analysis of China's glass packaging containers in 2021: the revenue of glass packaging containers increases year by year [figure]](/img/19/d93c8647415c593de9c3c959f72d64.jpg)
Current situation and trend analysis of China's glass packaging containers in 2021: the revenue of glass packaging containers increases year by year [figure]

Embark on a new journey and reach the world with wisdom
![Analysis on development scale and development trend of China's night economy industry in 2021 [figure]](/img/57/d6821fca9a608bf33e78287cf26bae.jpg)
Analysis on development scale and development trend of China's night economy industry in 2021 [figure]

Leetcode-101-symmetric binary tree
Android Development Notes - Quick Start (from sqllite to room licentiousness) 2

【C语言练习——打印上三角及其变形(带空格版)】

最新數據挖掘賽事方案梳理!

Kotlin compose terminate todo project Click to edit and modify todo

ECS 7-day practical training camp (Advanced route) -- day03 -- ecs+slb load balancing practice
随机推荐
How to quickly close port 8080
Miner's Diary: why should I go mining on April 5, 2021
QQ机器人疫情查询/疫情关注等【最新beta2版本】
Analysis on market scale and supply of China's needle coke industry in 2020 [figure]
Apifox简单了解——WEB端测试的集大成者
MySQL prompt performance_ Schema missing table
网络安全检测与防范 测试题(五)
Network security detection and prevention test questions (I)
LeetCode-101-对称二叉树
Network security detection and prevention test questions (V)
Overview and trend analysis of China's foreign direct investment industry in 2020 [figure]
为什么生命科学企业都在陆续上云?
QQ机器人:群成员自我禁言管理【最新beta2版本】
Connecting PHP to MySQL instances in the lamp environment of alicloud's liunx system
Detailed explanation of oauth2 - Introduction (I)
谈谈CNN中的位置和尺度问题
ECS 7-day practical training camp (Advanced route) -- day01 -- setting up FTP service based on ECS
Do you want to know how new investors open accounts? Is online account opening safe?
electron 基础项目搭建 &&主线程和渲染线程的通信
Elastic high-performance computing on the cloud supports the rapid development of the life science industry, reducing costs and increasing efficiency