【Tomcat】Tomcat性能分析


一、預研任務介紹和預研目標

任務介紹:

Apache Tomcat是目前較為流行的web服務器,以其技術先進、性能穩定著稱,其次它還是一個免費開源的項目。

Tomcat性能分析的意義在於能為日常工作中的一些內存泄露和tomcat crash問題提供參考,本文主要通過一些工具的使用和一些參數的講解,穿插分析tomcat性能。

預研目標:

通過壓力測試以及性能檢測工具監控,分析tomcat的性能,並做相應的調優操作。

二、操作步驟

(0)假如測試的並發數過大,請預先對tomcat的maxThreads選項進行設置;

1)部署測試對象

以供電局需求側分析項目作為web壓力測試對象,在其web.xml中將spring security的過濾器模塊注釋掉,並將其部署上tomcat7.0

測試是否成功去除spring security攔截,在頁面輸入http://localhost:8080/DSM/index.jsp,如圖1則表示操作成功。

 

 

去除攔截后直接越過登錄檢測登入系統

 

dosh下輸入JVisualVM [1],開啟tomcat性能監控。

至此測試對象已經部署完畢。

 

(2)使用http_load [2]進行壓力測試 

http://localhost:8080/DSM/index.jsp
http://localhost:8080/DSM/rest/CommunicatManagement/NoticeboardManagement/NoticeboardViewer?_dc=1376059585323&searchString=&datetimeArray=&page=1&start=0&limit=20
http://localhost:8080/DSM/rest/CommunicatManagement/WorkflowManagement/WorkflowViewer/WorkflowViewer?_dc=1376059701735&searchString=&page=1&start=0&limit=20
http://localhost:8080/DSM/rest/CommunicatManagement/GuestbookManagement/GuestbookViewer?_dc=1376059728941&searchString=&datetimeArray=&page=1&start=0&limit=12
http://localhost:8080/DSM/rest/CommunicatManagement/PowerCutManagement/PowerCutViewerService?_dc=1376059750417&searchString=&datetimeArray=&page=1&start=0&limit=20

在當前目錄建立url.txt,內容如上面所示。url.txt內容的意義在於模仿用戶進入主界面然后對通信管理模塊的所有功能進行並行訪問。至於這些url如何獲取出來用於測試,你可以用ChromeDeveloper Tools或者FirefoxFireBug進行獲取。

http_load -p 50 -s 600 url.txt

dosh下輸入如上所示的命令,該命令使用http_loadurl.txt中包含的所有url進行並發數為50、為期600秒的壓力測試,承受這個壓力的即是我們部署的在tomcat上的項目,所以文章雖然叫tomcat分析,但實質也是在對我們的程序進行性能分析。這個時候你可以泡杯茶、散散步靜待10分鍾的結束,JVisualVM已經在后台默默的工作中了。

 

3)數據分析

復制代碼
8559 fetches, 50 max parallel, 2.95904e+07 bytes, in 600 seconds
3457.23 mean bytes/connection
14.265 fetches/sec, 49317.4 bytes/sec
msecs/connect: 0.0851023 mean, 0.341 max, 0.015 min
msecs/first-response: 3458.08 mean, 26924.7 max, 0.225 min
991 bad byte counts
HTTP response codes:
  code 200 -- 7568
  code 500 -- 991
復制代碼

10分鍾到了,在dosh下截獲如上所示的壓力測試報告。第1行關注其產生了8559個請求,最大並發數為50;第3行關注其每秒處理的請求數為14;第4行關注到每次連接(url里面的內容被處理一次稱為一次連接)的平均毫秒為0.0851023(效率高的可怕,這是hibernate的緩存在發揮作用);最后一行我們看到有991條請求當掉了,說明我們的程序性能還是有一定的問題。后台報的錯誤主要是oracle數據庫連接錯誤,這表明我們的數據庫連接池存在一定的問題,需要進一步進行優化。

然而僅憑這些數據,我們還得不出什么直觀的性能分析結果,照目前來說,只能算還正常。進一步地,我們需要配合jvisualvm進行分析。

 

