SpringBoot-技術專區-用正確的姿勢如何用外接tomcat配置及執行(Tomcat優化分析)

李浩宇Alex發表於2021-08-13

前提概要

在特別特殊的時候,我們可能需要外接tomcat去執行程式,例如alitomcat等特殊場景,方便我們去定時化開發專案或者其他特殊場景。

外接tomcat執行

pom.xml檔案首先更改打包方式 war,再排除springboot內建的 web 專案下tomcat依賴

Maven配置調整

移除tomcat依賴或者將tomcat依賴scope改為provide,移除tomcat依賴

<dependency>
  <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!-- 移除嵌入式tomcat外掛 -->
    <exclusions>
      <exclusion>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
      </exclusion>
    </exclusions>
</dependency>

再引入tomcat依賴:

 <dependency>
    <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-tomcat</artifactId>
     <!--打包的時候可以不用包進去,別的設施會提供。事實上該依賴理論上可以參與編譯,測試,執行等週期。
                相當於compile,但是打包階段做了exclude操作-->
     <scope>provided</scope>
  </dependency>

將打包方式修改為war

<packaging>war</packaging>

調整springboot的啟動類

繼承org.springframework.boot.web.servlet.support.SpringBootServletInitializer,實現configure方法:
為什麼繼承該類,SpringBootServletInitializer原始碼註釋:

  • Note that a WebApplicationInitializer is only needed if you are building a war file and deploying it. If you prefer to run an embedded web server then you won't need this at all.

  • 注意,如果您正在構建WAR檔案並部署它,則需要WebApplicationInitializer。如果你喜歡執行一個嵌入式Web伺服器,那麼你根本不需要這個。

DemoApplication,讓其實現SpringBootServletInitializer,然後重寫configure()方法:

方式一,啟動類繼承SpringBootServletInitializer實現configure:
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(Application.class);
    }
}
方式二,新增加一個類繼承SpringBootServletInitializer實現configure:
public class ServletInitializer extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        //此處的Application.class為帶有@SpringBootApplication註解的啟動類
        return builder.sources(Application.class);
    }
}

注意事項
  • 使用外部Tomcat部署訪問的時候,application.properties(或者application.yml)中配置的將失效,請使用tomcat的埠,tomcat,webapps下專案名進行訪問。
server.port=
server.servlet.context-path=
  • 為了防止應用上下文所導致的專案訪問資源載入不到的問題,建議pom.xml檔案中標籤下新增標籤:
<build>
    <!-- 應與application.properties(或application.yml)中context-path保持一致 -->
    <finalName>war包名稱</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

  1. IDEA 下,執行mvn clean,--> mvn package ,等到專案打包成功,在該專案檔案位置找到target 下的 demo.war,拷貝到tomcat/webapps目錄下,

  2. 使用windows命令列,啟動tomcat伺服器,專案啟動成功會出現, spring的標誌。

  3. 訪問路徑:localhost:8080/${打包檔名}/請求url

  4. 如何在訪問時去掉war包名?

原理:Tomcat的預設根目錄是ROOT,實際上ROOT這個專案在實際生產環境是沒有用的,所以我們可以用我們的專案覆蓋ROOT專案

操作過程

  1. 刪除ROOT下所有檔案及資料夾.

  2. 把我們專案的war包解壓後,專案目錄下的所有檔案和子目錄都拷貝到ROOT目錄下即可或者有更狠的一招:直接刪掉ROOT目錄,然後把我們的專案打包名稱改成ROOT.war,放到webapps下就行.

原理:Tomcat本身可以配置虛擬目錄。方法就是在Server.xml中節點下加入Context資訊。

如我們可以配置<Context path="/abc" docBase="D:\app\abc" ... />,那我們可以通過地址http://localhost:8080/abc來訪問我們放在D:\app\下面的abc專案。我們可以把這個path="/abc"修改為path=""。意思就是把abc對映到根目錄,訪問路徑就會變成http://localhost:8080/。

按照配置虛擬目錄的方式,在下新增一個Context節點,具體配置如下:

	<Engine name="Catalina" defaultHost="localhost">  
	        <Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true">  
	        	<Context path="" docBase="Interface" reloadable="true" />  
	    	<!--注:我這裡使用的是相對路徑,Interface專案是放在Tomcat的webapps目錄下的,當然也可以改為絕對路徑--> 
	        </Host>  
        </Engine>

