複製鏈接
請複製以下鏈接發送給好友

(網絡技術名稱)

鎖定
池,即Pool(池),網絡技術名稱,應用在服務器端軟件的開發上。
中文名
概    念
在服務器端軟件的開發上
資源池
資源放置於內存對象中以備使用
分    析
中出現的所有實體

目錄

定義

池的描述和定義:Pool(池)的概念被廣泛的應用在服務器端軟件的開發上。使用池結構可以明顯的提高你的應用程序的速度,改善效率和降低系統資源的開銷。所以在應用服務器端的開發中池的設計和實現是開發工作中的重要一環。
那麼到底什麼是池呢?我們可以簡單的想象一下應用運行時的環境,當大量的客户併發的訪問應用服務器時我們如何提供服務呢?我們可以為每一個客户提供一個新的服務對象進行服務。
這種方法看起來簡單,在實際應用中如果採用這種實現會有很多問題,顯而易見的是不斷的創建和銷燬新服務對象必將給造成系統資源的巨大開銷,導致系統的性能下降。
針對這個問題我們採用池的方式。池可以想象成就是一個容器保存着各種我們需要的對象。我們對這些對象進行復用,從而提高系統性能。從結構上看,它應該具有容器對象和具體的元素對象。
從使用方法上看,我們可以直接取得池中的元素來用,也可以把我們要做的任務交給它處理。所以從目的上看池應該有兩種類型,一種是用於處理客户提交的任務的,我們通常用Thread Pool(線程池)來描述它,另一種是客户從池中獲取有關的對象進行使用,我們通常用 Resource Pool(資源池)來描述它。它們可以分別解決不同的問題。以下結合具體的應用進行介紹。

資源池

首先介紹資源池(有時也可以叫做對象池)資源池可以維護多種可以重用的資源。資源池最基本的思想就是預先建立一些資源放置於內存對象中以備使用,例如Socket連接,JDBC連接,CORBA 對象 tuxedo連接等等。舉一個簡單的WEB數據查詢的例子,用户通過服務器建立一個JDBC連接,然後查詢,最後關閉。如果用户量比較大那麼對JDBC的連接管理就自然會成為應用瓶頸。
採用資源池可以用來在多個客户訪問時提供對共享資源的管理機制。當一個客户訪問一種指定類型的資源時,服務器不是簡單的分配給客户新的資源而是從池中取得已經實例化的資源對象為它服務。
分析
首先我們分析一下這個問題中出現的所有實體,通過分析他們的共性來設計統一的接口。
我們可以得到一個ConnManger對象,通過它提供對多個Pool對象的創建和管理和為客户提供對資源的存取方法。一個採用特定的數據結構實現的Pool 對象用於存取指定類型的資源對象。對各種資源對象的抽象描述接口IpoolItem。所有需要重用的資源對象都要實現這個接口。
通過這三個基本的類和他們的方法,就可以實現一個簡單的資源池。下面我們進一步對它們進行改動,增加一些更有效的管理方法。
改進
錯誤恢復:在資源池中最常見的問題時如何處理出現異常的資源對象。池的實現必須提供完整的機制進行資源的保護,資源對象為什麼會出現異常呢,讓我們分析一下一個多客户的服務器程序可能出現的問題。一個資源在長時間使用後,連接可能發生了超時;數據服務的進程可能發生了退出;網絡可能中斷等等。那麼這個資源對象的狀態就會相應的中斷,使用這個資源的客户端就會發生異常,而且我們要求客户端在使用完資源後把這個資源放回池中,所以這一定會影響其他客户對資源的訪問,進一步使情況惡化,如果不對這種狀況進行處理,很有可能池中的所有資源都會變成不可用,從而服務器無法提供服務。我們必須提供一種方式使池可以處理發生故障的資源對象。而不是簡單的把對象放回池中。所以我們對ConnManager和Pool對象提供新的方法repairConnection和fixConnection;使客户端在發現資源異常時可以使用這個方法通知池恢復出錯的資源對象。動態管理:在系統的運行時客户的請求數量往往是一種具有波峯和波谷的曲線,所以我們希望在系統允許的範圍內,提供對池的動態管理簡單的説就是在峯值請求時池會動態的調整加大池的尺寸提供更多的可供使用的資源;波谷時減小池的尺寸進行資源的回收。考慮到這個目的,所以為Pool對象增加一個後台運行的監視線程在池對象創建後,按照一定的算法進行檢測Pool對象的運行狀態,實現動態調整的功能。補充説明一點如果Pool對象的內部數據結構的不同,可以提供更為豐富的管理機制。統一的接口。ConnManger對池對象的創建採用從配置文件中讀取配置信息的方式,動態的加載特定的PoolItem實例到相應的Pool對象中。從而可以保證池的多元性。

線程池

前面已經提到了很多的應用服務器,都需要處理從客户端發起的任務請求,這些任務往往具有高密度,短時間的特性,無論通過什麼方式在服務器得到client 請求後,服務器就需要獨立的處理這個客户請求。針對這個的問題,線程池提供了處理系統性能和大用户量請求之間的矛盾的方法,通過對多個任務重用已經存在的線程對象,降低了對線程對象創建和銷燬的開銷,由於當客户請求到了時,線程對象已經存在,可以提高請求的響應時間從而整體的提高了系統服務的表現。
下面給出一個線程池的簡單設計樣例(參見圖2)
分析
在這個環境中,我們必須注意到一個問題就是線程的邏輯和應用的任務邏輯的分離,不能把用户的應用邏輯固化到線程池的實現中。如果沒有達到這個目標那麼這個線程池的實現是有一定的侷限性的。為了實現這一點,必須對線程池的運行邏輯進行抽象通過一個任務的抽象接口來模擬客户提交的任務。
一個ThreadPool對象,它管理和創建可重用的線程對象TaskRunable,通過runTask方法接受客户提交的任務,並選擇可以使用的線程對象調用它的getTaks方法使其執行任務。線程池中重用的線程對象 TaskRunnable。它是一個獨立的線程對象,通過getTask方法執行由所在容器ThreadPool傳遞的任務。任務對象接口Itask。所以的客户任務都必須實現這個接口,從而保證線程邏輯和應用邏輯的分離。
改進
錯誤恢復:在TaskRunable對象中必須時刻監視thread對象的運行狀況,如果發生錯誤,必須通知ThreadPool 對象進行相應的處理保證所有的TaskRunable對象的運行正常,因此添加notfiyThreadCrash方法。動態管理:我們可以參照資源池的實現同樣提供一個監視線程Monitor管理ThreadPool對象的運行狀態,實現Pool的動態管理。