4jvisualvm分析

 

2 CPU變化圖

 

由圖片可以得出,簡單的壓力測試中CPU的最大占有率達到19%左右,測試環境是在我的個人PC機(I5CPU)上,可見並發對CPU的壓力還是很大的。峰值之后的曲線還是比較平緩的,這是CPU的調度能力發揮了作用。假如是對服務器做並發測試的話,這個數據就顯得非常重要了。

 

占用CPU最大的三個方法

 

Tomcat服務器自帶的任務調度和oracle數據庫連接占據了最大的CPU,可見我們的主要壓力都作用在了oracletomcat上了。

 

堆內存變化圖

 

堆內存中,最大的使用內存才達到414M左右,可見並發對內存的要求不高。曲線非常秘密的那一塊說明發生了頻繁的產生對象和垃圾回收,JVMGC還是非常強大的,它一直在背后默默的回收垃圾。除了峰值參考,曲線的另一個意義在於,觀察上升和下降的幅度是否大抵一致,如若一直上漲,就有可能是程序出了問題,例如某個for循環寫錯了,這個時候就會報java.lang.OutOfMemoryError: Java heap space錯誤。

 

持久代內存變化圖

 

持久代的內存完全沒有波動,說明我們沒有發生內存溢出(一般內存溢出都是這里發生的)。為什么一般的內存溢出會發生在這里?PermGen [3]意為permanent generation,即持久代(年老代),程序頻繁的讀/寫數據庫將會對這一層造成極大壓力,溢出后會報java.lang.OutOfMemoryError: PermGen space錯誤。

 

占用內存最大的三個類

 

這里我們可以得出,字符串類型的操作以及IO讀寫在壓力測試中是發生得最平凡的。

 

5參數調優 [4]和數據庫連接池調優

假如你是window 32/64bit,請在tomcat_home/bin下新建setenv.bat並輸入以下內容:

set JAVA_OPTS=%JAVA_OPTS%
-Xms1024m -Xmx2048m -XX:PermSize=32m
-XX:MaxPermSize=512m -Xss2m -XX:+UseConcMarkSweepGC
-XX:+CMSClassUnloadingEnabled

假如你是linux 32/64bit,請在tomcat_home/bin下新建setenv.sh並輸入以下內容:

export JAVA_OPTS="$JAVA_OPTS -Xms1024m -Xmx2048m -XX:PermSize=32m
-XX:MaxPermSize=512m -Xss2m -XX:+UseConcMarkSweepGC
-XX:+CMSClassUnloadingEnabled
-Djava.awt.headless=true"

假如你是以eclipse啟動tomcat,請在其vm arguments添加如下內容:

-Xms1024m -Xmx2048m -XX:PermSize=32m
-XX:MaxPermSize=512m -Xss2m -XX:+UseConcMarkSweepGC
-XX:+CMSClassUnloadingEnabled
-Djava.awt.headless=true

下面對所有參數進行一一解釋:

  • -Xms1024m 初始化堆的大小
  • -Xmx2048m 堆的最大值(最大設置為內存值的80%
  • -XX:PermSize=32m 初始化持久代內存大小
  • -XX:MaxPermSize=512m 最大持久代內存大小
  • -Xss2m 方法棧內存大小
  • -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled 啟用並行垃圾收集器
  • -Djava.awt.headless=true 為了不影響linux圖形化效果,我們可以添加這個參數

另外,如果你要為你的orcale數據庫添加unicode默認支持,則加入如下參數:

-Doracle.jdbc.defaultNChar=true

 下一步,我們需要對數據庫連接池進行調優:

復制代碼
<!--配置apache dbcp數據源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
    <property name="url"
        value="jdbc:oracle:thin:@192.168.0.3:1520:NIKEY" />
    <property name="username" value="PHOENIX" />
    <property name="password" value="123456" />
    <!-- 連接池啟動時的初始值 -->
    <property name="initialSize" value="50" />
    <!-- 連接池的最大值 -->
    <property name="maxActive" value="100" />
    <!-- 最大空閑值.當經過一個高峰時間后,連接池可以慢慢將已經用不到的連接慢慢釋放一部分,一直減少到maxIdle為止 -->
    <property name="maxIdle" value="10" />
    <!-- 最小空閑值.當空閑的連接數少於閥值時,連接池就會預申請去一些連接,以免洪峰來時來不及申請 -->
    <property name="minIdle" value="5" />
</bean>
復制代碼

備注:所需jar包:commons-dbcp.jar & commons-pool.jar & commons-logging.jar

 

6)再測試

