主頁 > 後端開發 > 一文吃透Tomcat核心知識點

一文吃透Tomcat核心知識點

2023-05-05 07:52:47 後端開發

架構

首先,看一下整個架構圖,最全面的Java面試網站

接下來簡單解釋一下,

Server:服務器,Tomcat 就是一個 Server 服務器,

Service:在服務器中可以有多個 Service,只不過在我們常用的這套 Catalina 容器的Tomcat 中只包含一個 Service,在 Service 中包含連接器和容器,一個完整的 Service 才能完成對請求的接收和處理,

連接器:Coyote 是連接器具體的實作,用于與新來的請求建立連接并決議資料,因為 Tomcat 支持的 IO 模型有 NIO、NIO2、APR,而支持的應用層協議有 HTTP1.1、HTTP2、AJP,所以針對不同的 IO 模型和應用層協議請求,在一個 Service 中可以有多個連接器來適用不同的協議的IO請求,

  EndPoint :Coyote 通信端點,即通信監聽的介面,是具體 Socket 接收和發送處理器,是用來實作 TCP/IP 傳輸協議的,

    Acceptor:用于接收請求的 socket,

    Executor:執行緒池,在接收到請求的 socket 后會從執行緒池中分配一條來執行后面的操作,

  Processor :Coyote 協議處理介面,是用來實作 HTTP 應用層協議的,接收 EndPoint 、容器傳來的 Socket 位元組流,決議成 request 或 response 物件,

  ProtocolHandler:Coyote 協議介面,通過 EndPoint 和 Processor,實作針對具體協議的處理能力,

  Adapter:容器只負責處理資料,對于請求協議不同的資料,容器會無法處理,所以在 ProtocolHandler 處理生成的 request 物件后,還需要將其轉成 Tomcat 定義好的統一格式的 ServletRequest 物件,Adapter 就是用來進行這樣的操作的,

本文已經收錄到Github倉庫,該倉庫包含計算機基礎、Java基礎、多執行緒、JVM、資料庫、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服務、設計模式、架構、校招社招分享等核心知識點,歡迎star~

Github地址

如果訪問不了Github,可以訪問gitee地址,

gitee地址

容器: Tomcat 的核心組件, 用于處理請求并回傳資料,Catalina 是其具體的實作,

  Engine:表示整個 Catalina 的 Servlet 引擎,用來管理多個虛擬站點,一個 Service 最多只能有一個 Engine,但是一個 Engine 可以包含多個 Host,

  Host:表示一個主機地址,或者說一個站點,一個 Host 下有可以配置多個 Context,

  Context:表示一個 web 應用,一個 Web 應用可以包含多個 Wrapper

  Wrapper:表示一個 Servlet,是容器中的最底層組件,

各組件的比例關系

各組件的實作與執行

組件實作

前面提到的各個組件名都是介面或者抽象方法,在實際處理請求時執行的都是其子類或者實作類,

Server、Service、Engine、Host、Context都是介面, 下圖中羅列了這些介面的默認 實作類,

Adapter 的實作是 CoyoteAdapter

對于 Endpoint組件來說,在Tomcat中沒有對應的Endpoint介面, 但是有一個抽象類AbstractEndpoint ,其下有三個實作類: NioEndpoint、Nio2Endpoint、AprEndpoint , 這三個實作類,分別對應于前面講解聯結器 Coyote 時, 提到的聯結器支持的三種IO模型:NIO,NIO2,APR ,tomcat8.5版本中,默認采用的是 NioEndpoint,

ProtocolHandler : Coyote協議介面,通過封裝Endpoint和Processor , 實作針對具體協議的處理功能,Tomcat按照協議和IO提供了6個實作類,

給大家分享一個Github倉庫,上面有大彬整理的300多本經典的計算機書籍PDF,包括C語言、C++、Java、Python、前端、資料庫、作業系統、計算機網路、資料結構和演算法、機器學習、編程人生等,可以star一下,下次找書直接在上面搜索,倉庫持續更新中~

Github地址

AJP協議:

1) AjpNioProtocol :采用NIO的IO模型,

2) AjpNio2Protocol:采用NIO2的IO模型,

3) AjpAprProtocol :采用APR的IO模型,需要依賴于APR庫,

HTTP協議:

1) Http11NioProtocol :采用NIO的IO模型,默認使用的協議(如果服務器沒有安裝APR),

2) Http11Nio2Protocol:采用NIO2的IO模型,

3) Http11AprProtocol :采用APR的IO模型,需要依賴于APR庫,

這些組件均存在初始化、啟動、停止等周期方法,所以 Tomcat 設計了一個 LifeCycle 介面,用于定義這些組件生命周期中需要執行的共同方法,這些組件實作類都實作了這個介面,

啟動流程

1) 啟動tomcat , 需要呼叫 bin/startup.bat (在linux 目錄下 , 需要呼叫 bin/startup.sh) , 在

startup.bat 腳本中, 呼叫了catalina.bat,

2) 在catalina.bat 腳本檔案中,呼叫了BootStrap 中的main方法,

3)在BootStrap 的main 方法中呼叫了 init 方法 , 來創建Catalina 及 初始化類加載器,

