1. 程式人生 > >Tomcat性能監控與調優

Tomcat性能監控與調優

ftp工具 原本 urn toc 配置參數 詳細 tomcat優化 處理 pass

tomcat遠程debug

Tomcat是目前被應用得最多的一款Java Web服務器,很多人都會使用Tomcat來作為項目的服務器。也經常需要在開發的時候對Tomcat進行debug。在本地對Tomcat進行debug相信很多人都會,但如果需要對遠程的Tomcat進行debug,相信有部分小夥伴還是沒接觸過的,而本小節將簡單介紹一下如何對Tomcat進行遠程debug。

Tomcat遠程debug是基於 JDWP 協議實現的,關於 JDWP 協議,可參考以下文檔:

https://www.ibm.com/developerworks/cn/java/j-lo-jpda3/

想要進行遠程Debug,首先得配置一下遠程的Tomcat,讓其開啟遠程Debug模式。如下:

[root@server ~]# vim /home/tomcat/apache-tomcat-8.5.8/bin/startup.sh   # 在最後一行增加jdpa參數
exec "$PRGDIR"/"$EXECUTABLE" jpda start "$@"
[root@server ~]# vim /home/tomcat/apache-tomcat-8.5.8/bin/catalina.sh  # 將原本的localhost:8000改為9000
  if [ -z "$JPDA_ADDRESS" ]; then
    JPDA_ADDRESS="9000"
  fi
[root@server ~]# /home/tomcat/apache-tomcat-8.5.8/bin/startup.sh  # 啟動Tomcat
Using CATALINA_BASE:   /home/tomcat/apache-tomcat-8.5.8
Using CATALINA_HOME:   /home/tomcat/apache-tomcat-8.5.8
Using CATALINA_TMPDIR: /home/tomcat/apache-tomcat-8.5.8/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /home/tomcat/apache-tomcat-8.5.8/bin/bootstrap.jar:/home/tomcat/apache-tomcat-8.5.8/bin/tomcat-juli.jar
Tomcat started.
[root@server ~]# netstat -lntp |grep 9000  # 查看9000端口是否已被監聽
tcp        0      0 0.0.0.0:9000            0.0.0.0:*               LISTEN      17380/java 
[root@server ~]#

然後我們新建一個Controller,用於演示遠程debug,所以代碼也比較簡單。代碼如下:

package org.zero01.monitor_tuning.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * @program: monitor_tuning
 * @description: Tomcat遠程debug演示
 * @author: 01
 * @create: 2018-07-15 17:58
 **/
@RestController
@RequestMapping("/remote/debug")
public class TomcatRemoteDebugController {

    @RequestMapping("/hello")
    public String hello(@RequestParam(value = "size", defaultValue = "10") int size) {
        StringBuilder str = new StringBuilder();
        for (int i = 0; i < size; i++) {
            str.append(i);
        }
        return str.toString();
    }
}

因為我們需要打成war包上傳到遠程的服務器上,所以需要讓SpringBoot的啟動類繼承 SpringBootServletInitializer ,並且重寫其中的configure方法。代碼如下:

package org.zero01.monitor_tuning;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class MonitorTuningApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(MonitorTuningApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(MonitorTuningApplication.class);
    }
}

接著將pom.xml配置文件中的打包方式,指定為war包:

<groupId>org.zero01</groupId>
<artifactId>monitor_tuning</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

最後使用maven命令進行打包,命令如下:

mvn clean package -Dmaven.skip.test=true

打包好後,上傳到遠程的服務器上,我這裏使用的是rz命令上傳的,也可以使用ftp工具來上傳。將上傳好的war包放到Tomcat的webapps目錄下:

[root@server ~]# ls
monitor_tuning-0.0.1-SNAPSHOT.war
[root@server ~]# mv monitor_tuning-0.0.1-SNAPSHOT.war monitor_tuning.war
[root@server ~]# ls
monitor_tuning.war
[root@server ~]# mv monitor_tuning.war /home/tomcat/apache-tomcat-8.5.8/webapps/
[root@server ~]# ls /home/tomcat/apache-tomcat-8.5.8/webapps/  # Tomcat會自動解壓war包
monitor_tuning  monitor_tuning.war  ROOT  simple-blog
[root@server ~]# 

