走進JavaWeb技術世界3:JDBC的進化與鏈接池技術

本系列文章將整理到我在GitHub上的《Java面試指南》倉庫,更多精彩內容請到個人倉庫裏查看html

https://github.com/h2pl/Java-...

喜歡的話麻煩點下Star哈java

文章首發於個人我的博客:linux

www.how2playlife.com

本文是微信公衆號【Java技術江湖】的《走進JavaWeb技術世界》其中一篇,本文部份內容來源於網絡,爲了把本文主題講得清晰透徹,也整合了不少我認爲不錯的技術博客內容,引用其中了一些比較好的博客文章,若有侵權,請聯繫做者。
該系列博文會告訴你如何從入門到進階,從servlet到框架,從ssm再到SpringBoot,一步步地學習JavaWeb基礎知識,並上手進行實戰,接着瞭解JavaWeb項目中常常要使用的技術和組件,包括日誌組件、Maven、Junit,等等內容,以便讓你更完整地瞭解整個Java Web技術體系,造成本身的知識框架。爲了更好地總結和檢驗你的學習成果,本系列文章也會提供每一個知識點對應的面試題以及參考答案。git

若是對本系列文章有什麼建議,或者是有什麼疑問的話,也能夠關注公衆號【Java技術江湖】聯繫做者,歡迎你參與本系列博文的創做和修訂。程序員

<!-- more -->github

JDBC數據庫鏈接池

談談鏈接池、線程池技術原理

作互聯網研發,最先接觸使用jdbc技術,爲了數據庫鏈接可以複用,會用到c3p0、dbcp等數據庫鏈接池。應該是研發人員最先接觸的數據庫鏈接池,再到httpclient http鏈接池,再到微服務netty鏈接池,redis客戶端鏈接池,以及jdk中線程池技術。web

       這麼多數據庫、http、netty鏈接池,jdk線程池,本質上都是鏈接池技術,鏈接池技術核心是鏈接或者說建立的資源複用。面試

       鏈接池技術核心:經過減小對於鏈接建立、關閉來提高性能。用於用戶後續使用,好處是後續使用不用在建立鏈接以及線程,由於這些都須要相關不少文件、鏈接資源、操做系統內核資源支持來完成構建,會消耗大量資源,而且建立、關閉會消耗應用程序大量性能。redis

       網絡鏈接自己會消耗大量內核資源,在linux系統下,網絡鏈接建立自己tcp/ip協議棧在內核裏面,鏈接建立關閉會消耗大量文件句柄(linux中萬物皆文件,一種厲害抽象手段)系統資源。當下更可能是應用tcp技術完成網絡傳輸,反覆打開關閉,須要操做系統維護大量tcp協議棧狀態。sql

       鏈接池本質上是構建一個容器,容器來存儲建立好的線程、http鏈接、數據庫鏈接、netty鏈接等。對於使用方至關於黑盒,按照接口進行使用就能夠了。各個鏈接池構建、使用管理詳細過程大概分紅如下三部分。

       第一部分:首先初始化鏈接池,根據設置相應參數,鏈接池大小、核心線程數、核心鏈接數等參數,初始化建立數據庫、http、netty鏈接以及jdk線程。

       第二部分:鏈接池使用,前邊初始化好的鏈接池、線程池,直接從鏈接池、線程中取出資源便可進行使用,使用完後要記得交還鏈接池、線程池,經過池容器來對資源進行管理。

       第三部分:對於鏈接池維護,鏈接池、線程池來維護鏈接、線程狀態,不可用鏈接、線程進行銷燬,正在使用鏈接、線程進行狀態標註,鏈接、線程不夠後而且少於設置最大鏈接、線程數,要進行新鏈接、線程建立。

       經過上邊能夠了解到各類鏈接池技術以及線程池原理或者說套路,理解原理才能不被紛繁複雜表象掩蓋。

       下面談談構建本身鏈接池,其實理解了鏈接池、線程原理,可使用ArrayList來構建本身鏈接池、線程池。初始化時建立配置鏈接數、線程,存儲在ArrayList容器中,使用時從ArrayList從取出鏈接、線程進行使用,執行完任務後,提交回ArrayList容器。前提條件是單線程,在多線程狀態下要用線程安全容器。

       前邊根據原理介紹了一個簡單鏈接池、線程池怎樣構建,實際工業級別線程池還要考慮到鏈接狀態,短鏈接重連,線程池維護管理高效,線程池穩定等多個因素。

       須要用到鏈接池而又沒有相關開源產品可用時,java鏈接池可使用common-pool2來構建,好比google開源gRPC技術,自己是高性能跨平臺技術,但目前做爲微服務使用,沒有鏈接池、負載均衡等相應配套,這時能夠根據須要本身基於Java容器構建本身鏈接池。也能夠利用common-pool2構建鏈接池來提高應用性能,以及保持高可用。common-pool2自己不只僅能夠構建鏈接池使用,還能夠用來構建對象池。

       鏈接池還有一個反作用就是實現了高可用,在微服務場景下一個鏈接不可用,那麼再從netty鏈接池中取出一個進行使用,避免了鏈接不可用問題。

       掌握原理從比較全面掌握各類池技術,避免數據庫鏈接池,再到httpclient http鏈接池,再到微服務netty鏈接池,redis客戶端鏈接池,以及jdk中線程池,對象池各類各樣池技術,使咱們眼花繚亂,花費過多時間,掌握原理機制以不變應萬變。

       推廣一下這個方法,其餘技術也是相似,深刻掌握其原理,就能夠明白其餘相似技術類似原理,避免疲於應對各類新技術。但每一種架構設計與實現又與領域有着關係,也不可講原理不顧實際狀況擴展。理論與架構設計、源碼學習相結合纔是最好的,但願有幫助。