4)在BootStrap 的main 方法中呼叫了 load 方法 , 在其中又呼叫了Catalina的load方法,

5)在Catalina 的load 方法中 , 需要進行一些初始化的作業, 并需要構造Digester 物件, 用于決議 XML,

6) 然后在呼叫后續組件的初始化操作 ,,,

加載Tomcat的組態檔,初始化容器組件 ,監聽對應的埠號, 準備接受客戶端請求 ,

簡而言之就是進行各組件逐級執行 init() 和 start() 方法,

執行流程

當一個請求進入 Tomcat 時,執行情況如下( 因為 Tomcat 只有一個 Service,所以下面就將 Service 和 Engine 寫在同一個框中):

定位主要通過 Mapper 組件來實作,其本質就是一個 K、V鍵值對,在決議時首先會將請求網址進行決議,將其中的 Host 部分在 Mapper 類中的 hosts屬性(MappedHost陣列,保存所有的 Host 資訊)中進行查找,找到后再決議 Context 部分,在該 MapperHost 中又有 contextList 屬性(保存所有的 context 資訊),然后再向下找,最終得到對應的 Servlet,執行,

除此之外,為了增強各組件之間的拓展性,Tomcat 中定義了 Pipeline 和 Valve 兩個介面,Pipeline 用于構建責任鏈, 后者代表責任鏈上的每個處理器,Pipeline 中維護了一個基礎的 Valve,它始終位于Pipeline的末端(最后執行),封裝了具體的請求處理和輸出回應的程序,當然,我們也可以呼叫addValve()方法, 為Pipeline 添加其他的Valve,后添加的Valve 位于基礎的Valve之前,并按照添加順序執行,Pipiline通過獲得首個Valve來啟動整合鏈條的執行 ,

所以最終的執行如下:

步驟如下:

1)Connector組件Endpoint中的Acceptor監聽客戶端套接字連接并接收Socket,

2)將連接交給執行緒池Executor處理,開始執行請求回應任務,

3)Processor組件讀取訊息報文,決議請求行、請求體、請求頭,封裝成Request物件,

4)Mapper組件根據請求行的URL值和請求頭的Host值匹配由哪個Host容器、Context容器、Wrapper容器處理請求,

5)CoyoteAdaptor組件負責將Connector組件和Engine容器關聯起來,把生成的Request物件和回應物件Response傳遞到Engine容器中,呼叫 Pipeline,

6)Engine容器的管道開始處理,管道中包含若干個Valve、每個Valve負責部分處理邏輯,執行完Valve后會執行基礎的 Valve--StandardEngineValve,負責呼叫Host容器的Pipeline,

7)Host容器的管道開始處理,流程類似,最后執行 Context容器的Pipeline,

8)Context容器的管道開始處理,流程類似,最后執行 Wrapper容器的Pipeline,

9)Wrapper容器的管道開始處理,流程類似,最后執行 Wrapper容器對應的Servlet物件的處理方法,

組態檔

首先看一下 tomcat 的目錄結構

核心組態檔在 conf 目錄下

Server.xml(重點)

其中最重要的就是 server.xml,主要配置了 tomcat 容器的所有配置,下面來看一下其中有哪些配置,

Server

是 server.xml 的根元素,用于創建一個 Server 實體,默認的實作是

<Server port="8005" shutdown="SHUTDOWN"> 
... 
</Server>

port:Tomcat監聽的關閉服務器的埠

shutdown:關閉服務器的指令字串,

Server 內嵌的子元素為 Listener、GlobalNamingResources、Service,

配置的5個Listener 的含義:

<!-- 用于以日志形式輸出服務器 、作業系統、JVM的版本資訊 --> 
<Listener className="org.apache.catalina.startup.VersionLoggerListener" /> 

<!-- 用于加載(服務器啟動) 和 銷毀 (服務器停止) APR, 如果找不到APR庫, 則會輸出日志, 并 不影響Tomcat啟動 --> 
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /> 

<!-- 用于避免JRE記憶體泄漏問題 -->
 <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />

<!-- 用戶加載(服務器啟動) 和 銷毀(服務器停止) 全域命名服務 --> 
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /> 

<!-- 用于在Context停止時重建Executor 池中的執行緒, 以避免ThreadLocal 相關的記憶體泄漏 -->
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

GlobalNamingResources 中定義了全域命名服務

Service

用于創建 Service 實體,內嵌的元素為:Listener、Executor、Connector、Engine,其中 : Listener 用于為Service添加生命周期監聽器, Executor 用于配置Service 共享執行緒池,Connector 用于配置Service 包含的聯結器, Engine 用于配置Service中聯結器對應的Servlet 容器引擎,默認 Service 就叫 Catalina,

Executor

默認情況,Service 并未配置共享執行緒池,各個連接器使用的都是各自的執行緒池(默認size為10),如果我們想添加一個執行緒池,可以在 Service 標簽中添加如下配置

<Executor name="tomcatThreadPool" 
    namePrefix="catalina-exec-" 
    maxThreads="200" 
    minSpareThreads="100" 
    maxIdleTime="60000" 
    maxQueueSize="Integer.MAX_VALUE"                 
   prestartminSpareThreads="false" threadPriority="5" 
  className="org.apache.catalina.core.StandardThreadExecutor"/>    

