這麼多數據庫、http、netty鏈接池,jdk線程池,本質上都是鏈接池技術,鏈接池技術核心是鏈接或者說建立的資源複用。java
鏈接池技術核心:經過減小鏈接建立、關閉來提高性能。用於用戶後續使用,好處是後續使用不用在建立鏈接以及線程,由於這些都須要相關不少文件、鏈接資源、操做系統內核資源支持來完成構建,會消耗大量資源,而且建立、關閉會消耗應用程序大量性能。mysql
網絡鏈接自己會消耗大量內核資源,在linux系統下,網絡鏈接建立自己tcp/ip協議棧在內核裏面,鏈接建立關閉會消耗大量文件句柄(linux中萬物皆文件,一種厲害抽象手段)系統資源。當下更可能是應用tcp技術完成網絡傳輸,反覆打開關閉,須要操做系統維護大量tcp協議棧狀態。linux
鏈接池本質上是構建一個容器,容器來存儲建立好的線程、http鏈接、數據庫鏈接、netty鏈接等。對於使用方至關於黑盒,按照接口進行使用就能夠了。各個鏈接池構建、使用管理詳細過程大概分紅如下三部分。redis
第一部分:首先初始化鏈接池,根據設置相應參數,鏈接池大小、核心線程數、核心鏈接數等參數,初始化建立數據庫、http、netty鏈接以及jdk線程。sql
第二部分:鏈接池使用,前邊初始化好的鏈接池、線程池,直接從鏈接池、線程中取出資源便可進行使用,使用完後要記得交還鏈接池、線程池,經過池容器來對資源進行管理。數據庫
第三部分:對於鏈接池維護,鏈接池、線程池來維護鏈接、線程狀態,不可用鏈接、線程進行銷燬,正在使用鏈接、線程進行狀態標註,鏈接、線程不夠後而且少於設置最大鏈接、線程數,要進行新鏈接、線程建立。安全
經過上邊能夠了解到各類鏈接池技術以及線程池原理或者說套路,理解原理才能不被紛繁複雜表象掩蓋。微信
下面談談構建本身鏈接池,其實理解了鏈接池、線程原理,可使用ArrayList來構建本身鏈接池、線程池。初始化時建立配置鏈接數、線程,存儲在ArrayList容器中,使用時從ArrayList從取出鏈接、線程進行使用,執行完任務後,提交回ArrayList容器。前提條件是單線程,在多線程狀態下要用線程安全容器。網絡
前邊根據原理介紹了一個簡單鏈接池、線程池怎樣構建,實際工業級別線程池還要考慮到鏈接狀態,短鏈接重連,線程池維護管理高效,線程池穩定等多個因素。多線程
須要用到鏈接池而又沒有相關開源產品可用時,java鏈接池可使用common-pool2來構建,好比google開源gRPC技術,自己是高性能跨平臺技術,但目前做爲微服務使用,沒有鏈接池、負載均衡等相應配套,這時能夠根據須要本身基於Java容器構建本身鏈接池。也能夠利用common-pool2構建鏈接池來提高應用性能,以及保持高可用。common-pool2自己不只僅能夠構建鏈接池使用,還能夠用來構建對象池。
鏈接池還有一個反作用就是實現了高可用,在微服務場景下一個鏈接不可用,那麼再從netty鏈接池中取出一個進行使用,避免了鏈接不可用問題。
掌握原理從比較全面掌握各類池技術,避免數據庫鏈接池,再到httpclient http鏈接池,再到微服務netty鏈接池,redis客戶端鏈接池,以及jdk中線程池,對象池各類各樣池技術,使咱們眼花繚亂,花費過多時間,掌握原理機制以不變應萬變。
推廣一下這個方法,其餘技術也是相似,深刻掌握其原理,就能夠明白其餘相似技術類似原理,避免疲於應對各類新技術。但每一種架構設計與實現又與領域有着關係,也不可講原理不顧實際狀況擴展。理論與架構設計、源碼學習相結合纔是最好的,但願有幫助。
享元模式的主要目的是實現對象的共享,即共享池,當系統中對象多的時候能夠減小內存的開銷,一般與工廠模式一塊兒使用。
FlyWeightFactory負責建立和管理享元單元,當一個客戶端請求時,工廠須要檢查當前對象池中是否有符合條件的對象,若是有,就返回已經存在的對象,若是沒有,則建立一個新對象,FlyWeight是超類。
一提到共享池,咱們很容易聯想到Java裏面的JDBC鏈接池,想一想每一個鏈接的特色,咱們不難總結出:適用於做共享的一些個對象,他們有一些共有的屬性,就拿數據庫鏈接池來講,url、driverClassName、username、password及dbname,這些屬性對於每一個鏈接來講都是同樣的,因此就適合用享元模式來處理,建一個工廠類,將上述相似屬性做爲內部數據,其它的做爲外部數據,在方法調用時,當作參數傳進來,這樣就節省了空間,減小了實例的數量。
看個例子:
看下數據庫鏈接池的代碼:
[java] view plaincopy
經過鏈接池的管理,實現了數據庫鏈接的共享,不須要每一次都從新建立鏈接,節省了數據庫從新建立的開銷,提高了系統的性能!