Tomcat能夠正常解壓war包後,到瀏覽器上進行訪問看看能否訪問到我們編寫的接口,如下就是訪問成功的:
技術分享圖片

遠程的服務器配置好後,回到我們的工程中,添加一個遠程的Tomcat:
技術分享圖片
技術分享圖片

配置Debug的端口號:
技術分享圖片

以及服務器的ip地址和端口號:
技術分享圖片

完成以上配置後,在測試的代碼上打一個斷點,如下:
技術分享圖片

然後使用Debug模式進行啟動:
技術分享圖片

啟動成功後,和之前一樣到瀏覽器上訪問測試接口。可以看到,成功進入到斷點的位置了,這就表示我們可以進行遠程Debug了:
技術分享圖片

如果我們希望普通的Java進程也能支持遠程Debug的話,只需要在啟動的時候加入如下啟動參數即可:

-agentlib:jdwp=transport=$JPDA_TRANSPORT address=$JPDA_ADDRESS,server=y,suspend=$JPDA_SUSPEND

例如Tomcat其實就是加了這段參數:
-agentlib:jdwp=transport=dt_socket,address=9000,server=y,suspend=n

tomcat-manager監控

tomcat-manager是Tomcat自帶的一個監控及管理工具,在低版本的Tomcat中,該監控工具默認是開啟的。而在高版本的Tomcat中,由於一些安全上的問題,默認是不開啟的。

官方文檔地址如下(Tomcat9.0版本):

https://tomcat.apache.org/tomcat-9.0-doc/manager-howto.html

在高版本的Tomcat中我們需要手動開啟這個監控工具,開啟步驟如下:

  1. 在 conf/tomcat-users.xml 文件中添加管理員用戶
  2. 新建 conf/Catalina/localhost/manager.xml 文件,在該文件中配置允許的遠程連接
  3. 重啟Tomcat服務

首先是第一步,在 conf/tomcat-users.xml 文件的 &lt; tomcat-users &gt; 標簽內,增加如下配置內容:

[root@server ~]# vim /home/tomcat/apache-tomcat-8.5.8/conf/tomcat-users.xml  // 配置內容如下
<role rolename="tomcat"/>
<role rolename="manager-status"/>
<role rolename="manager-gui"/>
<user username="zeroJun" password="123456a." roles="tomcat,manager-status,manager-gui"/>

第二步,新建 conf/Catalina/localhost/manager.xml 文件,在該文件中配置允許的遠程連接

[root@server ~]# vim /home/tomcat/apache-tomcat-8.5.8/conf/Catalina/localhost/manager.xml  // 配置內容如下
<?xml version="1.0" encoding="UTF-8"?>
<Context antiResourceLocking="false" privileged="true" >
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
         allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1|101.106.102.*" />  // 配置允許訪問的ip
  <Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
</Context>

第三步,啟動/重啟Tomcat服務:

[root@server ~]# /home/tomcat/apache-tomcat-8.5.8/bin/startup.sh 
Using CATALINA_BASE:   /home/tomcat/apache-tomcat-8.5.8
Using CATALINA_HOME:   /home/tomcat/apache-tomcat-8.5.8
Using CATALINA_TMPDIR: /home/tomcat/apache-tomcat-8.5.8/temp
Using JRE_HOME:        /usr
Using CLASSPATH:       /home/tomcat/apache-tomcat-8.5.8/bin/bootstrap.jar:/home/tomcat/apache-tomcat-8.5.8/bin/tomcat-juli.jar
Tomcat started.
[root@server ~]# 

啟動好後,在瀏覽器上訪問Tomcat的管理頁面,會要求輸入用戶名和密碼才能進行登錄:
技術分享圖片

登錄成功後,管理界面如下:
技術分享圖片

點擊 ”List Applications“ 可以看到當前的Tomcat部署的web應用列表:
技術分享圖片

在這裏點擊相應的按鈕,就可以重啟、重載、取消部署以及設置session過期時間:
技術分享圖片

在這裏可以上傳war包進行部署:
技術分享圖片

點擊右上角的 “Server Status” 可以看到Tomcat服務器的狀態信息:
技術分享圖片

如下:
技術分享圖片