Spring Boot也提供了對JMX監控的支援。JMX監控對外暴露的資訊相同,不過是使用MBeans容器將應用資料封裝管理。

  • Springboot 的jmx 是預設開啟的,如果tomcat 部署兩個原springboot 打成的war 包。

    • 需要將每一個專案的jmx關閉Application.properties 配置中 新增spring.jmx.enabled=false;

    • 在各自專案中都新增:spring.jmx.default-domain=project1以及spring.jmx.default-domain=project2保證domain是不一樣的。

tomcat 相關配置修改

修改預設的http訪問埠:8080 為 8181,在tomcat8.5/conf/server.xml檔案裡修改:示例

<Connector port="8181" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

修改預設的session有效期

在tomcat/conf/web.xml檔案裡修改,範圍是具體專案:示例

    <session-config>
       <session-timeout>30</session-timeout>
    </session-config>

在tomcat/conf/server.xml

<Context path="/test" docBase="/test"  
		  defaultSessionTimeOut="3600" isWARExpanded="true"  
		  isWARValidated="false" isInvokerEnabled="true"  
		  isWorkDirPersistent="false"/>

在java後臺程式碼裡配置,具體頁面的session有效時間

session.setMaxInactiveInterval(30*60);

生效優先順序: 3 > 2 > 1,

(彩蛋) tomcat 調優

tomcat 修改最大執行緒,在tomcat/conf/server.xml檔案裡修改:示例


  • maxThreads=“X” 表示最多同時處理X個連線
  • minSpareThreads=“X” 初始化X個連線
  • maxSpareThreads=“X” 表示如果最多可以有X個執行緒,一旦超過X個,則會關閉不在需要的執行緒
  • acceptCount=“X” 當同時連線的人數達到maxThreads時,還可以排隊,佇列大小為X.超過X就不處理

tomcat 記憶體優化

  • Windows 下的catalina.bat
  • Linux 下的catalina.sh 如:

JAVA_OPTS=’-Xms256m -Xmx512m’
-Xms JVM初始化堆的大小
-Xmx JVM堆的最大值 實際引數大小根據伺服器配置或者專案具體設定.

Tomcat IO優化
  1. 同步阻塞IO(JAVA BIO) 同步並阻塞,伺服器實現模式為一個連線一個執行緒(one connection one thread 想想都覺得恐怖,執行緒可是非常寶貴的資源),當然可以通過執行緒池機制改善.
    • BIO方式適用於連線數目比較小且固定的架構,這種方式對伺服器資源要求比較高,併發侷限於應用中,JDK1.4以前的唯一選擇,但程式直觀簡單易理解.
  2. JAVA NIO:又分為同步非阻塞IO,非同步阻塞IO 與BIO最大的區別one request one thread.可以複用同一個執行緒處理多個connection(多路複用)
    • NIO方式適用於連線數目多且連線比較短(輕操作)的架構,比如聊天伺服器,併發侷限於應用中,程式設計比較複雜,JDK1.4開始支援.
  3. 非同步非阻塞IO(Java NIO2又叫AIO) 主要與NIO的區別主要是作業系統的底層區別.可以做個比喻:比作快遞,NIO就是網購後要自己到官網查下快遞是否已經到了(可能是多次),然後自己去取快遞;AIO就是快遞員送貨上門了(不用關注快遞進度)。
    • AIO方式使用於連線數目多且連線比較長(重操作)的架構,比如相簿伺服器,充分呼叫OS參與併發操作,程式設計比較複雜,JDK7開始支援.

在server.xml中

實現對Tomcat的IO切換

APR是從作業系統級別來解決非同步的IO問題,大幅度的提高效能. (http://apr.apache.org/).

  1. APR(Apache Portable Runtime)是一個高可移植庫,它是Apache HTTP Server 2.x的核心.能更好地和其它本地web技術整合,總體上讓Java更有效率作為一個高效能web伺服器平臺而不是簡單作為後臺容器.
  2. 在產品環境中,特別是直接使用Tomcat做WEB伺服器的時候,應該使用Tomcat,Native來提高其效能.如果不配APR,基本上300個執行緒狠快就會用滿,以後的請求就只好等待.但是配上APR之後,併發的執行緒數量明顯下降,從原來的300可能會馬上下降到只有幾十,新的請求會毫無阻塞的進來.
  3. 在區域網環境測,就算是400個併發,也是一瞬間就處理/傳輸完畢,但是在真實的Internet環境下,頁面處理時間只佔0.1%都不到,絕大部分時間都用來頁面傳輸.如果不用APR,一個執行緒同一時間只能處理一個使用者,勢必會造成阻塞。所以生產環境下用apr是非常必要的.

相關文章