使用上面同樣的壓力測試語句http_load -p 50 -s 600 url.txt,靜待10分鍾結束。

復制代碼
54995 fetches, 50 max parallel, 1.32363e+08 bytes, in 600 seconds
2406.83 mean bytes/connection
91.6583 fetches/sec, 220606 bytes/sec
msecs/connect: 0.0579369 mean, 0.308 max, 0.013 min
msecs/first-response: 544.293 mean, 6322.84 max, 0.111 min
HTTP response codes:
  code 200 -- 54995
復制代碼

54995多個請求全部成功,一秒處理91個請求,每個連接的平均時間為0.05豪秒,效率立即體現出來了。

再看CPU/內存使用圖如下:

 

堆內存變化圖

 

7 CPU變化圖

CPU的變化最大不超過20%,然而調優后需要考慮到由於程序能處理更多的並發,那么也會拉長GC的回收時間,那你所需要注意的是就是這么長的時間里峰值會達到多少,應該在參數配置中予以考慮。

 

7)總結

Tomcat的性能足以承受我們日常工作的並發操作,但是需要配置調優參數以防止撐爆,並且為了提高數據庫交互的效率我們最好使用連接池技術。

三、參考文獻

[1] Java自帶的GUI性能監控工具Jconsole以及JisualVM簡介

[2] Linuxhttp_load使用簡介

[3] JVM調優總結(十)-調優方法

[4] JVM 幾個重要的參數 & Java HotSpot VM Options & Java 6 JVM參數選項大全(中文版)

 

 

 

 

一、預研任務介紹和預研目標

任務介紹:

Apache Tomcat是目前較為流行的web服務器,以其技術先進、性能穩定著稱,其次它還是一個免費開源的項目。

Tomcat性能分析的意義在於能為日常工作中的一些內存泄露和tomcat crash問題提供參考,本文主要通過一些工具的使用和一些參數的講解,穿插分析tomcat性能。

預研目標:

通過壓力測試以及性能檢測工具監控,分析tomcat的性能,並做相應的調優操作。

二、操作步驟

(0)假如測試的並發數過大,請預先對tomcat的maxThreads選項進行設置;

1)部署測試對象

以供電局需求側分析項目作為web壓力測試對象,在其web.xml中將spring security的過濾器模塊注釋掉,並將其部署上tomcat7.0

測試是否成功去除spring security攔截,在頁面輸入http://localhost:8080/DSM/index.jsp,如圖1則表示操作成功。

 

 

去除攔截后直接越過登錄檢測登入系統

 

dosh下輸入JVisualVM [1],開啟tomcat性能監控。

至此測試對象已經部署完畢。

 

(2)使用http_load [2]進行壓力測試 

http://localhost:8080/DSM/index.jsp
http://localhost:8080/DSM/rest/CommunicatManagement/NoticeboardManagement/NoticeboardViewer?_dc=1376059585323&searchString=&datetimeArray=&page=1&start=0&limit=20
http://localhost:8080/DSM/rest/CommunicatManagement/WorkflowManagement/WorkflowViewer/WorkflowViewer?_dc=1376059701735&searchString=&page=1&start=0&limit=20
http://localhost:8080/DSM/rest/CommunicatManagement/GuestbookManagement/GuestbookViewer?_dc=1376059728941&searchString=&datetimeArray=&page=1&start=0&limit=12
http://localhost:8080/DSM/rest/CommunicatManagement/PowerCutManagement/PowerCutViewerService?_dc=1376059750417&searchString=&datetimeArray=&page=1&start=0&limit=20