我們在監控Tomcat的時候,就主要是查看這個界面中展示的信息,JVM一欄展示的是內存信息,而http-nio-8080一欄則是展示線程信息,一般我們關註這兩個地方就差不多了。

在該界面中,點擊右上角的 “Complete Server Status” 則能夠查看更完整的信息:
技術分享圖片


psi-probe監控

在上一小節中,我們簡單介紹了Tomcat自帶的監控工具,因為是自帶的,所以功能並不算很強大。而本小節將介紹更加強大的Tomcat監控工具,那就是psi-probe。

這家夥改了三次名,之前叫做lambdaprobe,最終的名字改為了psi-probe,之前是在googlecode下載,現在已經遷移到了github。

psi-probe的github地址如下:

https://github.com/psi-probe/psi-probe

使用git命令將psi-probe克隆到本地倉庫中,或者直接下載zip包再上傳到服務器也可以:

[root@01server ~]# cd /tmp
[root@01server /tmp]# git clone https://github.com/psi-probe/psi-probe.git

然後進入到psi-probe工程目錄中,使用maven命令進行編譯打包,這個編譯打包過程需要一段時間:

[root@01server /tmp]# cd psi-probe/
[root@01server /tmp/psi-probe]# mvn package -Dmaven.skip.test

打包完成後,將war包放到Tomcat的webapps目錄中:

[root@01server /tmp/psi-probe]# mv web/target/probe.war /usr/local/tomcat-8.5.32/webapps/

我這裏為了保證流程的完整,我這裏在另一臺服務器上安裝了新的Tomcat,所以我們還需要和之前一樣去開啟這個Tomcat的manager權限。

第一步,在 conf/tomcat-users.xml 文件的 &lt; tomcat-users &gt; 標簽內,增加如下配置內容:

[root@01server ~]# vim /usr/local/tomcat-8.5.32/conf/tomcat-users.xml  // 配置內容如下
<role rolename="tomcat"/>
<role rolename="manager-status"/>
<role rolename="manager-gui"/>
<user username="zeroJun" password="123456a." roles="tomcat,manager-status,manager-gui"/>

第二步,新建 conf/Catalina/localhost/manager.xml 文件,在該文件中配置允許的遠程連接

[root@01server ~]# vim /usr/local/tomcat-8.5.32/conf/Catalina/localhost/manager.xml  // 配置內容如下
<?xml version="1.0" encoding="UTF-8"?>
<Context antiResourceLocking="false" privileged="true" >
  <Valve className="org.apache.catalina.valves.RemoteAddrValve"
         allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1|101.106.102.*" />  // 配置允許訪問的ip
  <Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
</Context>

第三步,啟動/重啟Tomcat服務:

[root@01server ~]# startup.sh 
Using CATALINA_BASE:   /usr/local/tomcat-8.5.32
Using CATALINA_HOME:   /usr/local/tomcat-8.5.32
Using CATALINA_TMPDIR: /usr/local/tomcat-8.5.32/temp
Using JRE_HOME:        /usr/local/jdk1.8
Using CLASSPATH:       /usr/local/tomcat-8.5.32/bin/bootstrap.jar:/usr/local/tomcat-8.5.32/bin/tomcat-juli.jar
Tomcat started.
[root@01server ~]#

啟動好後,在瀏覽器上訪問psi-probe的管理頁面,同樣的會要求輸入用戶名和密碼才能進行登錄:
技術分享圖片

登錄成功後,主頁面如下,在這裏可以看到當前這個Tomcat服務器上的web應用:
技術分享圖片

在這個頁面上,可以看到web應用的統計信息、請求信息以及session信息,還可以對jsp進行預編譯。

在 “Data Source” 選項卡裏,可以看到數據源的相關信息,因為這裏目前沒有連接數據庫的應用,所以這塊是空的:
技術分享圖片

在 “Deployment” 選項卡裏,可以上傳war包到Tomcat上進行部署:
技術分享圖片

在 “logs” 選項卡裏,可以查看應用的日誌文件:
技術分享圖片

在 “Threads” 選項卡裏,可以查看到很詳細線程信息,和jstack打印出來的信息一樣:
技術分享圖片

