服務器優化:Tomcat、JVM 性能調優筆記

找到 Tomcat 根目錄下的 conf 目錄,修改 server.xml 文件的內容。對於這部分的調優,我所瞭解到的就是無非設置一下 Tomcat 服務器的最大併發數和 Tomcat 初始化時創建的線程數的設置,當然還有其他一些性能調優的設置,下圖是我根據我機子的性能設置的一些參數值,給各位詳細解釋一下吧:

1、URIEncoding=“UTF-8”:設置 Tomcat 的字符集。這種配置我們一般是不會設置的,因爲關於亂碼的轉換我們會在具體項目中具體處理,直接修改 Tomcat 的字符集未免過於太死板。

2、maxThreads=“300”:設置當前 Tomcat 的最大併發數。Tomcat 默認配置的最大請求數是 150 個,即同時能支持 150 個併發。但是在實際運用中,最大併發數與硬件性能和 CPU 數量都有很大關係的,更好的硬件、更高的處理器都會使 Tomcat 支持更多的併發數。如果一般在實際開發中,當某個應用擁有 250 個以上併發的時候,都會考慮到應用服務器的集羣。

3、minSpareThreads=“50”:設置當前 Tomcat 初始化時創建的線程數,默認值爲 25。

4、acceptCount=“250”:當同時連接的人數達到 maxThreads 參數設置的值時,還可以接收排隊的連接數量,超過這個連接的則直接返回拒絕連接。指定當任何能夠使用的處理請求的線程數都被使用時,能夠放到處理隊列中的請求數,超過這個數的請求將不予處理。默認值爲 100。在實際應用中,如果想加大 Tomcat 的併發數 ,應該同時加大 acceptCount 和 maxThreads 的值。整編:微信公衆號,搜雲庫技術團隊,ID:souyunku

5、enableLookups=“false”:是否開啓域名反查,一般設置爲 false 來提高處理能力,它的取值還有 true,一般很少使用。

6、maxKeepAliveRequests=“1”:nginx 動態的轉給 tomcat,nginx 是不能 keepalive 的,而 tomcat 端默認開啓了 keepalive,會等待 keepalive 的 timeout,默認不設置就是使用 connectionTimeout。所以必須設置 tomcat 的超時時間,並關閉 tomcat 的 keepalive。否則會產生大量 tomcat 的 socket timewait。

maxKeepAliveRequests=”1” 就可以避免 tomcat 產生大量的 TIME_WAIT 連接,從而從一定程度上避免 tomcat 假死。

JVM 性能調優

Tomcat 本身還是運行在 JVM 上的,通過對 JVM 參數的調整我們可以使 Tomcat 擁有更好的性能。目前針對 JVM 的調優主要有兩個方面:內存調優和垃圾回收策略調優。

一、內存調優

找到 Tomcat 根目錄下的 bin 目錄,設置 catalina.sh 文件中 JAVA_OPTS 變量即可,因爲後面的啓動參數會把 JAVA_OPTS 作爲 JVM 的啓動參數來處理。再說 Java 虛擬機的內存結構是有點複雜的,相信很多人在理解上都是很抽象的,它主要分爲堆、棧、方法區和垃圾回收系統等幾個部分組成,下面是我從網上扒的內存結構圖:

內存調優這塊呢,無非就是通過修改它們各自的內存空間的大小,使應用能夠更加合理的運用,下圖是我根據我機子的性能設置的參數,給各位詳細解釋一下各個參數的含義吧:

1、-Xmx512m:設置 Java 虛擬機的堆的最大可用內存大小,單位:兆 (m),整個堆大小 = 年輕代大小 + 年老代大小 + 持久代大小。持久代一般固定大小爲 64m。堆的不同分佈情況,對系統會產生一定的影響。儘可能將對象預留在新生代,減少老年代 GC 的次數(通常老年回收起來比較慢)。

實際工作中,通常將堆的初始值和最大值設置相等,這樣可以減少程序運行時進行的垃圾回收次數和空間擴展,從而提高程序性能。整編:微信公衆號,搜雲庫技術團隊,ID:souyunku

2、-Xms512m:設置 Java 虛擬機的堆的初始值內存大小,單位:兆 (m),此值可以設置與 - Xmx 相同,以避免每次垃圾回收完成後 JVM 重新分配內存。