在當前目錄建立url.txt,內容如上面所示。url.txt內容的意義在於模仿用戶進入主界面然后對通信管理模塊的所有功能進行並行訪問。至於這些url如何獲取出來用於測試,你可以用ChromeDeveloper Tools或者FirefoxFireBug進行獲取。

http_load -p 50 -s 600 url.txt

dosh下輸入如上所示的命令,該命令使用http_loadurl.txt中包含的所有url進行並發數為50、為期600秒的壓力測試,承受這個壓力的即是我們部署的在tomcat上的項目,所以文章雖然叫tomcat分析,但實質也是在對我們的程序進行性能分析。這個時候你可以泡杯茶、散散步靜待10分鍾的結束,JVisualVM已經在后台默默的工作中了。

 

3)數據分析

復制代碼
8559 fetches, 50 max parallel, 2.95904e+07 bytes, in 600 seconds
3457.23 mean bytes/connection
14.265 fetches/sec, 49317.4 bytes/sec
msecs/connect: 0.0851023 mean, 0.341 max, 0.015 min
msecs/first-response: 3458.08 mean, 26924.7 max, 0.225 min
991 bad byte counts
HTTP response codes:
  code 200 -- 7568
  code 500 -- 991
復制代碼

10分鍾到了,在dosh下截獲如上所示的壓力測試報告。第1行關注其產生了8559個請求,最大並發數為50;第3行關注其每秒處理的請求數為14;第4行關注到每次連接(url里面的內容被處理一次稱為一次連接)的平均毫秒為0.0851023(效率高的可怕,這是hibernate的緩存在發揮作用);最后一行我們看到有991條請求當掉了,說明我們的程序性能還是有一定的問題。后台報的錯誤主要是oracle數據庫連接錯誤,這表明我們的數據庫連接池存在一定的問題,需要進一步進行優化。

然而僅憑這些數據,我們還得不出什么直觀的性能分析結果,照目前來說,只能算還正常。進一步地,我們需要配合jvisualvm進行分析。

 

4jvisualvm分析

 

2 CPU變化圖

 

由圖片可以得出,簡單的壓力測試中CPU的最大占有率達到19%左右,測試環境是在我的個人PC機(I5CPU)上,可見並發對CPU的壓力還是很大的。峰值之后的曲線還是比較平緩的,這是CPU的調度能力發揮了作用。假如是對服務器做並發測試的話,這個數據就顯得非常重要了。

 

占用CPU最大的三個方法

 

Tomcat服務器自帶的任務調度和oracle數據庫連接占據了最大的CPU,可見我們的主要壓力都作用在了oracletomcat上了。

 

堆內存變化圖

 

堆內存中,最大的使用內存才達到414M左右,可見並發對內存的要求不高。曲線非常秘密的那一塊說明發生了頻繁的產生對象和垃圾回收,JVMGC還是非常強大的,它一直在背后默默的回收垃圾。除了峰值參考,曲線的另一個意義在於,觀察上升和下降的幅度是否大抵一致,如若一直上漲,就有可能是程序出了問題,例如某個for循環寫錯了,這個時候就會報java.lang.OutOfMemoryError: Java heap space錯誤。

 

持久代內存變化圖

 

持久代的內存完全沒有波動,說明我們沒有發生內存溢出(一般內存溢出都是這里發生的)。為什么一般的內存溢出會發生在這里?PermGen [3]意為permanent generation,即持久代(年老代),程序頻繁的讀/寫數據庫將會對這一層造成極大壓力,溢出后會報java.lang.OutOfMemoryError: PermGen space錯誤。

 

占用內存最大的三個類

 

這里我們可以得出,字符串類型的操作以及IO讀寫在壓力測試中是發生得最平凡的。

 

5參數調優 [4]和數據庫連接池調優

假如你是window 32/64bit,請在tomcat_home/bin下新建setenv.bat並輸入以下內容:

set JAVA_OPTS=%JAVA_OPTS%
-Xms1024m -Xmx2048m -XX:PermSize=32m
-XX:MaxPermSize=512m -Xss2m -XX:+UseConcMarkSweepGC
-XX:+CMSClassUnloadingEnabled