相關屬性說明:

Connector

用于創建連接器實體,默認情況下,server.xml 配置了兩個連接器,一個支持 HTTP 協議,一個支持 AJP 協議,

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

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

1) port: 埠號,Connector 用于創建服務端Socket 并進行監聽, 以等待客戶端請求鏈接,如果該屬性設定為0,Tomcat將會隨機選擇一個可用的埠號給當前Connector 使用,

2) protocol : 當前Connector 支持的訪問協議, 默認為 HTTP/1.1 , 并采用自動切換機制選擇一個基于 JAVA NIO 的聯結器或者基于本地APR的聯結器(根據本地是否含有Tomcat的本地庫判定),如果不希望采用上述自動切換的機制, 而是明確指定協議, 可以使用以下值,

Http協議:

  org.apache.coyote.http11.Http11NioProtocol , 非阻塞式 Java NIO 聯結器

  org.apache.coyote.http11.Http11Nio2Protocol , 非阻塞式 JAVA NIO2 聯結器

  org.apache.coyote.http11.Http11AprProtocol , APR 聯結器

AJP協議:

  org.apache.coyote.ajp.AjpNioProtocol , 非阻塞式 Java NIO 聯結器

  org.apache.coyote.ajp.AjpNio2Protocol ,非阻塞式 JAVA NIO2 聯結器

  org.apache.coyote.ajp.AjpAprProtocol , APR 聯結器

3) connectionTimeOut : Connector 接收鏈接后的等待超時時間, 單位為 毫秒, -1 表示不超時,

4) redirectPort:當前Connector 不支持SSL請求, 接收到了一個請求, 并且也符合securityconstraint 約束, 需要SSL傳輸,Catalina自動將請求重定向到指定的埠,

5) executor : 指定共享執行緒池的名稱, 也可以通過maxThreads、minSpareThreads 等屬性配置內部執行緒池,

6) URIEncoding : 用于指定編碼URI的字符編碼, Tomcat8.x版本默認的編碼為 UTF-8 , Tomcat7.x版本默認為ISO-8859-1,

Engine

Engine 作為Servlet 引擎的頂級元素,內部可以嵌入: Cluster、Listener、Realm、Valve和 Host,

<Engine name="Catalina" defaultHost="localhost"> 
...
</Engine>

1) name: 用于指定Engine 的名稱, 默認為Catalina ,該名稱會影響一部分Tomcat的存盤路徑(如臨時檔案),

2) defaultHost : 默認使用的虛擬主機名稱, 當客戶端請求指向的主機無效時, 將交由默認的虛擬主機處理, 默認為localhost, 在 ip 地址決議時首先根據defaultHost 設定的 Host從 Host 串列中找對用的 Host 跳轉,如果沒有再從 Host 串列中查找對應的,如果串列中沒有,那么就會訪問不到,

除此之外,在默認的組態檔中還包含 Realn 標簽,如下:

<Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available for use by the Realm.  -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
</Realm>

<GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
    <Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
 </GlobalNamingResources>

<Realm> 標簽是用來配置用戶權限的,

首先說一下 tomcat 的權限管理,因為在 tomcat 中可以配置多個 web 專案,而 tomcat 為這些專案的管理創建了管理頁面,也就是默認 webapps 下 host-manager 與 manager 檔案夾的專案頁面,為了保證安全性,訪問這兩個專案需要設定權限,但是如果對每個新用戶都單獨的設定權限比較繁瑣麻煩,所以在 tomcat 中定義了幾種不同的權限,我們可以自己配置 "角色"(可以看作是特定權限的集合) 和 "用戶"(設定登錄名、密碼,與角色相關聯),然后就可以通過自定義的 "用戶" 去訪問管理頁面,"角色" 和 "用戶" 的配置默認可以在 tomcat-users.xml 中配置,當 tomcat 啟動后,就會通過 conf 目錄下的 server.xml 中的 Realm 標簽來檢查權限,

<Realm> 支持多種 Realm 管理方式:

1 JDBCRealm 用戶授權資訊存盤于某個關系型資料庫中,通過JDBC驅動獲取資訊驗證

2 DataSourceRealm 用戶授權資訊存盤于關于型資料中,通過JNDI配置JDBC資料源的方式獲取資訊驗證

3 JNDIRealm 用戶授權資訊存盤在基于LDAP的目錄服務的服務器中,通過JNDI驅動獲取并驗證

4 UserDatabaseRealm 默認的配置方式,資訊存盤于XML檔案中 conf/tomcat-users.xml

5 MemoryRealm 用戶資訊存盤于記憶體的集合中,物件集合的資料來源于xml檔案 conf/tomcat-users.xml

6 JAASRealm 通過JAAS框架訪問授權資訊

上面代碼塊中可以看出Realm就是使用默認的 UserDatabaseRealm 方式配置,而它的 resourceName 就對應之前 <GlobalNamingResources> 中配置的 conf 目錄下的 tomcat-users.xml 檔案,

如果在Engine下配置Realm, 那么此配置將在當前Engine下的所有Host中共享, 同樣,如果在Host中配置Realm , 則在當前Host下的所有Context中共享,底層會覆寫掉上層對同一個資源的配置,