在 “Cluster” 選項卡裏,可以查看到集群信息,由於沒有進行集群,所以這裏也是空的:
技術分享圖片

在 “System” 選項卡裏,可以查看到系統信息,例如JVM內存信息、系統屬性信息、操作系統信息等等:
技術分享圖片

在這個選項卡裏,我們還能實時看到內存信息,而且是圖表化的,很直觀:
技術分享圖片

在 “Connectors” 選項卡裏,可以查看到Tomcat的連接信息,例如請求數量、請求的處理時間以及請求響應字節數等信息,也是圖表化的:
技術分享圖片

在 “Gertificates” 選項卡裏,可以查看到證書相關的信息,我這裏也沒有配置證書,所以是空白的:
技術分享圖片

在 “Quick check” 選項卡裏,可以進行快速檢查,以此驗證服務環境是否是正常的:
技術分享圖片


Tomcat優化

在以上小節中,我們介紹了如何使用監控工具去監控Tomcat的運行狀況,而在監控之上就是調優。所以本小節將介紹一些簡單的Tomcat優化方式,主要涉及以下兩種優化(因為內存優化方面會單獨在另一篇JVM層GC調優文章中介紹):

  • 線程優化
  • 配置優化

1.線程優化:

我們都知道Tomcat是一個Web服務器,所以對於線程優化這方面主要還是關註用於http連接的線程。在以下官方文檔中,有對http連接線程相關參數的說明:

http://tomcat.apache.org/tomcat-8.5-doc/config/http.html

通過設置這些參數,我們能把Tomcat調整到一個較優的狀態。當然,這個調整需要根據服務器的具體配置及Tomcat的實際監控數據進行調整。常用的線程優化參數如下:

  • maxConnections:最大連接數,當達到最大連接數時,請求會被放到請求隊列裏等待處理,對於NiO和NiO2,默認值為10000。對於APR/本機,默認值為8192
  • acceptCount:最大請求隊列長度,當隊列滿時收到的任何請求都將被拒絕,默認值為100
  • MaxThreads:最大工作線程數量,該參數的值決定了可處理的並發請求的最大數量,默認值為200
  • minSpareThreads:最小空閑的工作線程數量,默認值為10
  • enableLookups:該參數用於在執行 request.getRemoteHost(); 語句時,能夠以DNS方式進行查詢,並返回遠程客戶端的實際主機名。默認值為false,會跳過DNS查詢,直接以字符串形式返回IP地址(從而提高性能),所以在生產環境下不要打開這個參數。
  • protocol:該參數用於配置http協議,默認值為HTTP/1.1。該參數還可以設置連接器,默認情況下它使用自動切換機制來選擇基於NIO的連接器或基於APR/本機的連接器。如果是高並發場景下使用APR連接器性能會更高些,可選的值如下:
    • org.apache.coyote.http11.Http11NioProtocol : NIO連接器
    • org.apache.coyote.http11.Http11Nio2Protocol :NIO2連接器
    • org.apache.coyote.http11.Http11AprProtocol :APR連接器

2.配置優化:

關於配置參數方面的介紹,官方文檔裏描述的也比較詳細了,地址如下:

http://tomcat.apache.org/tomcat-8.5-doc/config/host.html
http://tomcat.apache.org/tomcat-8.5-doc/config/context.html

常用的配置參數如下:

  • autoDeploy:該參數用於指定是否開啟熱部署,默認值為true。因為實現熱部署需要單獨開啟一個線程去周期性的檢查server.xml中appBase屬性所配置的目錄,默認為webapps目錄,所以會影響Tomcat的性能。在線上一般都是關閉的,也就是設置為false
  • reloadable:該參數用於開啟自動檢測代碼更改,當代碼更改時,會自動重新加載Web應用程序。默認值為false,該參數不應該在生產環境中開啟,會影響性能。但在開發過程中比較實用,所以挺多人會開啟這個參數,在上線時應該檢查該參數是否已關閉。

末尾:雖然現在的項目基本都是前後端分離了,JSP已經很少再用了,但不乏還是會出現JSP編寫的項目。如果是JSP項目,可以在不需要使用到session的JSP頁面上禁用session,不然每訪問一個JPS都開啟session的話,會影響性能。

Tomcat性能監控與調優