架構
首先,看一下整個架構圖,最全面的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
標籤:其他
下一篇:返回列表