Host

用于配置一個虛擬主機, 它支持以下嵌入元素:Alias、Cluster、Listener、Valve、Realm、Context,一個 Engine 標簽下可以配置多個 Host,

<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
...
</Host>

屬性說明:

1) name: 當前Host通用的網路名稱, 必須與DNS服務器上的注冊資訊一致, Engine中包含的Host必須存在一個名稱與Engine的defaultHost設定一致,

2) appBase: 當前Host的應用基礎目錄, 當前Host上部署的Web應用均在該目錄下(可以是絕對目錄,相對路徑),默認為webapps,

3) unpackWARs: 設定為true, Host在啟動時會將appBase目錄下war包解壓為目錄,設定為 false, Host將直接從war檔案啟動,

4) autoDeploy: 控制tomcat是否在運行時定期檢測并自動部署新增或變更的web應用,

Context

用于配置一個 Web 應用,

<Context docBase="myApp" path="/myApp"> 
.... 
</Context>

屬性描述:

1) docBase:Web應用目錄或者War包的部署路徑,可以是絕對路徑,也可以是相對于 Host appBase的相對路徑,

2) path:Web應用的Context 路徑,如果我們Host名為localhost, 則該web應用訪問的根路徑為:http://localhost:8080/myApp,它支持的內嵌元素為:CookieProcessor, Loader, Manager,Realm,Resources,WatchedResource,JarScanner,Valve,

tomcat-user.xml(權限管理)

上面的 realm 標簽說到這個檔案是配合 realm 標簽來設定用戶權限的,所以就來看一下具體是如何設定的,

首先看一下默認配置

<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<tomcat-users xmlns="http://tomcat.apache.org/xml"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
              version="1.0">
<!--
  NOTE:  By default, no user is included in the "manager-gui" role required
  to operate the "/manager/html" web application.  If you wish to use this app,
  you must define such a user - the username and password are arbitrary. It is
  strongly recommended that you do NOT use one of the users in the commented out
  section below since they are intended for use with the examples web
  application.
-->
<!--
  NOTE:  The sample user and role entries below are intended for use with the
  examples web application. They are wrapped in a comment and thus are ignored
  when reading this file. If you wish to configure these users for use with the
  examples web application, do not forget to remove the <!.. ..> that surrounds
  them. You will also need to set the passwords to something appropriate.
-->
<!--
  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <user username="tomcat" password="<must-be-changed>" roles="tomcat"/>
  <user username="both" password="<must-be-changed>" roles="tomcat,role1"/>
  <user username="role1" password="<must-be-changed>" roles="role1"/>
-->
</tomcat-users>

<tomcat-users> 標簽內有兩個子標簽,<role><user>,role 是用來設定 "角色",而 user 是用來設定登陸 "用戶" 的,管理頁面是 webapps 下的 host-manager 與 manager 目錄,分別來管理所有主機以及所有的 web專案,如果我們只將注釋的部分打開,還是不能訪問管理頁面,因為 tomcat 設定了特定的權限名,首先是 manager:

manager-gui 允許訪問html介面(即URL路徑為/manager/html/*)

manager-script 允許訪問純文本介面(即URL路徑為/manager/text/*)

manager-jmx 允許訪問JMX代理介面(即URL路徑為/manager/jmxproxy/*)

manager-status 允許訪問Tomcat只讀狀態頁面(即URL路徑為/manager/status/*)

對于 host-manager:

admin-gui 允許訪問html介面(即URL路徑為/host-manager/html/*)

admin-script 允許訪問純文本介面(即URL路徑為/host-manager/text/*)

admin-jmx 允許訪問JMX代理介面(即URL路徑為/host-manager/jmxproxy/*)

admin-status 允許訪問Tomcat只讀狀態頁面(即URL路徑為/host-manager/status/*)

如果我們想讓某個角色直接能訪問這兩個專案頁面,可以將 roles 配置成下面的設定,然后就可以訪問 manager 和 host-manager 頁面了,

<user username="tomcat" password="tomcat" roles="admin-script,admin-gui,manager-gui,manager-script"/>

Web.xml(不常用)

web.xml 目前已經很少再用了,所以這部分內容簡單了解下即可,web.xml 檔案分為 tomcat 安裝目錄的 conf 下的以及各個專案的 WEB-INF 目錄下的,conf 下的是全域配置,所有 web 專案都會受到影響,而 WEB-INF 下的只會作用于當前專案,但是如果與 conf 下的 web.xml 配置沖突,那么就會覆寫掉 conf的,

ServletContext 初始化全域引數

K、V鍵值對,可以在應用程式中使用 javax.servlet.ServletContext.getInitParameter()方法獲取引數值,

<context-param> 
  <param-name>contextConfigLocation</param-name> 
  <param-value>classpath:applicationContext-*.xml</param-value> 
  <description>Spring Config File Location</description> <
</context-param>  

會話設定

用于配置Web應用會話,包括 超時時間、Cookie配置以及會話追蹤模式,它將覆寫server.xml 和 context.xml 中的配置,

<session-config>
  <session-timeout>30</session-timeout> 
  <cookie-config> 
    <name>JESSIONID</name> 
    <domain>www.itcast.cn</domain> 
    <path>/</path> 
    <comment>Session Cookie</comment> 
    <http-only>true</http-only> 
    <secure>false</secure> 
    <max-age>3600</max-age> 
  </cookie-config> 
  <tracking-mode>COOKIE</tracking-mode> 
</session-config>

1) session-timeout : 會話超時時間,單位:分鐘

2) cookie-config: 用于配置會話追蹤Cookie

  name:Cookie的名稱

  domain:Cookie的域名

  path:Cookie的路徑

  comment:注釋

  http-only:cookie只能通過HTTP方式進行訪問,JS無法讀取或修改,此項可以增加網站訪問的安全性,

  secure:此cookie只能通過HTTPS連接傳遞到服務器,而HTTP 連接則不會傳遞該資訊,注意是從瀏覽器傳遞到服務器,服務器端的Cookie物件不受此項影響,

  max-age:以秒為單位表示cookie的生存期,默認為-1表示是會話Cookie,瀏覽器關閉時就會消失,

3) tracking-mode :用于配置會話追蹤模式,Servlet3.0版本中支持的追蹤模式:COOKIE、URL、SSL

  A. COOKIE : 通過HTTP Cookie 追蹤會話是最常用的會話追蹤機制, 而且Servlet規范也要求所有的Servlet規范都需要支持Cookie追蹤,

  B. URL : URL重寫是最基本的會話追蹤機制,當客戶端不支持Cookie時,可以采用URL重寫的方式,當采用URL追蹤模式時,請求路徑需要包含會話標識資訊,Servlet容器會根據路徑中的會話標識設定請求的會話資訊,如: http://www.myserver.com/user/index.html;jessionid=1234567890,

  C. SSL : 對于SSL請求, 通過SSL會話標識確定請求會話標識,

Servlet 配置

Servlet 的配置主要是兩部分, servlet 和 servlet-mapping :

<servlet> 
    <servlet-name>myServlet</servlet-name> 
    <servlet-class>cn.itcast.web.MyServlet</servlet-class> 
    <init-param> 
        <param-name>fileName</param-name> 
        <param-value>init.conf</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
    <enabled>true</enabled> 
</servlet> 
<servlet-mapping> 
    <servlet-name>myServlet</servlet-name> 
    <url-pattern>*.do</url-pattern> 
    <url-pattern>/myservet/*</url-pattern> 
</servlet-mapping>        

1)servlet-name : 指定servlet的名稱, 該屬性在web.xml中唯一,

2)servlet-class : 用于指定servlet類名

3)init-param: 用于指定servlet的初始化引數, 在應用中可以通過HttpServlet.getInitParameter 獲取,

4) load-on-startup: 用于控制在Web應用啟動時,Servlet的加載順序, 值小于0,web應用啟動時,不加載該servlet, 第一次訪問時加載,

5) enabled: true , false , 若為false ,表示Servlet不處理任何請求,

6) url-pattern: 用于指定URL運算式,一個 servlet-mapping可以同時配置多個 url-pattern,

Servlet 中檔案上傳配置:

<servlet> 
    <servlet-name>uploadServlet</servlet-name> 
    <servlet-class>cn.itcast.web.UploadServlet</servlet-class>                     
    <multipart-config> 
        <location>C://path</location> 
        <max-file-size>10485760</max-file-size> 
        <max-request-size>10485760</max-request-size> 
        <file-size-threshold>0</file-size-threshold> 
    </multipart-config> 
</servlet>

1) location:存放生成的檔案地址,

2) max-file-size:允許上傳的檔案最大值, 默認值為-1, 表示沒有限制,

3) max-request-size:針對該 multi/form-data 請求的最大數量,默認值為-1, 表示無限制,

4) file-size-threshold:當數量量大于該值時, 內容會被寫入檔案,

Listener 配置

Listener用于監聽servlet中的事件,例如context、request、session物件的創建、修改、洗掉,并觸發回應事件,Listener是觀察者模式的實作,在servlet中主要用于對context、request、session物件的生命周期進行監控,在servlet2.5規范中共定義了8中Listener,在啟動時,ServletContextListener的執行順序與web.xml 中的配置順序一致, 停止時執行順序相反,

<listener> 
    <listener- class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener>

Filter 配置

fifilter 用于配置web應用過濾器, 用來過濾資源請求及回應, 經常用于認證、日志、加密、資料轉換等操作, 配置如下:

<filter> 
    <filter-name>myFilter</filter-name> 
    <filter-class>cn.itcast.web.MyFilter</filter-class> 
    <async-supported>true</async-supported> 
    <init-param> 
        <param-name>language</param-name> 
        <param-value>CN</param-value> 
    </init-param> 
</filter> 
<filter-mapping> 
    <filter-name>myFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

1) filter-name: 用于指定過濾器名稱,在web.xml中,過濾器名稱必須唯一,

2) filter-class : 過濾器的全限定類名, 該類必須實作Filter介面,

3) async-supported: 該過濾器是否支持異步

4) init-param :用于配置Filter的初始化引數, 可以配置多個, 可以通過 FilterConfig.getInitParameter獲取

5) url-pattern: 指定該過濾器需要攔截的URL,

歡迎頁面配置

<welcome-file-list> 
    <welcome-file>index.html</welcome-file> 
    <welcome-file>index.htm</welcome-file> 
    <welcome-file>index.jsp</welcome-file> 
</welcome-file-list>

嘗試請求的順序,從上到下,

錯誤頁面配置

error-page 用于配置Web應用訪問例外時定向到的頁面,支持HTTP回應碼和例外類兩種形式,

<error-page> 
    <error-code>404</error-code> 
    <location>/404.html</location> 
</error-page> 
<error-page> 
    <error-code>500</error-code> 
    <location>/500.html</location> 
</error-page> 
<error-page> 
    <exception-type>java.lang.Exception</exception-type>                 
    <location>/error.jsp</location> 
</error-page>

安全與優化

安全

配置安全

1) 洗掉webapps目錄下的所有檔案,禁用tomcat管理界面;

2) 注釋或洗掉tomcat-users.xml檔案內的所有用戶權限;

3) 更改關閉tomcat指令或禁用;tomcat的server.xml中定義了可以直接關閉 Tomcat 實體的管理埠(默認8005),可以通過 telnet連接上該埠之后,輸入 SHUTDOWN (此為默認關閉指令)即可關閉 Tomcat 實體(注意,此時雖然實體關閉了,但是行程還是存在的),由于默認關閉Tomcat 的埠和指令都很簡單,默認埠為8005,指令為SHUTDOWN ,

方案一:更改埠號

<Server port="8456" shutdown="itcast_shut">

方案二:禁用8005 埠,設為-1,

<Server port="-1" shutdown="SHUTDOWN">

4) 定義錯誤頁面,如果不定義在發生例外后會顯示代碼類名以及位置,會泄漏目錄結構,在webapps/ROOT目錄下定義錯誤頁面 404.html,500.html;然后在tomcat/conf/web.xml中進行配置 , 配置錯誤頁面:

<error-page> 
    <error-code>404</error-code> 
    <location>/404.html</location> 
</error-page> 
<error-page> 
    <error-code>500</error-code> 
    <location>/500.html</location> 
</error-page>

應用安全

應用安全是指在某些隱私頁面應該是登陸用戶或者管理員用戶才能訪問的,而對于這些頁面在權限不夠時應該被攔截,可以使用攔截器或者一些安全框架,比如 SpringSecurity、Shiro 等,

傳輸安全

傳統的網路應用協議 HTTP 并不安全,此時可以使用 HTTPS 來代替,它在 HTTP 的基礎上加入 SSL/TLS 來進行資料加密,保護交換資料不被泄漏、竊取,

HTTPS和HTTP的區別主要為以下四點:

1) HTTPS協議需要到證書頒發機構CA申請SSL證書, 然后與域名進行系結,HTTP不用申請證書;

2) HTTP是超文本傳輸協議,屬于應用層資訊傳輸,HTTPS 則是具有SSL加密傳安全性傳輸協議,對資料的傳輸進行加密,相當于HTTP的升級版;

3) HTTP和HTTPS使用的是完全不同的連接方式,用的埠也不一樣,前者是8080,后者是8443,

4) HTTP的連接很簡單,是無狀態的;HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網路協議,比HTTP協議安全,

HTTPS協議優勢:

1) 提高網站排名,有利于SEO,谷歌已經公開宣告兩個網站在搜索結果方面相同,如果一個網站啟用了SSL,它可能會獲得略高于沒有SSL網站的等級,而且百度也表明對安裝了SSL的網站表示友好,因此,網站上的內容中啟用SSL都有明顯的SEO優勢,

2) 隱私資訊加密,防止流量劫持,特別是涉及到隱私資訊的網站,互聯網大型的資料泄露的事件頻發發生,網站進行資訊加密勢在必行,北京市昌平區建材城西路金燕龍辦公樓一層 電話:400-618-9090

3) 瀏覽器受信任, 自從各大主流瀏覽器大力支持HTTPS協議之后,訪問HTTP的網站都會提示“不安全”的警告資訊,

性能優化

性能測驗

ApacheBench(ab)是一款ApacheServer基準的測驗工具,用戶測驗Apache Server的服務能力(每秒處理請求數),它不僅可以用戶Apache的測驗,還可以用于測驗Tomcat、Nginx、lighthttp、IIS等服務器,

安裝:yum install httpd-tools

執行:b -n 1000 -c 100 -p data.json -T application/json http://localhost:9000/course/search.do?page=1&pageSize=10

引數說明:

如果此請求需要攜帶 Post 資料,那么需要自定義一個檔案來保存這個資料,一般使用 json 格式來保存傳輸

執行結果部分:

引數說明:

重點需要關注的引數:

JVM 優化

因為 Tomcat 是一臺 Java 服務器,所以它的優化就可以歸結到 JVM 的優化上,而 Tomcat 在JVM 上的優化可以分為垃圾回收器的選擇以及一些引數配置,關于垃圾回收器和相關引數配置這里就不過多闡述了,這里只介紹下如何在 Tomcat 啟動時攜帶我們想要的配置,

windows 下: 修改bin/catalina.bat 檔案,在第一行添加 : set JAVA_OPTS=-server -Dfile.encoding=UTF-8 具體配置

linux 下:修改 bin/catalina.sh 檔案,在第一行添加: JAVA_OPTS=" -server 具體配置"

Tomcat 配置優化

連接器的配置是決定 Tomcat 性能的關鍵,在一般情況下使用默認的就可以了,但是在程式比較吃力時,就需要手動配置它來提高效率,完整的配置如下:

<Connector port="8080" 
    protocol="HTTP/1.1" 
    executor="tomcatThreadPool" 
    maxThreads="1000" 
    minSpareThreads="100" 
    acceptCount="1000" 
    maxConnections="1000" 
    connectionTimeout="20000" 
    compression="on" 
    compressionMinSize="2048" 
    disableUploadTimeout="true" 
    redirectPort="8443" 
    URIEncoding="UTF-8" />

相關引數:

maxThreads:表示Tomcat可創建的最大的執行緒數;

minSpareThreads:最小空閑執行緒數,Tomcat初始化時創建的執行緒數,該值應該少于maxThreads,預設值為4;

acceptCount:指定當所有可以使用的處理請求的執行緒數都被使用時,可以放到處理佇列中的請求數,超過這個數的請求將不予處理,默認為10個;

maxConnections:服務器在任何給定時間接受和處理的最大連接數,

connectionTimeout:網路連接超時時間,單位為毫秒,如果設定為“0”則表示永不超時,不建議這樣設定;

compression:默認為 off,開啟是連接器在試圖節省服務器的帶寬使用 HTTP/1.1 GZIP 壓縮,關倍訓自動在壓縮和傳輸之間進行權衡,

compressionMinSize:在 compression 開啟時,可以通過這個來配置進行壓縮的最小資料量,默認為 "2048",

disableUploadTimeout:上傳檔案時是否使用超時機制,默認開啟,由 ConnectionTimeout 決定,如果為 false,那么只會在設定的 connectionUploadTimeout 設定的時間后才會斷開,

redirectPort:如果此連接器支持非 SSL 請求,并且收到匹配需要 SSL 傳輸的請求,Catalina 將自動將請求重定向到此處指定的埠號,

其他引數可參考博客 tomcat(4)連接器 ,

如果只是想簡單配置,可以只配置 maxConnections、maxThreads、acceptCount,

Tomcat 附加功能 WebSocket

我們在瀏覽網頁時,一般使用的是HTTP 協議或者 HTTPS 協議,這種方式是一種 "請求---回應" 模式,也就是只支持從客戶端發送請求,服務器收到后進行處理,然后回傳一個回應,但是不能主動發送資料給客戶端,這樣某些場景下的實作就比較困難,甚至無法實作,比如聊天室實時聊天,可能有人會說直接將在 servlet 中處理向要發送訊息的客戶端發送不就行了,但是因為是 "請求-回應" 模式,當其他客戶端與服務器一段時間沒有通信,連接就會斷開,服務器也就無法轉發訊息了,而 WebSocket 則是基于 HTTP 的一種長連接協議,并且是雙向通道,可以實作服務器主動向客戶端發送訊息,

WebSocket 請求程序

WebSocket 請求和普通的HTTP請求有幾點不同:

\1. GET請求的地址不是類似 http://,而是以 ws:// 開頭的地址;

\2. 請求頭 Connection: Upgrade 和 請求頭 Upgrade: websocket 表示這個連接將要被轉換為WebSocket 連接;

\3. Sec-WebSocket-Key 是用于標識這個連接, 是一個BASE64編碼的密文, 要求服務端回應一個對應加密的Sec-WebSocket-Accept頭資訊作為應答;

\4. Sec-WebSocket-Version 指定了WebSocket的協議版本;

\5. HTTP101 狀態碼表明服務端已經識別并切換為WebSocket協議 , Sec-WebSocket-Accept是服務端與客戶端一致的秘鑰計算出來的資訊,

Tomcat的7.0.5 版本開始支持WebSocket,并且實作了Java WebSocket規范(JSR356), 而在7.0.5版本之前(7.0.2之后)則采用自定義API, 即WebSocketServlet實作,Java WebSocket應用由一系列的WebSocketEndpoint組成,Endpoint 是一個java物件,代表WebSocket鏈接的一端,對于服務端,我們可以視為處理具體WebSocket訊息的介面, 就像Servlet之與http請求一樣,我們可以通過兩種方式定義Endpoint:

1). 第一種是編程式, 即繼承類 javax.websocket.Endpoint并實作其方法,

2). 第二種是注解式, 即定義一個POJO, 并添加 @ServerEndpoint相關注解,Endpoint實體在WebSocket握手時創建,并在客戶端與服務端鏈接程序中有效,最后在鏈接關閉時結束,在Endpoint介面中明確定義了與其生命周期相關的方法, 規范實作者確保生命周期的各個階段呼叫實體的相關方法,生命周期方法如下:

通過為Session添加MessageHandler訊息處理器來接收訊息,當采用注解方式定義Endpoint時,我們還可以通過 @OnMessage 注解指定接收訊息的方法,發送訊息則由RemoteEndpoint 完成, 其實體由Session維護, 根據使用情況, 我們可以通過Session.getBasicRemote獲取同步訊息發送的實體 , 然后呼叫其sendXxx()方法就可以發送訊息, 可以通過Session.getAsyncRemote 獲取異步訊息發送實體,

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/551600.html

標籤:其他

上一篇:SpringBoot匯出Word檔案的三種方式

下一篇:返回列表

標籤雲
其他(158393) Python(38117) JavaScript(25399) Java(18012) C(15221) 區塊鏈(8261) C#(7972) AI(7469) 爪哇(7425) MySQL(7157) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5871) 数组(5741) R(5409) Linux(5334) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4565) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2432) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1964) Web開發(1951) HtmlCss(1931) python-3.x(1918) 弹簧靴(1913) C++(1912) xml(1889) PostgreSQL(1874) .NETCore(1857) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • 一文吃透Tomcat核心知識點

    架構 首先,看一下整個架構圖。最全面的Java面試網站 接下來簡單解釋一下。 Server:服務器。Tomcat 就是一個 Server 服務器。 Service:在服務器中可以有多個 Service,只不過在我們常用的這套 Catalina 容器的Tomcat 中只包含一個 Service,在 S ......

    uj5u.com 2023-05-05 07:52:47 more
  • SpringBoot匯出Word檔案的三種方式

    SpringBoot匯出Word檔案的三種方式 一、匯出方案 1、直接在Java代碼里創建Word檔案,設定格式樣式等,然后匯出。(略) 需要的見:https://blog.csdn.net/qq_42682745/article/details/120867432 2、富文本轉換后的HTML下載為 ......

    uj5u.com 2023-05-05 07:52:09 more
  • golang推薦的命名規范

    二 golang推薦的命名規范 很少見人總結一些命名規范,也可能是筆者孤陋寡聞, 作為一個兩年的golang 開發者, 我根據很多知名的專案,如 moby, kubernetess 等總結了一些常見的命名規范。 命名規范可以使得代碼更容易與閱讀, 更少的出現錯誤。 檔案命名規范 由于檔案跟包無任何關 ......

    uj5u.com 2023-05-05 07:51:51 more
  • golang基礎知識

    一 golang基礎知識 Go(又稱 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 開發的一種計算機編程語言語言。 設計初衷 Go語言是谷歌推出的一種的編程語言,可以在不損失應用程式性能的情況下降低代碼的復雜性。谷歌首席軟體工程 ......

    uj5u.com 2023-05-05 07:51:41 more
  • 工匠回憶(二)

    接上文 4、條件分支控制流 避免分支嵌套,例外放在代碼片段最前面 4.1、歸約函式 4.2、條件運算式的封裝避免過長而導致可讀性下降 4.3、德摩根定律 4.4、and、or優先級 4.5、or短路效應 4.6、消失的分支 4.6.1、二分查找演算法 4.6.2、字典演算法 5、例外錯誤處理 無需多言 ......

    uj5u.com 2023-05-05 07:51:35 more
  • python 匿名函式(lambda函式)

    Python中的匿名函式是指沒有命名識別符號的函式,通常被稱為lambda函式。與普通函式不同,它們是一種更加簡潔的方式來撰寫小型臨時函式。在Python中,匿名函式使用關鍵字lambda來定義,其語法如下: lambda arguments: expression 其中,arguments表示函式參 ......

    uj5u.com 2023-05-05 07:51:31 more
  • 刺激!ChatGPT給我虛構了一本書?

    ChatGPT很強大,可以幫我們處理很多問題,但這些問題的答案的正確性您是否有考證過呢? 昨晚,DD就收到了一個有趣的反饋: 提問:有什么關于資料權限設計的資料推薦嗎? ChatGPT居然介紹了一本根本不存在的書《資料權限設計與實作》,作者居然還是我... 那么你在使用ChatGPT的時候,有碰到過 ......

    uj5u.com 2023-05-05 07:46:16 more
  • Django筆記三十五之admin后臺界面介紹

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記三十五之admin后臺界面介紹 這一篇介紹一下 Django 的后臺界面使用。 Django 自帶了一套后臺管理界面,可用于我們直接操作資料庫資料,本篇筆記目錄如下: 創建后臺賬號以及登錄操作 注冊后臺顯示的資料表 串列欄位的顯示操作 字 ......

    uj5u.com 2023-05-05 07:33:50 more
  • 【pandas基礎】--資料讀取

    資料讀取是第一步,只有成功加載資料之后,后續的操作才有可能。 pandas可以讀取和匯入各種資料格式的資料,如CSV,Excel,JSON,SQL,HTML等,不需要手動撰寫復雜的讀取代碼。 1. 各類資料源 pandas提供了匯入各類常用檔案格式資料的介面,這里介紹3種最常用的加載資料的介面。 1 ......

    uj5u.com 2023-05-05 07:33:38 more
  • 工匠回憶(二)

    接上文 4、條件分支控制流 避免分支嵌套,例外放在代碼片段最前面 4.1、歸約函式 4.2、條件運算式的封裝避免過長而導致可讀性下降 4.3、德摩根定律 4.4、and、or優先級 4.5、or短路效應 4.6、消失的分支 4.6.1、二分查找演算法 4.6.2、字典演算法 5、例外錯誤處理 無需多言 ......

    uj5u.com 2023-05-05 07:33:34 more