JDBC 數據庫鏈接池 

轉自:

什麼狀況下使用鏈接池?

對於一個簡單的數據庫應用,因爲對於數據庫的訪問不是很頻繁。這時能夠簡單地在須要訪問數據庫時,就新建立一個鏈接,用完後就關閉它,這樣作也不會帶來什麼明顯的性能上的開銷。可是對於一個複雜的數據庫應用,狀況就徹底不一樣了。頻繁的創建、關閉鏈接,會極大的減低系統的性能,由於對於鏈接的使用成了系統性能的瓶頸。

使用鏈接池的好處

  1. 鏈接複用。經過創建一個數據庫鏈接池以及一套鏈接使用管理策略,使得一個數據庫鏈接能夠獲得高效、安全的複用,避免了數據庫鏈接頻繁創建、關閉的開銷。
  2. 對於共享資源,有一個很著名的設計模式:資源池。該模式正是爲了解決資源頻繁分配、釋放所形成的問題的。把該模式應用到數據庫鏈接管理領域,就是創建一個數據庫鏈接池,提供一套高效的鏈接分配、使用策略,最終目標是實現鏈接的高效、安全的複用。

鏈接池的實現

數據庫鏈接池的基本原理是在內部對象池中維護必定數量的數據庫鏈接,並對外暴露數據庫鏈接獲取和返回方法。

外部使用者可經過 getConnection 方法獲取鏈接,使用完畢後再經過 close 方法將鏈接返回,注意此時鏈接並無關閉,而是由鏈接池管理器回收,併爲下一次使用作好準備。

Java 中有一個 DataSource 接口, 數據庫鏈接池就是 DataSource 的一個實現

經常使用數據庫鏈接池

1、JDBC數據庫鏈接池的必要性

  在使用開發基於數據庫的web程序時,傳統的模式基本是按如下步驟:

  ①在主程序(如servlet、beans)中創建數據庫鏈接。
  ②進行sql操做
  ③斷開數據庫鏈接。

  這種模式開發,存在的問題:

  ①普通的JDBC數據庫鏈接使用 DriverManager 來獲取,每次向數據庫創建鏈接的時候都要將 Connection 加載到內存中,再驗證用戶名和密碼(得花費0.05s~1s的時間)。須要數據庫鏈接的時候,就向數據庫要求一個,執行完成後再斷開鏈接。這樣的方式將會消耗大量的資源和時間。數據庫的鏈接資源並無獲得很好的重複利用.若同時有幾百人甚至幾千人在線,頻繁的進行數據庫鏈接操做將佔用不少的系統資源,嚴重的甚至會形成服務器的崩潰。
  ②對於每一次數據庫鏈接,使用完後都得斷開。不然,若是程序出現異常而未能關閉,將會致使數據庫系統中的內存泄漏,最終將致使重啓數據庫。
  ③這種開發不能控制被建立的鏈接對象數,系統資源會被毫無顧及的分配出去,如鏈接過多,也可能致使內存泄漏,服務器崩潰。

