学习Tomcat这一篇就够了
目錄
- 第一章 Tomcat概述
- 1.1、Tomcat概述
- 1.2、Tomcat歷史
- 1.3、Tomcat官網
- 第二章 Tomcat單實例安裝
- 2.1、環境準備
- 2.2、Tomcat下載
- 2.3、Tomcat解壓
- 2.4、Tomcat安裝
- 2.5、Tomcat啟動
- 2.6、Tomcat關閉
- 第三章 Tomcat配置文件詳解
- 3.1、server.xml 詳解
- 3.1.1、Server
- 3.1.2、Listener
- 3.1.3、GlobalNamingResources
- 3.1.4、Service
- 3.1.5、Executor
- 3.1.6、Connector
- 3.1.7、Engine
- 3.1.8、Host
- 3.1.9、Context
- 3.2、tomcat-users.xml 詳解
- 3.2.1、host-manager應用配置
- 3.2.2、manager應用配置
- 3.3、web.xml 詳解
- 3.3.1、ServletContext初始化參數
- 3.3.2、會話配置
- 3.3.3、Servlet配置
- 3.3.4、Listener配置
- 3.3.5、Filter配置
- 3.3.6、歡迎頁面配置
- 3.3.7、錯誤頁面配置
- 第四章 Tomcat高可用集群
- 4.1、環境準備
- 4.2、集群概述
- 4.3、集群架構
- 4.4、安裝第一臺tomcat服務器
- 4.5、安裝第二臺tomcat服務器
- 4.6、安裝Nginx反向代理服務器
- 4.7、訪問測試
- 4.8、如何保證主nginx高可用
- 4.9、如何解決session共享問題
- 第五章 Tomcat安全問題
- 5.1、配置安全
- 5.2、應用安全
- 5.3、傳輸安全
- 第六章 Tomcat原理分析
- 6.1、Http工作原理
- 6.2、Tomcat整體架構
- 6.3、Coyote連接器架構
- 6.4、Catalina容器架構
- 6.5、Jasper處理流程
- 6.6、JSP編譯過程
- 6.7、Tomcat啟動流程
- 6.8、Tomcat請求處理流程
第一章 Tomcat概述
1.1、Tomcat概述
Tomcat是Apache 軟件基金會(Apache Software Foundation)的Jakarta 項目中的一個核心項目,由Apache、Sun 和其他一些公司及個人共同開發而成。由于有了Sun 的參與和支持,最新的Servlet 和JSP 規范總是能在Tomcat 中得到體現,Tomcat 5支持最新的Servlet 2.4 和JSP 2.0 規范。因為Tomcat 技術先進、性能穩定,而且免費,因而深受Java 愛好者的喜愛并得到了部分軟件開發商的認可,成為目前比較流行的Web 應用服務器。
Tomcat 服務器是一個免費的開放源代碼的Web 應用服務器,屬于輕量級應用服務器,在中小型系統和并發訪問用戶不是很多的場合下被普遍使用,是開發和調試JSP 程序的首選。對于一個初學者來說,可以這樣認為,當在一臺機器上配置好Apache 服務器,可利用它響應HTML(標準通用標記語言下的一個應用)頁面的訪問請求。實際上Tomcat是Apache 服務器的擴展,但運行時它是獨立運行的,所以當你運行tomcat 時,它實際上作為一個與Apache 獨立的進程單獨運行的。
1.2、Tomcat歷史
1.3、Tomcat官網
點擊打開
第二章 Tomcat單實例安裝
2.1、環境準備
- 虛擬機的版本:VMware-workstation-full-15.5.6-16341506.exe
- 系統鏡像版本:CentOS-6.10-x86_64-bin-DVD1.iso,全新安裝,桌面版,可上網
- 系統內存大小:1GB
- 系統硬盤大小:20GB
- 連接工具版本:SecureCRTSecureFX_HH_x64_7.0.0.326.zip
2.2、Tomcat下載
[root@caochenlei ~]# wget https://mirrors.bfsu.edu.cn/apache/tomcat/tomcat-8/v8.5.57/bin/apache-tomcat-8.5.57.tar.gz2.3、Tomcat解壓
[root@caochenlei ~]# tar -zxvf apache-tomcat-8.5.57.tar.gz2.4、Tomcat安裝
[root@caochenlei ~]# mv apache-tomcat-8.5.57 /usr/local/tomcat2.5、Tomcat啟動
注意:Tomcat啟動需要Java環境,我這里沒有安裝,使用的是系統自帶的,如果你的系統沒有Java環境請自行安裝,Java環境安裝不再本講之中!
啟動Tomcat:
[root@caochenlei ~]# /usr/local/tomcat/bin/startup.sh關閉防火墻:
[root@caochenlei ~]# service iptables stop [root@caochenlei ~]# chkconfig iptables off**在瀏覽器輸入:**http://192.168.239.144:8080/
2.6、Tomcat關閉
[root@caochenlei ~]# /usr/local/tomcat/bin/shutdown.sh第三章 Tomcat配置文件詳解
3.1、server.xml 詳解
server.xml 是tomcat 服務器的核心配置文件,包含了Tomcat的 Servlet 容器(Catalina)的所有配置。
3.1.1、Server
Server是server.xml的根元素,用于創建一個Server實例,默認使用的實現類是 org.apache.catalina.core.StandardServer。
<Server port="8005" shutdown="SHUTDOWN"> ... </Server>標簽屬性和子元素:
- port:Tomcat 監聽的關閉服務器的端口。
- shutdown:關閉服務器的指令字符串。
- Server內嵌的子元素為 Listener、GlobalNamingResources、Service。
3.1.2、Listener
默認配置的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" />3.1.3、GlobalNamingResources
GlobalNamingResources中定義了全局命名服務:
<GlobalNamingResources><!‐‐ 可編輯的用戶數據庫,UserDatabaseRealm也可以使用該數據庫對用戶進行身份驗證 ‐‐><Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat‐users.xml" /> </GlobalNamingResources>3.1.4、Service
該元素用于創建 Service 實例,默認使用 org.apache.catalina.core.StandardService。默認情況下,Tomcat 僅指定了Service 的名稱, 值為 “Catalina”。Service 可以內嵌的元素為 : Listener、Executor、Connector、Engine,其中 : Listener 用于為Service添加生命周期監聽器, Executor 用于配置Service 共享線程池,Connector 用于配置Service 包含的鏈接器, Engine 用于配置Service中鏈接器對應的Servlet 容器引擎。一個Server服務器,可以包含多個Service服務。
<Service name="Catalina"> ... </Service>3.1.5、Executor
默認情況下,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" />標簽屬性和子元素:
- name:線程池名稱,用于Connector中指定。
- namePrefix:所創建的每個線程的名稱前綴,一個單獨的線程名稱為 namePrefix+threadNumber。
- maxThreads:池中最大線程數。
- minSpareThreads:活躍線程數,也就是核心池線程數,這些線程不會被銷毀,會一直存在。
- maxIdleTime:線程空閑時間,超過該時間后,空閑線程會被銷毀,默認值為6000(1分鐘),單位毫秒。
- maxQueueSize:在被執行前最大線程排隊數目,默認為Int的最大值,也就是廣義的無限。除非特殊情況,這個值不需要更改, 否則會有請求不會被處理的情況發生。
- prestartminSpareThreads:啟動線程池時是否啟動 minSpareThreads部分線程。 默認值為false,即不啟動。
- threadPriority:線程池中線程優先級,默認值為5,值從1到10。
- className:線程池實現類,未指定情況下,默認實現類為 org.apache.catalina.core.StandardThreadExecutor。 如果想使用自定義線程池首先需要實現 org.apache.catalina.Executor接口。
3.1.6、Connector
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" />標簽屬性和子元素:
-
port:端口號,Connector 用于創建服務端Socket 并進行監聽, 以等待客戶端請求鏈接。如果該屬性設置為0,Tomcat將會隨機選擇一個可用的端口號給當前Connector使用。
-
protocol:當前Connector 支持的訪問協議。 默認為 HTTP/1.1,并采用自動切換機制選擇一個基于 JAVA NIO 的鏈接器或者基于本地APR的鏈接器(根據本地是否含有Tomcat的本地庫判定)。如果不希望采用上述自動切換的機制, 而是明確指定協議, 可以使用以下值。
- Http協議:
- AJP協議:
-
connectionTimeout:Connector接收連接后的等待超時時間, 單位為毫秒。 -1 表示不超時。
-
redirectPort:當前Connector 不支持SSL請求, 接收到了一個請求, 并且也符合 security-constraint 約束, 需要SSL傳輸,Catalina自動將請求重定向到指定的端口。
-
executor:指定共享線程池的名稱, 也可以通過maxThreads、minSpareThreads 等屬性配置內部線程池。
-
URIEncoding:用于指定編碼URI的字符編碼, Tomcat8.x版本默認的編碼為UTF-8 , Tomcat7.x版本默認為ISO-8859-1。
-
maxThreads:池中最大線程數。
-
minSpareThreads:活躍線程數,也就是核心池線程數,這些線程不會被銷毀,會一直存在。
-
acceptCount:接收的連接數。
-
maxConnections:接收的最大連接數。
-
compression:是否壓縮。
-
compressionMinSize:壓縮的大小。
-
disableUploadTimeout:禁用上傳超時。
完整的配置如下:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" executor="tomcatThreadPool" URIEncoding="UTF‐8"maxThreads="1000" minSpareThreads="100" acceptCount="1000" maxConnections="1000" compression="on" compressionMinSize="2048"disableUploadTimeout="true" />3.1.7、Engine
Engine 作為Servlet 引擎的頂級元素,內部可以嵌入: Cluster、Listener、Realm、 Valve和Host。
<Engine name="Catalina" defaultHost="localhost"> ... </Engine>標簽屬性和子元素:
- name: 用于指定Engine的名稱, 默認為Catalina 。該名稱會影響一部分Tomcat的存儲路徑(如臨時文件)。
- defaultHost : 默認使用的虛擬主機名稱, 當客戶端請求指向的主機無效時, 將交由默認的虛擬主機處理, 默認為localhost。
3.1.8、Host
Host 元素用于配置一個虛擬主機, 它支持以下嵌入元素:Alias、Cluster、Listener、Valve、Realm、Context。
如果在Engine下配置Realm, 那么此配置將在當前Engine下的所有Host中共享。 同樣,如果在Host中配置Realm , 則在當前Host下的所有Context中共享。
Context中的Realm優先級 > Host 的Realm優先級 > Engine中的Realm優先級。
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">... </Host>標簽屬性和子元素:
- name:當前Host通用的網絡名稱,必須與DNS服務器上的注冊信息一致。 Engine中包含的Host必須存在一個名稱與Engine的defaultHost設置一致。
- appBase:當前Host的應用基礎目錄,當前Host上部署的Web應用均在該目錄下(可以是絕對目錄,相對路徑),默認為webapps。
- unpackWARs:設置為true,Host在啟動時會將appBase目錄下war包解壓為目錄。設置為false, Host將直接從war文件啟動。
- autoDeploy:控制tomcat是否在運行時定期檢測并自動部署新增或變更的web應用。
通過給Host添加別名,我們可以實現同一個Host擁有多個網絡名稱,配置如下:
<Host name="www.web1.com" appBase="webapps" unpackWARs="true" autoDeploy="true"><Alias>www.web2.com</Alias> </Host>這個時候,我們就可以通過兩個域名訪問當前Host下的應用(需要確保DNS或hosts中添加了域名的映射配置)。
3.1.9、Context
Context 用于配置一個Web應用,默認的配置如下:
<Context docBase="myApp" path="/myApp">.... </Context>標簽屬性和子元素:
- docBase:Web應用目錄或者War包的部署路徑??梢允墙^對路徑,也可以是相對于Host appBase的相對路徑。
- path:Web應用的Context 路徑。如果我們Host名為localhost, 則該web應用訪問的根路徑為: http://localhost:8080/myApp。
- 它支持的內嵌元素為:CookieProcessor, Loader, Manager,Realm,Resources,WatchedResource,JarScanner,Valve。
簡單的舉例:
<Host name="www.tomcat.com" appBase="webapps" unpackWARs="true" autoDeploy="true"><Context docBase="D:\servlet_project" path="/myApp"></Context><Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host>3.2、tomcat-users.xml 詳解
該配置文件中,主要配置的是Tomcat的用戶,角色等信息,用來控制Tomcat中 host-manager、manager的訪問權限。
從早期的Tomcat版本開始,就提供了Web版的管理控制臺,他們是兩個獨立的Web應用,位于webapps目錄下。Tomcat 提供的管理應用有用于管理的Host的host-manager 和用于管理Web應用的manager。
3.2.1、host-manager應用配置
Tomcat啟動之后,可以通過 http://localhost:8080/host-manager/html 訪問該Web應用。 host-manager 默認添加了訪問權限控制,當打開網址時,需要輸入用戶名和密碼(conf/tomcat-users.xml中配置) 。所以要想訪問該頁面,需要在conf/tomcat-users.xml 中配置,并分配對應的角色:
<role rolename="admin-gui"/> <role rolename="admin-script"/> <user username="admin" password="123456" roles="admin-gui,admin-script"/>標簽屬性和子元素:
- admin-gui:用于控制頁面訪問權限。
- admin-script:用于控制以簡單文本的形式進行訪問。
啟動Tomcat,然后點擊host-manager,我是在虛擬機的火狐瀏覽器中打開的,它不能讓別人隨意訪問,否則會出現安全問題:
3.2.2、manager應用配置
manager的訪問地址為 http://localhost:8080/manager,同樣,manager也添加了頁面訪問控制,所以要想訪問該頁面,需要在conf/tomcat-users.xml 中配置,并分配對應的角色:
<role rolename="admin‐gui" /> <role rolename="admin‐script" /> <role rolename="manager‐gui" /> <role rolename="manager‐script" /> <user username="admin" password="123456" roles="admin-script,admin-gui,manager-gui,manager-script" />啟動Tomcat,然后點擊manager,我是在虛擬機的火狐瀏覽器中打開的,它不能讓別人隨意訪問,否則會出現安全問題:
3.3、web.xml 詳解
web.xml 是web應用的描述文件, 它支持的元素及屬性來自于Servlet 規范定義 。 在Tomcat 中, Web 應用的描述信息包括 tomcat/conf/web.xml 中默認配置以及 Web應用 WEB-INF/web.xml 下的定制配置。
3.3.1、ServletContext初始化參數
我們可以通過 添加ServletContext 初始化參數,它配置了一個鍵值對,這樣我們可以在應用程序中使用 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>標簽屬性和子元素:
- param‐name:初始化參數名稱。
- param‐value:初始化參數的值。
- description:這個參數的描述信息。
3.3.2、會話配置
用于配置Web應用會話,包括 超時時間、Cookie配置以及會話追蹤模式。它將覆蓋server.xml 和 context.xml 中的配置。舉例如下:
<session-config><session-timeout>30</session‐timeout><cookie-config><name>JESSIONID</name><domain>www.baidu.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>標簽屬性和子元素:
- session-timeout: 會話超時時間,單位:分鐘。
- cookie-config:用于配置會話追蹤Cookie。
- name:Cookie的名稱。
- domain:Cookie的域名。
- path:Cookie的路徑。
- comment:Cookie的注釋。
- http-only:Cookie只能通過HTTP方式進行訪問,JS無法讀取或修改,此項可以增 加網站訪問的安全性。
- secure:此Cookie只能通過HTTPS連接傳遞到服務器,而HTTP連接則不會傳遞該信息。注意是從瀏覽器傳遞到服務器,服務器端的Cookie對象不受此項影響。
- max-age:以秒為單位表示cookie的生存期,默認為‐1表示是會話Cookie,瀏覽器 關閉時就會消失。
- tracking-mode:用于配置會話追蹤模式,Servlet3.0版本中支持的追蹤模式: COOKIE、URL、SSL。
3.3.3、Servlet配置
Servlet 的配置主要是兩部分, servlet 和 servlet-mapping :
<servlet><servlet-name>myServlet</servlet‐name><servlet-class>com.caochenlei.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>標簽屬性和子元素:
servlet:
- servlet-name:指定servlet的名稱, 該屬性在web.xml中唯一。
- servlet-class:用于指定servlet類名。
- init-param:用于指定servlet的初始化參數, 在應用中可以通過 HttpServlet.getInitParameter 獲取。
- param-name:初始化參數名稱。
- param-value:初始化參數的值。
- load-on-startup:用于控制在Web應用啟動時,Servlet的加載順序, 值小于0,web應用啟動時,不加載該servlet,第一次訪問時加載。
- enabled:若為false,表示Servlet不處理任何請求。
servlet-mapping:
- servlet-name:你想要讓哪個servlet處理,這里就寫哪個servlet名稱。
- url-pattern:用于指定URL表達式,一個 servlet‐mapping可以同時配置多個 url‐ pattern。
servlet 中文件上傳配置:
<servlet><servlet-name>uploadServlet</servlet‐name><servlet-class>com.caochenlei.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>標簽屬性和子元素:
- multipart-config:上傳的配置
- location:存放生成的文件地址。
- max-file-size:允許上傳的文件最大值。 默認值為‐1, 表示沒有限制。
- max-request-size:針對該 multi/form‐data 請求的最大數量,默認值為‐1, 表示無限制。
- file-size-threshold:當數量量大于該值時, 內容會被寫入文件。
3.3.4、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>標簽屬性和子元素:
- listener-class:用于指定監聽的類,該類必須實現Listener接口。
3.3.5、Filter配置
filter 用于配置web應用過濾器, 用來過濾資源請求及響應。 經常用于認證、日志、加密、數據轉換等操作, 配置如下:
<filter><filter-name>myFilter</filter‐name><filter-class>com.caochenlei.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>標簽屬性和子元素:
filter:
- filter-name:用于指定過濾器名稱,在web.xml中,過濾器名稱必須唯一。
- filter-class:過濾器的全限定類名,該類必須實現Filter接口。
- async-supported:該過濾器是否支持異步。
- init-param:用于配置Filter的初始化參數, 可以配置多個, 可以通過FilterConfig.getInitParameter獲取。
- param-name:初始化參數名稱。
- param-value:初始化參數的值。
filter-mapping:
- filter-name:這里指的是你想使用哪個過濾器進行過濾就寫哪個過濾器的名稱。
- url-pattern:指定該過濾器需要攔截的URL。
3.3.6、歡迎頁面配置
welcome-file-list 用于指定web應用的歡迎文件列表。嘗試請求的順序,從上到下。
<welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file><welcome-file>default.html</welcome-file><welcome-file>default.htm</welcome-file><welcome-file>default.jsp</welcome-file> </welcome-file-list>3.3.7、錯誤頁面配置
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>第四章 Tomcat高可用集群
4.1、環境準備
- 虛擬機的版本:VMware-workstation-full-15.5.6-16341506.exe
- 系統鏡像版本:CentOS-6.10-x86_64-bin-DVD1.iso,全新安裝,桌面版,可上網
- 系統內存大小:1GB
- 系統硬盤大小:20GB
- 連接工具版本:SecureCRTSecureFX_HH_x64_7.0.0.326.zip
4.2、集群概述
由于單臺Tomcat的承載能力是有限的,當我們的業務系統用戶量比較大,請求壓力比較大時,單臺Tomcat是扛不住的,這個時候,就需要搭建Tomcat的集群,而目前比較流程的做法就是通過Nginx來實現Tomcat集群的負載均衡。
4.3、集群架構
4.4、安裝第一臺tomcat服務器
解壓:
[root@caochenlei ~]# tar -zxvf apache-tomcat-8.5.57.tar.gz安裝:
[root@caochenlei ~]# mv apache-tomcat-8.5.57 /usr/local/tomcat1創建測試目錄和頁面:
[root@caochenlei ~]# mkdir -p /usr/local/tomcat1/webapps/edu [root@caochenlei ~]# echo "<h1>This is 8080 Port</h1>" > /usr/local/tomcat1/webapps/edu/a.html開放防火墻:
[root@caochenlei ~]# /sbin/iptables -I INPUT -p tcp --dport 8080 -j ACCEPT [root@caochenlei ~]# /etc/rc.d/init.d/iptables save啟動:
[root@caochenlei ~]# /usr/local/tomcat1/bin/startup.sh4.5、安裝第二臺tomcat服務器
解壓:
[root@caochenlei ~]# tar -zxvf apache-tomcat-8.5.57.tar.gz安裝:
[root@caochenlei ~]# mv apache-tomcat-8.5.57 /usr/local/tomcat2修改端口:
- 先刪除:
- 再添加:
創建測試目錄和頁面:
[root@caochenlei ~]# mkdir -p /usr/local/tomcat2/webapps/edu [root@caochenlei ~]# echo "<h1>This is 8081 Port</h1>" > /usr/local/tomcat2/webapps/edu/a.html開放防火墻:
[root@caochenlei ~]# /sbin/iptables -I INPUT -p tcp --dport 8081 -j ACCEPT [root@caochenlei ~]# /etc/rc.d/init.d/iptables save啟動:
[root@caochenlei ~]# /usr/local/tomcat2/bin/startup.sh4.6、安裝Nginx反向代理服務器
安裝依賴:
[root@caochenlei ~]# yum install -y gcc gcc-c++ make libtool wget pcre pcre-devel zlib zlib-devel openssl openssl-develNginx下載:
[root@caochenlei ~]# wget http://nginx.org/download/nginx-1.18.0.tar.gzNginx解壓:
[root@caochenlei ~]# tar -zxvf nginx-1.18.0.tar.gzNginx安裝:
[root@caochenlei ~]# cd nginx-1.18.0 [root@caochenlei nginx-1.18.0]# ./configure [root@caochenlei nginx-1.18.0]# make && make install注意:安裝完成后的路徑為:/usr/local/nginx
Nginx配置:
[root@caochenlei nginx-1.18.0]# vi /usr/local/nginx/conf/nginx.conf #在 server 外邊配置,負載均衡服務列表 upstream myserver {server 192.168.239.144:8080;server 192.168.239.144:8081; }#在 location / { 里邊配置,路徑請求轉發規則proxy_pass http://myserver; [root@caochenlei nginx-1.18.0]# /usr/local/nginx/sbin/nginxNginx命令:
- 普通啟動服務:/usr/local/nginx/sbin/nginx
- 配置文件啟動:/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
- 暴力停止服務:/usr/local/nginx/sbin/nginx -s stop
- 優雅停止服務:/usr/local/nginx/sbin/nginx -s quit
- 檢查配置文件:/usr/local/nginx/sbin/nginx -t
- 重新加載配置:/usr/local/nginx/sbin/nginx -s reload
- 查看相關進程:ps -ef | grep nginx
開放防火墻:
[root@caochenlei ~]# /sbin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT [root@caochenlei ~]# /etc/rc.d/init.d/iptables save iptables:將防火墻規則保存到 /etc/sysconfig/iptables:[確定]4.7、訪問測試
打開IE瀏覽器輸入:http://192.168.206.128/edu/a.html
4.8、如何保證主nginx高可用
請您參考:學習Nginx這一篇就夠了中的高可用集群如何搭建的。
原理說明:準備兩臺Nginx,一主一備,每一臺上安裝一個keepalived,由keepalived負責監測當前機器上的nginx是否可用(其實是調用一個shell腳本不停的查看進程信息),同時也會在兩個keepalived之間進行心跳監測,如果主節點宕機,則從節點自動跟上,訪問是通過虛擬IP進行訪問的。
4.9、如何解決session共享問題
方案一:ip_hash 策略
通過修改Nginx配置文件,讓每個請求按訪問 ip 的 hash 結果分配,這樣每個訪客固定訪問一個后端服務器,可以解決 session 的問題。 例如:
方案二:session 復制
在每臺Tomcat的 conf/server.xml 配置如下:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>在每臺Tomcat部署的應用程序中,例如:servlet_demo 的 web.xml 中加入如下配置 :
<distributable/>注意:上述方案,適用于較小的集群環境(節點數不超過4個),如果集群的節點數比較多的話,通過這種廣播的形式來完成Session的復制,會消耗大量的網絡帶寬,影響服務的性能。
第五章 Tomcat安全問題
5.1、配置安全
- 刪除webapps目錄下的所有文件
- 禁用tomcat管理界面
- 注釋或刪除tomcat-users.xml文件內的所有用戶權限
- 更改關閉tomcat指令或禁用
- 定義錯誤頁面
5.2、應用安全
在大部分的Web應用中,特別是一些后臺應用系統,都會實現自己的安全管理模塊(權 限模塊),用于控制應用系統的安全訪問,基本包含兩個部分:認證(登錄/單點登錄) 和授權(功能權限、數據權限)兩個部分。對于當前的業務系統,可以自己做一套適用 于自己業務系統的權限模塊,也有很多的應用系統直接使用一些功能完善的安全框架, 將其集成到我們的web應用中,如:SpringSecurity、Apache Shiro等。
5.3、傳輸安全
HTTPS的全稱是超文本傳輸安全協議(Hypertext Transfer Protocol Secure),是一種網絡安全傳輸協議。在HTTP的基礎上加入SSL/TLS來進行數據加密,保護交換數據不被泄露、竊取。
SSL 和 TLS 是用于網絡通信安全的加密協議,它允許客戶端和服務器之間通過安全鏈接 通信。SSL 協議的3個特性:
- 保密:通過SSL鏈接傳輸的數據時加密的。
- 鑒別:通信雙方的身份鑒別,通常是可選的,單至少有一方需要驗證。
- 完整性:傳輸數據的完整性檢查。
從性能角度考慮,加解密是一項計算昂貴的處理,因為盡量不要將整個Web應用采用SSL 鏈接, 實際部署過程中, 選擇有必要進行安全加密的頁面(存在敏感信息傳輸的頁面) 采用SSL通信。
HTTPS和HTTP的區別主要為以下四點:
- HTTPS協議需要到證書頒發機構CA申請SSL證書,然后與域名進行綁定,HTTP不用申請證書。
- HTTP是超文本傳輸協議,屬于應用層信息傳輸,HTTPS則是具有SSL加密傳安全性傳輸協議,對數據的傳輸進行加密,相當于HTTP的升級版。
- HTTP和HTTPS使用的是完全不同的連接方式,用的端口也不一樣,前者是8080,后者是8443。
- HTTP的連接很簡單,是無狀態的、HTTPS協議是由SSL+HTTP協議構建的可進行加密傳輸、身份認證的網絡協議,比HTTP協議安全。
HTTPS協議優勢:
- 提高網站排名,有利于SEO。谷歌已經公開聲明兩個網站在搜索結果方面相同,如果 一個網站啟用了SSL,它可能會獲得略高于沒有SSL網站的等級,而且百度也表明對安裝了SSL的網站表示友好。因此,網站上的內容中啟用SSL都有明顯的SEO優勢。
- 隱私信息加密,防止流量劫持。特別是涉及到隱私信息的網站,互聯網大型的數據泄露的事件頻發發生,網站進行信息加密勢在必行。
- 瀏覽器受信任。 自從各大主流瀏覽器大力支持HTTPS協議之后,訪問HTTP的網站都會提示“不安全”的警告信息。
Tomcat支持HTTPS:這里采用單實例版本的Tomcat進行配置測試
第一步:查找秘鑰庫生成器,這個工具是Java提供的
[root@caochenlei ~]# find / -name keytool /usr/bin/keytool /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.41.x86_64/jre/bin/keytool /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.181.x86_64/jre/bin/keytool /etc/alternatives/keytool第二步:生成秘鑰庫文件
[root@caochenlei ~]# /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.181.x86_64/jre/bin/keytool -genkey -alias tomcat -keyalg RSA -keystore tomcatkey.keystore 輸入密鑰庫口令: 再次輸入新口令: 您的名字與姓氏是什么?(這里使用的必須是域名)[Unknown]: www.abc.com 您的組織單位名稱是什么?[Unknown]: abc 您的組織名稱是什么?[Unknown]: abc 您所在的城市或區域名稱是什么?[Unknown]: BeiJing 您所在的省/市/自治區名稱是什么?[Unknown]: BeiJing 該單位的雙字母國家/地區代碼是什么?[Unknown]: CN CN=www.abc.com, OU=abc, O=abc, L=BeiJing, ST=BeiJing, C=CN是否正確?[否]: Y輸入 <tomcat> 的密鑰口令(如果和密鑰庫口令相同, 按回車): Warning: JKS 密鑰庫使用專用格式。建議使用 "keytool -importkeystore -srckeystore tomcatkey.keystore -destkeystore tomcatkey.keystore -deststoretype pkcs12" 遷移到行業標準格式 PKCS12。第三步:將秘鑰庫文件 tomcatkey.keystore 復制到tomcat/conf 目錄下
[root@caochenlei ~]# cp tomcatkey.keystore /usr/local/tomcat/conf/第四步:配置tomcat/conf/server.xml
先刪除:
[root@caochenlei ~]# rm -rf /usr/local/tomcat/conf/server.xml再添加:
[root@caochenlei ~]# vi /usr/local/tomcat/conf/server.xml <?xml version="1.0" encoding="UTF-8"?> <Server port="8005" shutdown="SHUTDOWN"><Listener className="org.apache.catalina.startup.VersionLoggerListener" /><Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" /><Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" /><Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" /><Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" /><GlobalNamingResources><Resource name="UserDatabase" auth="Container" type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" pathname="conf/tomcat-users.xml" /></GlobalNamingResources><Service name="Catalina"><Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /><!-- 主要新增的代碼 --><Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" maxThreads="150" schema="https" secure="true" SSLEnabled="true"><SSLHostConfig certificateVerification="false"><Certificate certificateKeystoreFile="/usr/local/tomcat/conf/tomcatkey.keystore" certificateKeystorePassword="123456" type="RSA" /></SSLHostConfig></Connector><Engine name="Catalina" defaultHost="localhost"><Realm className="org.apache.catalina.realm.LockOutRealm"><Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase" /></Realm><Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"><Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /></Host></Engine></Service> </Server>第五步:關閉服務器,防止啟動失敗,然后再啟動訪問
[root@caochenlei ~]# /usr/local/tomcat1/bin/shutdown.sh [root@caochenlei ~]# /usr/local/tomcat2/bin/shutdown.sh [root@caochenlei ~]# /usr/local/nginx/sbin/nginx -s quit [root@caochenlei ~]# /usr/local/tomcat/bin/startup.sh第六步:配置本機域名映射
復制一份 C:\Windows\System32\drivers\etc\hosts 到桌面,然后新增一條記錄,然后再替換回去。
#虛擬機的IP地址 虛擬域名 192.168.239.144 www.abc.com打開瀏覽器輸入:https://www.abc.com:8443/
第六章 Tomcat原理分析
6.1、Http工作原理
HTTP協議是瀏覽器與服務器之間的數據傳送協議。作為應用層協議,HTTP是基于TCP/IP協議來傳遞數據的(HTML文件、圖片、查詢結果等),HTTP協議不涉及數據包(Packet)傳輸,主要規定了客戶端和服務器之間的通信格式。它的整個過程如下圖所示:
那我們想要探究的Tomcat作為一個HTTP服務器,在這個過程中都做了些什么事情呢?
主要是接受連接、解析請求數據、處理請求和發送響應這幾個步驟。
6.2、Tomcat整體架構
Tomcat要實現兩個核心功能:
因此Tomcat設計了兩個核心組件連接器(Connector)和容器(Container)來分別做這 兩件事情。連接器負責對外交流,容器負責內部處理。
6.3、Coyote連接器架構
Coyote是Tomcat的連接器框架的名稱 , 是Tomcat服務器提供的供客戶端訪問的外部接口??蛻舳送ㄟ^Coyote與服務器建立連接、發送請求并接受響應 。
Coyote封裝了底層的網絡通信(Socket請求及響應處理),為Catalina容器提供了統一的接口,使Catalina容器與具體的請求協議及IO操作方式完全解耦。Coyote 將Socket輸入轉換封裝為Request對象,交由Catalina容器進行處理,處理請求完成后,Catalina通過Coyote提供的Response對象將結果寫入輸出流 。
Coyote作為獨立的模塊,只負責具體協議和IO的相關操作,與Servlet規范實現沒有直接關系,因此即便是Request和Response對象也并未實現Servlet規范對應的接口, 而是在Catalina中將他們進一步封裝為ServletRequest和ServletResponse。
在Coyote中,Tomcat支持的IO模型,請看下表:
| NIO | 非阻塞I/O,采用Java NIO類庫實現。 |
| NIO2 | 異步I/O,采用JDK 7最新的NIO2類庫實現。 |
| APR | 采用Apache可移植運行庫實現,是C/C++編寫的本地庫。如果選擇該方案,需要單獨安裝APR庫。 |
在Coyote中,Tomcat支持的應用層協議,請看下表:
| HTTP/1.1 | 這是大部分Web應用采用的訪問協議。 |
| AJP/1.3 | 用于和Web服務器集成(如Apache),以實現對靜態資源的優化以及集群部署。 |
| HTTP/2 | HTTP 2.0大幅度的提升了Web性能。下一代HTTP協議 , 自8.5以及9.0版本之后支持。 |
協議分層 :
在8.0之前,Tomcat 默認采用的I/O方式為 BIO,之后改為 NIO。 無論 NIO、NIO2還是 APR,在性能方面均優于以往的BIO。 如果采用APR,甚至可以達到 Apache HTTP Server的影響性能。
Tomcat為了實現支持多種I/O模型和應用層協議,一個容器可能對接多個連接器,就好比一個房間有多個門。但是單獨的連接器或者容器都不能對外提供服務,需要把它們組裝起來才能工作,組裝后這個整體叫作Service組件。這里請你注意,Service本身沒有做什么重要的事情,只是在連接器和容器外面多包了一層,把它們組裝在一起。Tomcat內可能有多個Service,這樣的設計也是出于靈活性的考慮。通過在Tomcat中配置多個Service,可以實現通過不同的端口號來訪問同一臺機器上部署的不同應用。
Coyote的主要組件結構如下:
Coyote的各個組件的作用如下:
-
EndPoint
EndPoint:Coyote 通信端點,即通信監聽的接口,是具體Socket接收和發送處理器,是對傳輸層的抽象,因此EndPoint用來實現TCP/IP協議的。
Tomcat 并沒有EndPoint接口,而是提供了一個抽象類AbstractEndpoint,里面定義了兩個內部類:Acceptor和SocketProcessor。Acceptor用于監聽Socket連接請求。SocketProcessor用于處理接收到的Socket請求,它實現Runnable接口,在Run方法里調用協議處理組件Processor進行處理。為了提高處理力,SocketProcessor被提交到線程池來執行,而這個線程池叫作執行器(Executor)。 -
Processor
Processor:Coyote 協議處理接口,如果說EndPoint是用來實現TCP/IP協議的,那么Processor用來實現HTTP協議,Processor接收來自EndPoint的Socket,讀取字節流解析成Tomcat Request和Response對象,并通過Adapter將其提交到容器處理,Processor是對應用層協議的抽象。 -
ProtocolHandler
ProtocolHandler:Coyote 協議接口,通過Endpoint和Processor,實現針對具體協議的處理能力。Tomcat按照協議和I/O 提供了6個實現類 : AjpNioProtocol、AjpNio2Protocol、AjpAprProtocol、Http11NioProtocol、Http11Nio2Protocol、Http11AprProtocol。我們在配置tomcat / conf / server.xml時,至少要指定具體的ProtocolHandler , 當然也可以指定協議名稱,如:HTTP/1.1,如果安裝了APR,那么將使用Http11AprProtocol,否則使用 Http11NioProtocol 。
-
Adapter
由于協議不同,客戶端發過來的請求信息也不盡相同,Tomcat定義了自己的Request類 來“存放”這些請求信息。ProtocolHandler接口負責解析請求并生成Tomcat Request類。 但是這個Request對象不是標準的ServletRequest,也就意味著,不能用Tomcat Request作為參數來調用容器。Tomcat設計者的解決方案是引入CoyoteAdapter,這是 適配器模式的經典運用,連接器調用CoyoteAdapter的Sevice方法,傳入的是Tomcat Request對象,CoyoteAdapter負責將Tomcat Request轉成ServletRequest,再調用容器的Service方法。
6.4、Catalina容器架構
Tomcat的模塊分層結構如下:
Tomcat本質上就是一款 Servlet 容器,因此Catalina 才是 Tomcat 的核心,其他模塊都是為Catalina提供支撐的。比如:通過Coyote模塊提供連接通信,Jasper 模塊提供JSP引擎,Naming 提供JNDI 服務,Juli提供日志服務。
Catalina的主要組件結構如下:
Catalina的各個組件的作用如下:
-
Catalina
負責解析Tomcat的配置文件 , 以此來創建服務器Server組件,并根據 命令來對其進行管理。
-
Server
服務器表示整個Catalina Servlet容器以及其它組件,負責組裝并啟動Servlet引擎、Tomcat連接器。Server通過實現Lifecycle接口,提供了 一種優雅的啟動和關閉整個系統的方式。
-
Service
服務是Server內部的組件,一個Server包含多個Service。它將若干個Connector組件綁定到一個Container(Engine)上。
-
Connector
連接器主要是處理與客戶端的通信,它負責接收客戶請求,然后轉給相關的容器處理,最后向客戶返回響應結果。
-
Container
容器負責處理用戶的Servlet請求,并返回對象給web用戶的模塊。
Container的主要組件結構如下:
Tomcat設計了4種容器,分別是Engine、Host、Context和Wrapper。這4種容器不是平行關系,而是父子關系。Tomcat通過一種分層的架構,使得Servlet容器具有很好的靈活性。
Container的各個組件的作用如下:
-
Engine
表示整個Catalina的Servlet引擎,用來管理多個虛擬站點,一個Service最多只能有一個Engine,但是一個引擎可包含多個Host。
-
Host
代表一個虛擬主機或者說一個站點,可以給Tomcat配置多個虛擬主機地址,而一個虛擬主機下可包含多個Context。
-
Context
表示一個Web應用程序, 一個Web應用可包含多個Wrapper。
-
Wrapper
表示一個Servlet,Wrapper 作為容器中的最底層,不能包含子容器。
我們也可以再通過Tomcat的server.xml配置文件來加深對Tomcat容器的理解。Tomcat采用了組件化的設計,它的構成組件都是可配置的,其中最外層的是Server,其他組件按照一定的格式要求配置在這個頂層容器中。
那么,Tomcat是怎么管理這些容器的呢?你會發現這些容器具有父子關系,形成一個樹形結構,你可能馬上就想到了設計模式中的組合模式。沒錯,Tomcat就是用組合模式來管理這些容器的。具體實現方法是,所有容器組件都實現了Container接口,因此組合模式可以使得用戶對單容器對象和組合容器對象的使用具有一致性。這里單容器對象指的是最底層的Wrapper,組合容器對象指的是上面的Context、Host或者Engine。
6.5、Jasper處理流程
Tomcat在默認的web.xml中配置了一個org.apache.jasper.servlet.JspServlet,用于處理所有的.jsp或 .jspx結尾的請求,該Servlet 實現即是運行時編譯的入口。
JspServlet 處理流程圖:
- 如果在 tomcat/conf/web.xml 中配置了參數scratchdir,則jsp編譯后的結果,就會存儲在該目錄下 。
- 如果沒有配置該選項,則會將編譯后的結果,存儲在Tomcat安裝目錄下的 work/Catalina(Engine名稱)/localhost(Host名稱)/Context名稱 。
除了運行時編譯,我們還可以直接在Web應用啟動時, 一次性將Web應用中的所有的JSP頁面一次性編譯完成。在這種情況下,Web應用運行過程中,便可以不必再進行實時編譯,而是直接調用JSP頁面對應的Servlet完成請求處理, 從而提升系統性能。
Tomcat 提供了一個Shell程序JspC,用于支持JSP預編譯,而且在Tomcat的安裝目錄下提供了一個 catalina-tasks.xml 文件聲明了Tomcat 支持的Ant任務, 因此,我們很容易使用 Ant 來執行JSP 預編譯。(要想使用這種方式,必須得確保在此之前已經下載并安裝了Apache Ant)。
6.6、JSP編譯過程
Compiler 編譯工作主要包含代碼生成和編譯兩部分:
-
代碼生成
- 1) Compiler 通過一個 PageInfo 對象保存JSP 頁面編譯過程中的各種配置,這些配置可能來源于 Web 應用初始化參數, 也可能來源于JSP頁面的指令配置(如 page , include)。
- 2) 調用ParserController 解析指令節點, 驗證其是否合法,同時將配置信息保存到 PageInfo 中, 用于控制代碼生成。
- 3) 調用ParserController 解析整個頁面, 由于 JSP 是逐行解析, 所以對于每一行會創建一個具體的Node 對象。如靜態文本(TemplateText)、Java代碼(Scriptlet)、定制標簽(CustomTag)、Include指令(IncludeDirective)。
- 4) 驗證除指令外其他所有節點的合法性, 如腳本、定制標簽、EL表達式等。
- 5) 收集除指令外其他節點的頁面配置信息。
- 6) 編譯并加載當前 JSP 頁面依賴的標簽。
- 7) 對于JSP頁面的EL表達式,生成對應的映射函數。
- 8) 生成JSP頁面對應的Servlet類源代碼 編譯 代碼生成完成后,Compiler還會生成 SMAP信息。 如果配置生成 SMAP信息,Compiler則會在編譯階段將SMAP信息寫到class文件中 。
-
編譯階段
Compiler的兩個實現 AntCompiler 和 JDTCompiler 分別調用先關框架的 API 進行源代碼編譯。
對于 AntCompiler 來說, 構造一個 Ant 的javac 的任務完成編譯。
對于 JDTCompiler 來說, 調用 org.eclipse.jdt.internal.compiler.Compiler 完成編譯。
6.7、Tomcat啟動流程
6.8、Tomcat請求處理流程
總結
以上是生活随笔為你收集整理的学习Tomcat这一篇就够了的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ps – report process
- 下一篇: tikz绘图