1. 程式人生 > >Tomcat優化之配置執行緒池

Tomcat優化之配置執行緒池

原文地址:https://bbs.aliyun.com/read/307481.html?spm=5176.bbsl239.0.0.nZJ2Kx&fpage=2

簡介

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

  1. 最大執行緒數。在程式執行的任何時候,執行緒數總數都不會超過這個數。如果請求數量超過最大數時,則會等待其他執行緒結束後再處理。
  2. 最大共享執行緒數,即最大空閒執行緒數。如果當前的空閒執行緒數超過該值,則多餘的執行緒會被殺掉。
  3. 最小共享執行緒數,即最小空閒執行緒數。如果當前的空閒數小於該值,則一次性建立這個數量的空閒執行緒,所以它本身也是一個建立執行緒的步長。 執行緒池有兩個概念:
  4. Worker執行緒。工作執行緒主要是執行執行程式碼,有兩種狀態:空閒狀態和執行狀態。在空閒狀態時,類似“休眠”,等待任務;處理執行狀態時,表示正在執行任務(Runnable)。
  5. 輔助執行緒。主要負責監控執行緒池的狀態:空閒執行緒是否超過最大空閒執行緒數或者小於最小空閒執行緒數等。如果不滿足要求,就調整之。

來 看一下執行緒池究竟是怎麼一回事?其實執行緒池的原理很簡單,類似於操作系統中的緩衝區的概念,它的流程如下:先啟動若干數量的執行緒,並讓這些執行緒都處於睡眠 狀態,當客戶端有一個新請求時,就會喚醒執行緒池中的某一個睡眠執行緒,讓它來處理客戶端的這個請求,當處理完這個請求後,執行緒又處於睡眠狀態。可能你也許會 問:為什麼要搞得這麼麻煩,如果每當客戶端有新的請求時,我就建立一個新的執行緒不就完了?這也許是個不錯的方法,因為它能使得你編寫程式碼相對容易一些,但 你卻忽略了一個重要的問題
??效能!就拿我所在的單位來說,我的單位是一個省級資料大集中的銀行網路中心,高峰期每秒的客戶端請求併發數超過100,如果 為每個客戶端請求建立一個新執行緒的話,那耗費的CPU時間和記憶體將是驚人的,如果採用一個擁有200個執行緒的執行緒池,那將會節約大量的的系統資源,使得更 多的CPU時間和記憶體用來處理實際的商業應用,而不是頻繁的執行緒建立與銷燬。


配置


使用執行緒池,用較少的執行緒處理較多的訪問,可以提高tomcat處理請求的能力。使用方式:
首先。開啟/conf/server.xml,增加
複製程式碼
  1. <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
  2.         maxThreads="500" minSpareThreads="20" maxIdleTime="60000" prestartminSpareThreads="true" maxQueueSize="100" />


name: 執行緒名稱namePrefix: 執行緒字首maxThreads : 最大併發連線數,不配置時預設200,一般建議設定500~ 800 ,要根據己的硬體設施條件和實際業務需求而定。
minSpareThreads:Tomcat啟動初始化的執行緒數,預設值25prestartminSpareThreads:在tomcat初始化的時候就初始化minSpareThreads的值, 不設定true時minSpareThreadsmaxQueueSize: 最大的等待佇列數,超過則拒絕請求minSpareThreads:執行緒最大空閒時間60秒。
然後,修改<connector ...="" style="box-sizing: border-box;">節點,增加executor屬性,如:

複製程式碼
  1. <Connector port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol"  
  2.         connectionTimeout="20000"  
  3.         redirectPort="8443"  
  4.         executor="tomcatThreadPool"  
  5.         enableLookups="false"  
  6.         acceptCount="100"  
  7.         maxPostSize="10485760"  
  8.         compression="on"  
  9.         disableUploadTimeout="true"  
  10.         compressionMinSize="2048"  
  11.         noCompressionUserAgents="gozilla, traviata"  
  12.         acceptorThreadCount="2"  
  13.         compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript"  
  14.         URIEncoding="utf-8"/>



port:連線埠。protocol:聯結器使用的傳輸方式。
Tomcat 8 設定 nio2 更好:org.apache.coyote.http11.Http11Nio2Protocolprotocol, Tomcat 6、7 設定 nio 更好:org.apache.coyote.http11.Http11NioProtocol
注:每個web客戶端請求對於伺服器端來說就一個單獨的執行緒,客戶端的請求數量增多將會導致執行緒數就上去了,CPU就忙著 跟執行緒切換。

而NIO則是使用單執行緒(單個CPU)或者只使用少量的多執行緒(多CPU)來接受Socket,而由執行緒池來處理堵塞在pipe 或者隊 列裡的請求.這樣的話,只要OS可以接受TCP的連線,web伺服器就可以處理該請求,大大提高了web伺服器的可伸縮性。

executor: 聯結器使用的執行緒池名稱enableLookups:禁用DNS 查詢acceptCount:指定當所有可以使用的處理請求的執行緒數都被使用時,可以放到處理佇列中的請求數,超過這個數的請求將不予處理,預設設定 100 。maxPostSize:限制 以FORM URL 引數方式的POST請求的內容大小,單位位元組,預設是 2097152(2兆),10485760 為 10M。

如果要禁用限制,則可以設定為 -1。acceptorThreadCount: 用於接收連線的執行緒的數量,預設值是1。一般這個指需要改動的時候是因為該伺服器是一個多核CPU,如果是多核 CPU 一般配置為 2。

compression:傳輸時是壓縮。compressionMinSize:壓縮的大小noCompressionUserAgents:不啟用壓縮的瀏覽器

提示:壓縮會增加Tomcat負擔,最好採用Nginx + Tomcat 或者 Apache + Tomcat 方式,壓縮交由Nginx/Apache 去做。

Tomcat 的壓縮是在客戶端請求伺服器對應資源後,從伺服器端將資原始檔壓縮,再輸出到客戶端,由客戶端的瀏覽器負責解壓縮並瀏覽。相對於普通的 瀏覽過程 HTML、CSS、Javascript和Text,它可以節省40% 左右的流量。更為重要的是,它可以對動態生成的,包括CGI、PHP、JSP、ASP、Servlet,SHTML等輸出的網頁也能進行壓縮,壓縮效率也很高。