1. 程式人生 > >認識TomCat 的執行緒池Connector

認識TomCat 的執行緒池Connector

作為Web容器,需要承受較高的訪問量,能夠同時回應不同使用者的請求,能夠在惡劣環境下保持較高的穩定性和健壯性。在HTTP伺服器領域,Apache HTTPD的效率是最高的,也是最為穩定的,但它只能處理靜態頁面的請求,如果需要支援動態頁面請求,則必須安裝相應的外掛程式,比如mod_perl可以處理Perl指令碼,mod_python可以處理Python指令碼。

Tomcat是使用最廣的JAVA Web容器,功能強大,可擴充性強。

Tomcat 的執行緒池位於tomcat-util.jar檔中,包含了兩種執行緒池方案。

  • 方案一:使用APR的Pool技術,使用了JNI;
  • 方案二:使用JAVA實現的ThreadPool。這裡介紹的是第二種。如果想瞭解APR的Pool技術,可以檢視APR的原始程式碼。

ThreadPool預設建立了5個執行緒,儲存在一個200維的執行緒陣列中,建立時就啟動了這些執行緒,當然在沒有請求時,它們都處理「等待」狀態(其實就是一個while迴圈,不停的等待notify)。如果有請求時,空閒執行緒會被喚醒執行使用者的請求。

具體的請求過程是: 服務啟動時,建立一個一維執行緒陣列(maxThread=200個),並建立空閒執行緒(minSpareThreads=5個)隨時等待使用者請求。 當有使用者請求時,呼叫 threadpool.runIt(ThreadPoolRunnable)方法,將一個需要執行的例項傳給ThreadPool中。其中使用者需要執行的例項必須實現ThreadPoolRunnable介面。 ThreadPool 首先查詢空閒的執行緒,如果有則用它執行要執行ThreadPoolRunnable;如果沒有空閒執行緒並且沒有超過maxThreads,就一次性建立 minSpareThreads個空閒執行緒;如果已經超過了maxThreads了,就等待空閒執行緒了。總之,要找到空閒的執行緒,以便用它執行例項。找到後,將該執行緒從執行緒陣列中移走。 接著喚醒已經找到的空閒執行緒,用它執行執行例項(ThreadPoolRunnable)。 執行完ThreadPoolRunnable後,就將該執行緒重新放到執行緒陣列中,作為空閒執行緒供後續使用。

執行緒池作為提高程式處理資料能力的一種方案,應用非常廣泛。大量的伺服器都或多或少的使用到了執行緒池技術,不管是用JAVA還是C++實現,執行緒池都有如下的特點:
執行緒池一般有三個重要引數:

  • 1. 最大執行緒數。在程式執行的任何時候,執行緒數總數都不會超過這個數。如果請求數量超過最大數時,則會等待其他執行緒結束後再處理。
  • 2. 最大共用執行緒數,即最大空閒執行緒數。如果當前的空閒執行緒數超過該值,則多餘的執行緒會被殺掉。
  • 3. 最小共用執行緒數,即最小空閒執行緒數。如果當前的空閒數小於該值,則一次性建立這個數量的空閒執行緒,所以它本身也是一個建立執行緒的步長。

執行緒池有兩個概念:

  • 1. Worker執行緒。工作執行緒主要是執行執行程式碼,有兩種狀態:空閒狀態和執行狀態。在空閒狀態時,類似「休眠」,等待任務;處理執行狀態時,表示正在執行任務(Runnable)。
  • 2. 輔助執行緒。主要負責監控執行緒池的狀態:空閒執行緒是否超過最大空閒執行緒數或者小於最小空閒執行緒數等。如果不滿足要求,就調整之。

web server允許的最大執行緒連線數還受制於作業系統的核心引數設定,通常Windows是2000個左右,Linux是1000個左右。

編輯tomcat安裝目錄下的conf目錄下的server.xml檔,在tomcat設定檔server.xml中的<Connector />配置中,和連線數相關的引數有:

  • maxThreads=”150″ 表示最多同時處理150個連線,Tomcat使用執行緒來處理接收的每個請求。這個值表示Tomcat可建立的最大的執行緒數。預設值200。
  • minSpareThreads=”25″ 表示即使沒有人使用也開這麼多空執行緒等
  • maxSpareThreads=”75″ 表示如果最多可以空75個執行緒,例如某時刻有80人訪問,之後沒有人訪問了,則tomcat不會保留80個空執行緒,而是關閉5個空的。
    (一旦建立的執行緒超過這個值,Tomcat就會關閉不再需要的socket執行緒。預設值50。)

acceptCount=”100″ 當同時連線的人數達到maxThreads時,還可以接收排隊的連線數量,超過這個連線的則直接返回拒絕連線。(指定當任何能夠使用的處理請求的執行緒數都被使用時,能夠放到處理佇列中的請求數,超過這個數的請求將不予處理。預設值10。 )
其中和最大連線數相關的引數為maxThreads和acceptCount。如果要加大併發連線數,應同時加大這兩個引數。

執行緒池配置:

<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
keystoreFile="/Users/max/Documents/settings/tomcat.keystore" keystorePass="changeit" keyAlias="tomcat"
clientAuth="false" sslProtocol="TLS" />