3、-Xmn170m:設置年輕代內存大小,單位:兆 (m),此值對系統性能影響較大,Sun 官方推薦配置爲整個堆的 3/8。一般在增大年輕代內存後,也會將會減小年老代大小。

4、-Xss128k:設置每個線程的棧大小。JDK5.0 以後每個線程棧大小爲 1M,以前每個線程棧大小爲 256K。更具應用的線程所需內存大小進行調整。

在相同物理內存下,減小這個值能生成更多的線程。但是操作系統對一個進程內的線程數還是有限制的,不能無限生成,經驗值在 3000~5000 左右。

5、-XX:NewRatio=4:設置年輕代(包括 Eden 和兩個 Survivor 區)與年老代的比值(除去持久代)。設置爲 4,則年輕代與年老代所佔比值爲 1:4,年輕代佔整個堆棧的 1/5 。

6、-XX:SurvivorRatio=4:設置年輕代中 Eden 區與 Survivor 區的大小比值。設置爲 4,則兩個 Survivor 區與一個 Eden 區的比值爲 2:4,一個 Survivor 區佔整個年輕代的 1/6。

7、-XX:MaxPermSize=16m:設置持久代大小爲 16m,上面也說了,持久代一般固定的內存大小爲 64m。

8、-XX:MaxTenuringThreshold=0:設置垃圾最大年齡。

如果設置爲 0 的話,則年輕代對象不經過 Survivor 區,直接進入年老代。對於年老代比較多的應用,可以提高效率。

如果將此值設置爲一個較大值,則年輕代對象會在 Survivor 區進行多次複製,這樣可以增加對象再年輕代的存活時間,增加在年輕代即被回收的概論。

二、垃圾回收策略調優

找到 Tomcat 根目錄下的 bin 目錄,也是設置 catalina.sh 文件中 JAVA_OPTS 變量即可。我們都知道 Java 虛擬機都有默認的垃圾回收機制,但是不同的垃圾回收機制的效率是不同的,正是因爲這點我們才經常對 Java 虛擬機的垃圾回收策略進行相應的調整。下面也是通過我的一些需求來配置的垃圾回收策略:

Java 虛擬機的垃圾回收策略一般分爲:串行收集器、並行收集器和併發收集器。

串行收集器:

1、-XX:+UseSerialGC:代表垃圾回收策略爲串行收集器,即在整個掃描和複製過程採用單線程的方式來進行,適用於單 CPU、新生代空間較小及對暫停時間要求不是非常高的應用上,是 client 級別默認的 GC 方式,主要在 JDK1.5 之前的垃圾回收方式。

併發收集器:

1、-XX:+UseParallelGC:代表垃圾回收策略爲並行收集器 (吞吐量優先),即在整個掃描和複製過程採用多線程的方式來進行,適用於多 CPU、對暫停時間要求較短的應用上,是 server 級別默認採用的 GC 方式。此配置僅對年輕代有效。該配置只能讓年輕代使用併發收集,而年老代仍舊使用串行收集。整編:微信公衆號,搜雲庫技術團隊,ID:souyunku

2、-XX:ParallelGCThreads=4:配置並行收集器的線程數,即:同時多少個線程一起進行垃圾回收。此值最好配置與處理器數目相等。

3、-XX:+UseParallelOldGC:配置年老代垃圾收集方式爲並行收集。JDK6.0 支持對年老代並行收集 。

4、-XX:MaxGCPauseMillis=100:設置每次年輕代垃圾回收的最長時間,如果無法滿足此時間,JVM 會自動調整年輕代大小,以滿足此值。

5、-XX:+UseAdaptiveSizePolicy:設置此選項後,並行收集器會自動選擇年輕代區大小和相應的 Survivor 區比例,以達到目標系統規定的最低相應時間或者收集頻率等,此值建議使用並行收集器時,一直打開。

併發收集器:

1、-XX:+UseConcMarkSweepGC:代表垃圾回收策略爲併發收集器。

好了,到此我對虛擬機的垃圾回收策略總結就這麼多,還是這句話:優化的學習一直在路上,下面還有一張從其他博客中偷到的圖,據說以上三種 GC 機制是需要配合使用的。

個人博客網站:https://programmerblog.xyz

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/4l7Wwg6gME7AlIP31BJ0gA