JVM之Tomcat的优化
Tomcat8優化
tomcat服務器在JavaEE項目中使用率非常高,所以在生產環境對tomcat的優化也變得非 常重要了。
對于tomcat的優化,主要是從2個方面入手,一是,tomcat自身的配置,另一個是 tomcat所運行的jvm虛擬機的調優。
下面我們將從這2個方面進行講解。
Tomcat配置優化
部署安裝tomcat8
下載并安裝:https://tomcat.apache.org/download-80.cgi
點擊“Server Status”,輸入用戶名、密碼進行登錄,tomcat/tomcat
進去之后即可看到服務的信息。
禁用AJP連接
在服務狀態頁面中可以看到,默認狀態下會啟用AJP服務,并且占用8009端口。
什么是AJP呢?
AJP(Apache JServer Protocol)
AJPv13協議是面向包的。WEB服務器和Servlet容器通過TCP連接來交互;為了節省 SOCKET創建的昂貴代價,WEB服務器會嘗試維護一個永久TCP連接到servlet容器,并且 在多個請求和響應周期過程會重用連接。
我們一般是使用Nginx+tomcat的架構,所以用不著AJP協議,所以把AJP連接器禁用。
修改conf下的server.xml文件,將AJP服務禁用即可。
重啟tomcat,查看效果。
可以看到AJP服務已經不在了。
執行器(線程池)
在tomcat中每一個用戶請求都是一個線程,所以可以使用線程池提高性能。
修改server.xml文件:
保存退出,重啟tomcat,查看效果。
在頁面中顯示最大線程數為-1,這個是正常的,僅僅是顯示的問題,實際使用的指定的 值。
也有人遇到這樣的問題:https://blog.csdn.net/weixin_38278878/article/details/80144397
3種運行模式
tomcat的運行模式有3種:
默認的模式,性能非常低下,沒有經過任何優化處理和支持.
(new I/O),是Java SE 1.4及后續版本提供的一種新的I/O操作方式(即java.nio包及 其子包)。Java nio是一個基于緩沖區、并能提供非阻塞I/O操作的Java API,因此nio 也被看成是non-blocking I/O的縮寫。它擁有比傳統I/O操作(bio)更好的并發運行性 能。
安裝起來最困難,但是從操作系統級別來解決異步的IO問題,大幅度的提高性能.
推薦使用nio,不過,在tomcat8中有最新的nio2,速度更快,建議使用nio2.
設置nio2
可以看到已經設置為nio2了。
部署測試用的Java web項目
為了方便測試性能,我們將部署一個java web項目,這個項目本身和本套課程沒有什么 關系,僅僅用于測試。
注意:這里在測試時,我們使用一個新的tomcat,進行測試,后面再對其進行優化 調整,再測試。
創建dashboard數據庫
在資料中找到到sql腳本文件dashboard.sql,在linux服務器上執行。
cat dashboard.sql | mysql ‐uroot ‐proot創建完成后,可以看到有3張表。
部署web應用
在資料中找到itcat-dashboard-web.war,上傳到linux服務器,進行部署安裝。
cd /tmp/apache‐tomcat‐8.5.34/webapps rm ‐rf * mkdir ROOT cd ROOT/ rz上傳war包 jar ‐xvf itcat‐dashboard‐web.war rm ‐rf itcat‐dashboard‐web.war #修改數據庫配置文件 cd /tmp/apache‐tomcat‐8.5.34/webapps/ROOT/WEB‐INF/classes vim jdbc.properties #這里根據自己的實際情況進行配置 jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://node01:3306/dashboard? useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true jdbc.username=root jdbc.password=root重新啟動tomcat。
訪問首頁,查看是否已經啟動成功:http://192.168.40.133:8080/index
使用Apache JMeter進行測試
Apache Jmeter是開源的壓力測試工具,我們借助于此工具進行測試,將測試出tomcat 的吞吐量等信息。
下載安裝
下載地址:http://jmeter.apache.org/download_jmeter.cgi
安裝:直接將下載好的Zip壓縮包進行解壓即可。
進入bin目錄,找到jmeter.bat文件,雙擊打開即可啟動。
修改主題和語言
默認的主題是黑色風格的主題并且語言是英語,這樣不太方便使用,所以需要修改下主題和中文語言。
主題修改完成。
接下來設置語言為簡體中文。
語言修改完成。
創建首頁的測試用例
第一步:保存測試用例
第二步:添加線程組,使用線程模擬用戶的并發。
1000個線程,每個線程循環10次,也就是tomcat會接收到10000個請求。
第三步:添加http請求
第四步:添加請求監控
啟動、進行測試
聚合報告
在聚合報告中,重點看吞吐量。
調整tomcat參數進行優化
通過上面測試可以看出,tomcat在不做任何調整時,吞吐量為73次/秒。
禁用AJP服務
可以看到,禁用AJP服務后,吞吐量會有所提升。
當然了,測試不一定準確,需要多測試幾次才能看出是否有提升。
設置線程池
通過設置線程池,調整線程池相關的參數進行測試tomcat的性能。
最大線程數為500初始為50
<Executor name="tomcatThreadPool" namePrefix="catalina‐exec‐" maxThreads="500" minSpareThreads="50" prestartminSpareThreads="true"/>測試結果:
最大線程數為1000,初始為200
<Executor name="tomcatThreadPool" namePrefix="catalina‐exec‐" maxThreads="1000" minSpareThreads="200" prestartminSpareThreads="true"/>
吞吐量為151,性能有所提升。
最大線程數為5000,初始為1000
是否是線程數越多,速度越快呢?我們來測試下。
<Executor name="tomcatThreadPool" namePrefix="catalina‐exec‐" maxThreads="5000" minSpareThreads="1000" prestartminSpareThreads="true"/>
可以看到,雖然最大線程已經設置到5000,但是實際測試效果并不理想,并且平均的響 應時間也邊長了,所以單純靠提升線程數量是不能一直得到性能提升的。
設置最大等待隊列數
默認情況下,請求發送到tomcat,如果tomcat正忙,那么該請求會一直等待。這樣雖然 可以保證每個請求都能請求到,但是請求時間就會邊長。
有些時候,我們也不一定要求請求一定等待,可以設置最大等待隊列大小,如果超過就 不等待了。這樣雖然有些請求是失敗的,但是請求時間會雖短。
典型的應用:12306。
測試結果:
- 平均響應時間:3.1秒
- 響應時間明顯縮短
- 錯誤率:49.88%
- 錯誤率提升到一半,也可以理解,最大線程為500,測試的并發為1000
- 吞吐量:238次/秒
- 吞吐量明顯提升
結論:響應時間、吞吐量這2個指標需要找到平衡才能達到更好的性能。
設置nio2的運行模式
將最大線程設置為500進行測試:
<Executor name="tomcatThreadPool" namePrefix="catalina‐exec‐"maxThreads="500" minSpareThreads="50" prestartminSpareThreads="true"/> <!‐‐ 設置nio2 ‐‐> <Connector executor="tomcatThreadPool" port="8080" protocol="org.apache.coyote.http11.Http11Nio2Protocol" connectionTimeout="20000" redirectPort="8443" />
可以看到,平均響應時間有縮短,吞吐量有提升,可以得出結論:nio2的性能要高于 nio。
調整JVM參數進行優化
接下來,測試通過jvm參數進行優化,為了測試一致性,依然將最大線程數設置為500, 啟用nio2運行模式。
設置并行垃圾回收器
#年輕代、老年代均使用并行收集器,初始堆內存64M,最大堆內存512M JAVA_OPTS="‐XX:+UseParallelGC ‐XX:+UseParallelOldGC ‐Xms64m ‐Xmx512m ‐XX:+PrintGCDetails ‐XX:+PrintGCTimeStamps ‐XX:+PrintGCDateStamps ‐XX:+PrintHeapAtGC -Xloggc:../logs/gc.log"
測試結果與默認的JVM參數結果接近。(執行了2次測試,結果是第二次測試的結果)
查看GC日志文件
將gc.log文件上傳到gceasy.io查看gc中是否存在問題。
問題一:
在報告中顯示,在5次GC時,系統所消耗的時間大于用戶時間,這反應出的服務器的性能 存在瓶頸,調度CPU等資源所消耗的時間要長一些。
問題二
可以關鍵指標中可以看出,吞吐量表現不錯,但是gc時,線程的暫停時間稍有點長。
問題三:
通過GC的統計可以看出:
- 年輕代的gc有74次,次數稍有多,說明年輕代設置的大小不合適需要調整
- FullGC有8次,說明堆內存的大小不合適,需要調整
問題四:
從GC原因的可以看出,年輕代大小設置不合理,導致了多次GC。
調整年輕代大小
JAVA_OPTS="‐XX:+UseParallelGC ‐XX:+UseParallelOldGC ‐Xms128m ‐Xmx1024m ‐XX:NewSize=64m ‐XX:MaxNewSize=256m ‐XX:+PrintGCDetails ‐XX:+PrintGCTimeStamps ‐XX:+PrintGCDateStamps ‐XX:+PrintHeapAtGC ‐Xloggc:../logs/gc.log"將初始堆大小設置為128m,最大為1024m
初始年輕代大小64m,年輕代最大256m
從測試結果來看,吞吐量以及響應時間均有所提升。
查看GC日志:
可以看到GC次數要明顯減少,說明調整是有效的。
設置G1垃圾回收器
#設置了最大停頓時間100毫秒,初始堆內存128m,最大堆內存1024m JAVA_OPTS="‐XX:+UseG1GC ‐XX:MaxGCPauseMillis=100 ‐Xms128m ‐Xmx1024m ‐XX:+PrintGCDetails ‐XX:+PrintGCTimeStamps ‐XX:+PrintGCDateStamps ‐XX:+PrintHeapAtGC ‐Xloggc:../logs/gc.log"測試結果:
可以看到,吞吐量有所提升,評價響應時間也有所縮短。
小結
通過上述的測試,可以總結出,對tomcat性能優化就是需要不斷的進行調整參數,然后 測試結果,可能會調優也可能會調差,這時就需要借助于gc的可視化工具來看gc的情 況。再幫我們做出決策應該調整哪些參數。
總結
以上是生活随笔為你收集整理的JVM之Tomcat的优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: RTSP的报文结构
- 下一篇: GooFlow入门使用