⑴ 如何判斷mysql資料庫連接池是否連接
如果你想在action里判斷資料庫是否鏈接,只能創建一個標記。全局變數。比搭亂如isConn.當掘歷創建鏈接的時候把這個標記設置為1.關閉資料庫的時候標記重置 為0.這樣在action里不用獲取connection對像,直接判斷這個全局標記就可以了。
還有就知散檔是在創建鏈接之前先判斷這個標記是否是0。在關閉鏈接之前判斷這個標記是否為1
⑵ MySQL與Redis資料庫連接池介紹(圖示+源碼+代碼演示)
資料庫連接池(Connection pooling)是程序啟動時建立足夠的資料庫連接,並將這些連接組成一個連接池,由程序動態地對池中的連接進行申請,使用,釋放。
簡單的說:創建資料庫連接是一個很耗時的操作,也容易對資料庫造成安全隱患。所以,在程序初始化的時候,集中創建多個資料庫連接,並把他們集中管理,供程序使用,可以保證較快的資料庫讀寫速度,還更加安全可靠。
不使用資料庫連接池
如果不使用資料庫連接池,對於每一次SQL操作,都要走一遍下面完整的流程:
1.TCP建立連接的三次握手(客戶端與 MySQL伺服器的連接基於TCP協議)
2.MySQL認證的三次我收
3.真正的SQL執行
4.MySQL的關閉
5.TCP的四次握手關閉
可以看出來,為了執行一條SQL,需要進行大量的初始化與關閉操作
使用資料庫連接池
如果使用資料庫連接池,那麼會 事先申請(初始化)好 相關的資料庫連接,然後在之後的SQL操作中會復用這些資料庫連接,操作結束之後資料庫也不會斷開連接,而是將資料庫對象放回到資料庫連接池中
資源重用:由於資料庫連接得到重用,避免了頻繁的創建、釋放連接引起的性能開銷,在減少系統消耗的基礎上,另一方面也增進了系統運行環境的平穩性(減少內存碎片以及資料庫臨時進程/線程的數量)。
更快的系統響應速度:資料庫連接池在初始化過程中,往往已經創建了若干資料庫連接置於池中備用。 此時連接的初始化工作均已完成。對於業務請求處理而言,直接利用現有可用連接,避免了從資料庫連接初始化和釋放過程的開銷,從而縮減了系統整體響應時間。
統一的連接管理,避免資料庫連接泄露:在較為完備的資料庫連接池實現中,可根據預先的連接佔用超時設定,強制收回被佔用連接。從而避免了常規資料庫連接操作中可能出現的資源泄露。
如果說你的伺服器CPU是4核i7的,連接池大小應該為((4*2)+1)=9
相關視頻推薦
90分鍾搞懂資料庫連接池技術|linux後台開發
《tcp/ip詳解卷一》: 150行代碼拉開協議棧實現的篇章
學習地址:C/C++Linux伺服器開發/後台架構師【零聲教育】-學習視頻教程-騰訊課堂
需要C/C++ Linux伺服器架構師學習資料加qun 812855908 獲取(資料包括 C/C++,Linux,golang技術,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協程,DPDK,ffmpeg 等),免費分享
源碼下載
下載方式:https://github.com/dongyusheng/csdn-code/tree/master/db_pool(Github中下載)
db_pool目錄下有兩個目錄,mysql_pool目錄為MySQL連接池代碼,redis_pool為redis連接池代碼
下面介紹mysql_pool
CDBConn解析
概念: 代表一個數據連接對象實例
相關成員:
m_pDBPool:該資料庫連接對象所屬的資料庫連接池
構造函數: 綁定自己所屬於哪個資料庫連接池
Init()函數: 創建資料庫連接句柄
CDBPool解析
概念:代表一個資料庫連接池
相關成員:
Init()函數:常見指定數量的資料庫實例句柄,然後添加到m_free_list中,供後面使用
GetDBConn()函數: 用於從空閑隊列中返回可以使用的資料庫連接句柄
RelDBConn()函數: 程序使用完該資料庫句柄之後,將句柄放回到空閑隊列中
測試之前,將代碼中的資料庫地址、埠、賬號密碼等改為自己的(代碼中有好幾處)
進入MySQL, 創建mysql_pool_test資料庫
進入到mysql_pool目錄下, 創建一個build目錄並進入 :
之後就會在目錄下生成如下的可執行文件
輸入如下兩條命令進行測試: 可以看到不使用資料庫連接池,整個操作耗時4秒左右;使用連接池之後,整個操作耗時2秒左右,提升了一倍
源碼下載
下面介紹redis_pool
測試
進入到redis_pool目錄下, 創建一個build目錄並進入 :
然後輸入如下的命令進行編譯
之後就會在目錄下生成如下的可執行文件
輸入如下的命令進行測試: 可以看到不使用資料庫連接池,整個操作耗時182ms;使用連接池之後,整個操作耗時21ms,提升了很多
進入redis,可以看到我們新建的key:
⑶ 服務產生大量TIME_WAIT如何解決
當TIME_WAIT超過linux系統tw數量的閥值(可用數量不會大於65535),系統會把多餘的time-wait socket 刪除掉,並且顯示警告信息,如果是NAT網路環境又存在大量訪問,會產生各種連接不穩定斷開的情況,從而影響了服務的穩定性。
一、狀態的產生
要解決TIME_WAIT狀態過多的問題,先來研究下TIME_WAIT狀態的產生,下面是TCP連接斷開時的四次揮手狀態轉換圖,說明一點,途中顯示的是客戶端主動斷開連接,tcp連接也可以由伺服器端主動斷開連接。我們先來描述一下斷開的狀態:
1)客戶端進程發出連接釋放報文,並且停止發送數據。釋放數據報文首部,FIN=1,其序列號為seq=u(等於前面已經傳送過來的數據的最後一個位元組的序號加1),此時,客戶端進入FIN-WAIT-1(終止等待1)狀態。 TCP規定,FIN報文段即使不攜帶數據,也要消耗一個序號。
2)伺服器收到連接釋放報文,發出確認報文,ACK=1,ack=u+1,並且帶上自己的序列號seq=v,此時,服務端就進入了CLOSE-WAIT(關閉等待)狀態。TCP伺服器通知高層的應用進程,客戶端向伺服器的方向就釋放了,這時候處於半關閉狀態,即客戶端已經沒有數據要發送了,但是伺服器若發送數據,客戶端依然要接受。這個狀態還要持續一段時間,也就是整個CLOSE-WAIT狀態持續的時間。
3)客戶端收到伺服器的確認請求後,此時,客戶端就進入FIN-WAIT-2(終止等待2)狀態,等待伺服器發送連接釋放報文(在這之前還需要接受伺服器發送的最後的數據)。
4)伺服器將最後的數據發送完畢後,就向客戶端發送連接釋放報文,FIN=1,ack=u+1,由於在半關閉狀態,伺服器很可能又發送了一些數據,假定此時的序列號為seq=w,此時,伺服器就進入了LAST-ACK(最後確認)狀態,等待客戶端的確認。
5)客戶端收到伺服器的連接釋放報文後,必須發出確認,ACK=1,ack=w+1,而自己的序列號是seq=u+1,此時,客戶端就進入了TIME-WAIT(時間等待)狀態。注意此時TCP連接還沒有釋放,必須經過2MSL(最長報文段壽命,RFC規定一個MSL為2min,linux中一般設置為30s)的時間後,當客戶端撤銷相應的TCB後,才進入CLOSED狀態。
6)伺服器只要收到了客戶端發出的確認,立即進入CLOSED狀態。同樣,撤銷TCB後,就結束了這次的TCP連接。可以看到,伺服器結束TCP連接的時間要比客戶端早一些。
可以看到TIME_WAIT狀態產生是在tcp連接主動關閉的一端產生的正常tcp狀態,超過兩個MSL之後,就會關閉,釋放佔用的埠。基於以上的分析我們可以推斷,在我們的應用中產生大量TIME_WAIT狀態的根本原因是頻繁創建斷開連接TCP連接。要解決TIME_WATIT狀態過多的問題,就要分析我們的應用把頻繁創建的短連接改為長連接。
二、常見的短連接產生的場景
1.服務連接服務
後台業務伺服器,通常需要調用redis、mysql以及其他http服務和grpc服務,在服務相互調用中,如果使用的是短連接,高並發時就會產生大量TIME_WAIT,如何解決呢?一般情況下,redis等客戶端會有連接池,我們要做的是設置好相關的連接服用參數,一般會有連接數、連接重用時間、連接空閑數等。所以在應用中通過設置合理的連接池參數可以避免TIME_WAIT狀態過多的問題:
1.檢查http連接池
2.檢查grpc連接池
3.檢查redis連接池
4.檢查mysql連接池
...
我們來查看一個mysql連接池配置信息,最大連接數100,最大空閑連接數10,測試的並發數50,產生的效果如下:
可以看到TIME_WAIT狀態快速上升,我們查看redis客戶端的連接情況:
{MaxOpenConnections:100 OpenConnections:1 InUse:0 Idle:1 WaitCount:0 WaitDuration:0s MaxIdleClosed:0 MaxLifetimeClosed:0}
{MaxOpenConnections:100 OpenConnections:17 InUse:15 Idle:2 WaitCount:0 WaitDuration:0s MaxIdleClosed:48 MaxLifetimeClosed:0}
{MaxOpenConnections:100 OpenConnections:51 InUse:44 Idle:7 WaitCount:0 WaitDuration:0s MaxIdleClosed:82 MaxLifetimeClosed:0}
{MaxOpenConnections:100 OpenConnections:51 InUse:50 Idle:1 WaitCount:0 WaitDuration:0s MaxIdleClosed:90 MaxLifetimeClosed:0}
{MaxOpenConnections:100 OpenConnections:50 InUse:49 Idle:1 WaitCount:0 WaitDuration:0s MaxIdleClosed:126 MaxLifetimeClosed:0}
{MaxOpenConnections:100 OpenConnections:51 InUse:49 Idle:2 WaitCount:0 WaitDuration:0s MaxIdleClosed:131 MaxLifetimeClosed:0}
{MaxOpenConnections:100 OpenConnections:50 InUse:49 Idle:1 WaitCount:0 WaitDuration:0s MaxIdleClosed:181 MaxLifetimeClosed:0}
{MaxOpenConnections:100 OpenConnections:51 InUse:51 Idle:0 WaitCount:0 WaitDuration:0s MaxIdleClosed:233 MaxLifetimeClosed:0}
{MaxOpenConnections:100 OpenConnections:51 InUse:51 Idle:0 WaitCount:0 WaitDuration:0s MaxIdleClosed:240 MaxLifetimeClosed:0}
{MaxOpenConnections:100 OpenConnections:46 InUse:38 Idle:8 WaitCount:0 WaitDuration:0s MaxIdleClosed:296 MaxLifetimeClosed:0}
{MaxOpenConnections:100 OpenConnections:51 InUse:50 Idle:1 WaitCount:0 WaitDuration:0s MaxIdleClosed:313 MaxLifetimeClosed:0}
{MaxOpenConnections:100 OpenConnections:51 InUse:50 Idle:1 WaitCount:0 WaitDuration:0s MaxIdleClosed:363 MaxLifetimeClosed:0}
{MaxOpenConnections:100 OpenConnections:51 InUse:50 Idle:1 WaitCount:0 WaitDuration:0s MaxIdleClosed:409 MaxLifetimeClosed:0}
{MaxOpenConnections:100 OpenConnections:50 InUse:48 Idle:2 WaitCount:0 WaitDuration:0s MaxIdleClosed:438 MaxLifetimeClosed:0}
{MaxOpenConnections:100 OpenConnections:49 InUse:49 Idle:0 WaitCount:0 WaitDuration:0s MaxIdleClosed:494 MaxLifetimeClosed:0}
分析發現MaxIdleClosed數據持續上升,此為mysql客戶端連接池配置不合理產生大量TIME_WAIT狀態的例子
2.網路抖動
網路情況不好時,如果主動方無TIME_WAIT等待,關閉前個連接後,主動方與被動方又建立起新的TCP連接,這時被動方重傳或延時過來的FIN包過來後會直接影響新的TCP連接。同樣網路情況不好並且無TIME_WAIT等待,關閉連接後無新連接,當接收到被動方重傳或延遲的FIN包後,會給被動方回一個RST包,可能會影響被動方其它的服務連接。
網路抖動問題比較好排查,直接使用ping命令可以觀察到。
⑷ 如何配置mysql資料庫連接池
使用org.springframework.jdbc.datasource.DriverManagerDataSource
說明:DriverManagerDataSource建立連接是只要有連接就新建一個connection,根本沒有連接池的作用。
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">大瞎
<property name="driverClassName"><value>${jdbc.driverClassName}</value></property>喊仿襲鄭兄
<property name="url"><value>${jdbc.url}</value></property>
<property name="username"><value>${jdbc.username}</value></property>
<property name="password"><value>${jdbc.password}</value></property>
</bean>
⑸ Linux上的tomcat連接MySql異常緩慢,求解
兩種情坦毀況: 3、linux防火1牆阻止7 2、你用的mysql用戶3被限制在本地登陸擾信敬 mdΕ@Υ伲nΗ印nΗ印sz①fz①緩慎dΕ@Υ伲aǖ
⑹ 一般連接池是怎麼處理mysql自動回收長時間
更快速的配置對比 pt-config-diff在我們日常工作中,大家一定遇到過以下場景:
若干套 MySQL 環境,只有一套:
∘行為異常,懷疑觸發 bug
∘性能異常,比其他環境都要低
在這種場景下,我們一鄭尺般的做法是首先控制變數,查看軟硬體配置,以及 MySQL 的參數配置。關於 MySQL 的參數配置對比,如果我們人工對比的話只會關注某些重點參數,而缺少了整體細節上的的對比。在這里我們推薦給大家 Percona Toolkit 中的一個工具 pt-config-diff
更准確的復制延時 pt-heartbeat在 MySQL 中,復制延遲可以理解為由兩部分組成:1. 主庫已經生成了 BINLOG,但是還沒有發送給從庫 -- 我們在這里稱之為:日誌延遲2. 從庫已經接收到了 BINLOG,但是還沒有應用完成 -- 我們在這里稱之為:應用延遲MySQL 原生的查看復制延遲的手段為:show slave statusG中的Seconds_Behind_Master。這種觀測手法只能觀測出應用延遲。在非同步復制或降級的半同步復制下,誤差較大,無法准確的反映出整體復制延時。
1. 在 Master 上循環插入:insert into database.heartbeat (master_now) values(NOW())
2. database.heartbeat 的變更會跟隨主從復制流向從庫
3. 系統當前時間 - 從庫表中的時間 = 從庫實際的復制延時
更准確的復制延時 pt-heartbeat在 MySQL 中,復制延遲可以理解為由兩部分組成:1. 主庫已經生成了 BINLOG,但是還沒有發送給從庫 -- 我們在這里稱之為:日誌延遲2. 從庫已經接收到了 BINLOG,但是還沒有應用完成 -- 我們在這里稱之為:應用延遲森叢擾MySQL 原生的查看復制延遲的手段為:show slave statusG中的Seconds_Behind_Master。這種觀測手法只能觀測出應用延遲。在非同步復制或降級的半同步復制下,誤差較大,無法准確的反映出整體復制延時。
更易用的調試工具 pt-pmp在某些情況下,我們肯定會遇到某些故障無法從日誌,以及狀態命令中找到原因,需要深入到程序邏輯級別。又或者我們需要立即通過非常規手段恢復故障資料庫,但是又想保留足夠多的故障信息。來避免我們事後復現問題的頭疼。pt-pmp 便是在這種場景下幫助我們的工具。它會使用 gdb 來列印 mysqld 的堆棧信息,並把調用鏈相同的線程堆棧合並。堆棧合並的功能對於 MySQL 這種多線程的應用非常有幫助,此旦會節省我們大量的時間。
⑺ MySql資料庫連接池如何配置
連接先建立一些連接,並且這些連接允許共享,因此這樣就節省了每次連接的時間開銷。Mysql資料庫為例,連接池在Tomcat中的配置與使用。
1、創建資料庫Student,表student
2、配置server.xml文件。Tomcat安裝目錄下conf中server.xml文件。
<GlobalNamingResources>
<Resource
name="jdbc/DBPool"
type="javax.sql.DataSource"
password=""
driverClassName="com.mysql.jdbc.Driver"
maxIdle="2"
maxWait="5000"
username="root"
url="jdbc:mysql://localhost:3306/student"
maxActive="3"
/>
</GlobalNamingResources>
name:指定連接池的名稱
type:指定連接池的類,他負責連接池的虧扮信事務處理
url:指定要連接的資料庫
driverClassName:指定連接資料庫使用的驅動程序
username:資料庫用戶名
password:資料庫密碼
maxWait:指定最大建立連接等待時間,如果超過此時間將接到異常
maxIdle:指定連接池中連接的最大空閑數
maxActive:指定連接池最大連接數
3、配置web.xml文件。
<web-app>
<resource-ref>
<description>mysql資料庫連接池配置</description>
<res-ref-name>jdbc/DBPool</res-ref-name>缺團
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
</web-app>
4、配置context.xml文件
與server.xml文件所在的位置相同。
<Context>
<ResourceLink
name="jdbc/銷輪DBPool"
type="javax.sql.DataSource"
global="jdbc/DBPool"
/>
</Context>
5、測試
DataSource pool = null;
Context env = null;
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try{
env = (Context)new InitialContext().lookup("java:comp/env");
//檢索指定的對象,返回此上下文的一個新實例
pool = (DataSource)env.lookup("jdbc/DBPool");
//獲得資料庫連接池
if(pool==null){out.printl("找不到指定的連接池!");}
con = pool.getConnection();
st = con.createStatement();
rs = st.executeQuery("select * from student");
}catch(Exception ex){out.printl(ne.toString());}
⑻ mysql怎麼設置thread
MySQL裡面為了提高客戶端請求創建連接過程的性能,提供了一個連接池也就是
Thread_Cache池,將空閑的連接線程放在連接池中,而不是立即銷毀.這樣的好處就是,當又有一個新的請求的時候,mysql不會立即去創建連接
線程,而是先模卜碼去Thread_Cache中去查找空閑的連接線程,如果存在則直接使用,不存在才創建新的連接線程.
有關Thread_Cache在MySQL有幾個重要的參數,簡單介紹如下:
thread_cache_size
Thread_Cache
中存放的最大連接線程數.在短連接的應用中Thread_Cache的功效非常明顯,因為在應用中資料庫的連接和創建是非常頻繁的,如果不使用
Thread_Cache那麼消耗的資源是非常可觀的!在長連接中雖然帶來的改善沒有短連接的那麼明顯,但是好處是顯而易見的.但並不是越大越好大了反而
浪費資源這個的確定一般認為和物理內存有一定關系,如下:
復制代碼 代碼如下:
1G —弊漏> 8
2G —> 16
3G —> 32
>3G —> 64
如果短連接多的話可以適當加大.
thread_stack
每個連接被創建的時候,mysql分配給它的內存.這個值一般認為默認就可以應用於大部分場景了,除非必要非則不要動它.
thread_handing
運用Thread_Cache處旦哪理連接的方式,5.1.19添加的新特性.有兩個值可選[no-threads|one-thread-per-
connection] 看字面意思大家也該猜出八九分了,呵呵,no-threads
伺服器使用一個線程,one-thread-per-connection
伺服器為每個客戶端請求使用一個線程.原手冊中提到,no-threads是在Linux下調試用的.
復制代碼 代碼如下:
mysql> show variables like 'thread%';
+——————-+—————————+
| Variable_name | Value |
+——————-+—————————+
| thread_cache_size | 32 |
| thread_handling | one-thread-per-connection |
| thread_stack | 196608 |
+——————-+—————————+
3 rows in set (0.01 sec)
mysql> show status like '%connections%';
+———————-+——–+
| Variable_name | Value |
+———————-+——–+
| Connections | 199156 |
| Max_used_connections | 31 |
+———————-+——–+
2 rows in set (0.00 sec)
mysql> show status like '%thread%';
+————————+——–+
| Variable_name | Value |
+————————+——–+
| Delayed_insert_threads | 0 |
| Slow_launch_threads | 0 |
| Threads_cached | 3 |
| Threads_connected | 6 |
| Threads_created | 8689 |
| Threads_running | 5 |
+————————+——–+
6 rows in set (0.00 sec)
通過以上3個命令,可以看到伺服器的 thread_cache池中最多可以存放32個連接線程,為每個客戶端球使用一個線程.為每個連接的線程分配192k的內存空間.
服 務器總共有199156次連接,最大並發連接數為31,當前在thread_cashe池中的連接數為3個,連接數為6個,處於活躍狀態的有5個,共創建 了8689次連接.顯然這里以短連接為主.可以算出thread_cache命中率,公式為:
復制代碼 代碼如下:
Thread_Cache_Hit=(Connections-Thread_created)/Connections*100%
當前伺服器的Thread_cache命中率約為95.6%這個結果我還是比較滿意的.但是可以看出 thread_cache_size有點多餘改成16或8更合理一些.