2、數據庫鏈接池(connection pool)

  數據庫鏈接池簡單介紹

  爲解決傳統開發中的數據庫鏈接問題,能夠採用數據庫鏈接池技術。

  數據庫鏈接池的基本思想就是爲數據庫鏈接創建一個「緩衝池」。預先在緩衝池中放入必定數量的鏈接,當須要創建數據庫鏈接時,只需從「緩衝池」中取出一個,使用完畢以後再放回去。

  數據庫鏈接池負責分配、管理和釋放數據庫鏈接,它容許應用程序重複使用一個現有的數據庫鏈接,而不是從新創建一個。

  數據庫鏈接池在初始化時將建立必定數量的數據庫鏈接放到鏈接池中,這些數據庫鏈接的數量是由最小數據庫鏈接數來設定的。不管這些數據庫鏈接是否被使用,鏈接池都將一直保證至少擁有這麼多的鏈接數量。鏈接池的最大數據庫鏈接數量限定了這個鏈接池能佔有的最大鏈接數,當應用程序向鏈接池請求的鏈接數超過最大鏈接數量時,這些請求將被加入到等待隊列中。

  數據庫鏈接池工做原理:

  數據庫鏈接池技術的優勢

  資源重用:

  ①因爲數據庫鏈接得以重用,避免了頻繁建立,釋放鏈接引發的大量性能開銷。在減小系統消耗的基礎上,另外一方面也增長了系統運行環境的平穩性。

  更快的系統反應速度:
  數據庫鏈接池在初始化過程當中,每每已經建立了若干數據庫鏈接置於鏈接池中備用。此時鏈接的初始化工做均已完成。對於業務請求處理而言,直接利用現有可用鏈接,避免了數據庫鏈接初始化和釋放過程的時間開銷,從而減小了系統的響應時間

  新的資源分配手段:
  對於多應用共享同一數據庫的系統而言,可在應用層經過數據庫鏈接池的配置,實現某一應用最大可用數據庫鏈接數的限制,避免某一應用獨佔全部的數據庫資源

  統一的鏈接管理,避免數據庫鏈接泄露:
  在較爲完善的數據庫鏈接池實現中,可根據預先的佔用超時設定,強制回收被佔用鏈接,從而避免了常規數據庫鏈接操做中可能出現的資源泄露

3、兩種開源的數據庫鏈接池

  JDBC 的數據庫鏈接池使用 javax.sql.DataSource 來表示,DataSource 只是一個接口,該接口一般由服務器(Weblogic, WebSphere, Tomcat)提供實現,也有一些開源組織提供實現:
  ①DBCP 數據庫鏈接池
  ②C3P0 數據庫鏈接池

  DataSource 一般被稱爲數據源,它包含鏈接池和鏈接池管理兩個部分,習慣上也常常把 DataSource稱爲鏈接池

  數據源和數據庫鏈接不一樣,數據源無需建立多個,它是產生數據庫鏈接的工廠,所以整個應用只須要一個數據源便可。

  當數據庫訪問結束後,程序仍是像之前同樣關閉數據庫鏈接:conn.close(); 但上面的代碼並無關閉數據庫的物理鏈接,它僅僅把數據庫鏈接釋放,歸還給了數據庫鏈接池。

參考文章

https://blog.csdn.net/u010028...
https://www.cnblogs.com/shaox...
https://www.cnblogs.com/alber...
https://blog.csdn.net/weixin_...
https://www.jianshu.com/p/073...

微信公衆號

我的公衆號:黃小斜

黃小斜是跨考軟件工程的 985 碩士,自學 Java 兩年,拿到了 BAT 等近十家大廠 offer,從技術小白成長爲阿里工程師。

做者專一於 JAVA 後端技術棧,熱衷於分享程序員乾貨、學習經驗、求職心得和程序人生,目前黃小斜的CSDN博客有百萬+訪問量,知乎粉絲2W+,全網已有10W+讀者。

黃小斜是一個斜槓青年,堅持學習和寫做,相信終身學習的力量,但願和更多的程序員交朋友,一塊兒進步和成長!

原創電子書:
關注公衆號【黃小斜】後回覆【原創電子書】便可領取我原創的電子書《菜鳥程序員修煉手冊:從技術小白到阿里巴巴Java工程師》

程序員3T技術學習資源: 一些程序員學習技術的資源大禮包,關注公衆號後,後臺回覆關鍵字 「資料」 便可免費無套路獲取。

考研複習資料:
計算機考研大禮包,都是我本身考研複習時用的一些複習資料,包括公共課和專業的複習視頻,這裏也推薦給你們,關注公衆號後,後臺回覆關鍵字 「考研」 便可免費獲取。

技術公衆號:Java技術江湖

若是你們想要實時關注我更新的文章以及分享的乾貨的話,能夠關注個人公衆號【Java技術江湖】一位阿里 Java 工程師的技術小站,做者黃小斜,專一 Java 相關技術:SSM、SpringBoot、MySQL、分佈式、中間件、集羣、Linux、網絡、多線程,偶爾講點Docker、ELK,同時也分享技術乾貨和學習經驗,致力於Java全棧開發!

Java工程師必備學習資源: 一些Java工程師經常使用學習資源,關注公衆號後,後臺回覆關鍵字 「Java」 便可免費無套路獲取。

個人公衆號

相關文章
相關標籤/搜索