假如你是linux 32/64bit,請在tomcat_home/bin下新建setenv.sh並輸入以下內容:

export JAVA_OPTS="$JAVA_OPTS -Xms1024m -Xmx2048m -XX:PermSize=32m
-XX:MaxPermSize=512m -Xss2m -XX:+UseConcMarkSweepGC
-XX:+CMSClassUnloadingEnabled
-Djava.awt.headless=true"

假如你是以eclipse啟動tomcat,請在其vm arguments添加如下內容:

-Xms1024m -Xmx2048m -XX:PermSize=32m
-XX:MaxPermSize=512m -Xss2m -XX:+UseConcMarkSweepGC
-XX:+CMSClassUnloadingEnabled
-Djava.awt.headless=true

下面對所有參數進行一一解釋:

  • -Xms1024m 初始化堆的大小
  • -Xmx2048m 堆的最大值(最大設置為內存值的80%
  • -XX:PermSize=32m 初始化持久代內存大小
  • -XX:MaxPermSize=512m 最大持久代內存大小
  • -Xss2m 方法棧內存大小
  • -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled 啟用並行垃圾收集器
  • -Djava.awt.headless=true 為了不影響linux圖形化效果,我們可以添加這個參數

另外,如果你要為你的orcale數據庫添加unicode默認支持,則加入如下參數:

-Doracle.jdbc.defaultNChar=true

 下一步,我們需要對數據庫連接池進行調優:

復制代碼
<!--配置apache dbcp數據源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
    <property name="url"
        value="jdbc:oracle:thin:@192.168.0.3:1520:NIKEY" />
    <property name="username" value="PHOENIX" />
    <property name="password" value="123456" />
    <!-- 連接池啟動時的初始值 -->
    <property name="initialSize" value="50" />
    <!-- 連接池的最大值 -->
    <property name="maxActive" value="100" />
    <!-- 最大空閑值.當經過一個高峰時間后,連接池可以慢慢將已經用不到的連接慢慢釋放一部分,一直減少到maxIdle為止 -->
    <property name="maxIdle" value="10" />
    <!-- 最小空閑值.當空閑的連接數少於閥值時,連接池就會預申請去一些連接,以免洪峰來時來不及申請 -->
    <property name="minIdle" value="5" />
</bean>
復制代碼

備注:所需jar包:commons-dbcp.jar & commons-pool.jar & commons-logging.jar

 

6)再測試

使用上面同樣的壓力測試語句http_load -p 50 -s 600 url.txt,靜待10分鍾結束。

復制代碼
54995 fetches, 50 max parallel, 1.32363e+08 bytes, in 600 seconds
2406.83 mean bytes/connection
91.6583 fetches/sec, 220606 bytes/sec
msecs/connect: 0.0579369 mean, 0.308 max, 0.013 min
msecs/first-response: 544.293 mean, 6322.84 max, 0.111 min
HTTP response codes:
  code 200 -- 54995
復制代碼

54995多個請求全部成功,一秒處理91個請求,每個連接的平均時間為0.05豪秒,效率立即體現出來了。

再看CPU/內存使用圖如下:

 

堆內存變化圖

 

7 CPU變化圖

CPU的變化最大不超過20%,然而調優后需要考慮到由於程序能處理更多的並發,那么也會拉長GC的回收時間,那你所需要注意的是就是這么長的時間里峰值會達到多少,應該在參數配置中予以考慮。

 

7)總結

Tomcat的性能足以承受我們日常工作的並發操作,但是需要配置調優參數以防止撐爆,並且為了提高數據庫交互的效率我們最好使用連接池技術。

三、參考文獻

[1] Java自帶的GUI性能監控工具Jconsole以及JisualVM簡介

[2] Linuxhttp_load使用簡介

[3] JVM調優總結(十)-調優方法

[4] JVM 幾個重要的參數 & Java HotSpot VM Options & Java 6 JVM參數選項大全(中文版)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM