第一章 Tomcat簡介
- Tomcat是Apache軟件基金會(Apache Software Foundation)的Jakarta項目中的一個核心項目,由Apache,Sun和其他一些公司及個人共同開發而成。
- Tomcat服務器是一個免費的開放源代碼的Web應用服務器,屬於輕量級應用服務器,在中小型系統和並發訪問用戶不是很多的場合下被普遍使用,是開發和調試JSP程序的首選。
- Tomcat和Nginx,APache(httpd),lighttpd等Web服務器一樣,具有處理HTML頁面的功能,另外它還是一個Servlet和JSP容器,獨立的Servlet容器是Tomcat的默認模式。不過,Tomcat處理靜態HTML的能力不如Nginx/Apache服務器。
對比php軟件,區別?
目前Tomcat最新版本為9.0。Java容器還有resin,weblogic等。
第二章 Tomcat安裝
2.1 軟件准備
JDK下載:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
Tomcat下載:http://tomcat.apache.org/
2.2 部署java環境jdk
#jdk的解壓安裝
[root@localhost ~]# tar xf jdk-8u60-linux-x64.tar.gz -C /usr/local/
[root@localhost ~]# ln -s /usr/local/jdk1.8.0_60 /usr/local/jdk
#配置java環境變量
[root@localhost ~]# sed -i.ori '$a export JAVA_HOME=/usr/local/jdk\nexport PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH\nexport CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar' /etc/profile
[root@localhost ~]# tail -3 /etc/profile
export JAVA_HOME=/usr/local/jdk
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar
#讓java環境變量立刻生效
[root@localhost ~]# source /etc/profile
#檢查java環境安裝情況
[root@localhost ~]# which java
/usr/local/jdk/bin/java
[root@localhost ~]# java -version #出現以下信息表示部署成功
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
關於上面那個sed命令的說明:
sed -i.ori :-i表示對文件本身操作,.ori表示修改的同時備份源文件
$a :$表示文件內容的最后一行,a表示在下面進行數據插入
\n :表示插入數據時換行
2.3 安裝Tomcat
#解壓安裝Tomcat
[root@localhost ~]# tar xf apache-tomcat-8.0.27.tar.gz -C /usr/local/
[root@localhost ~]# ln -s /usr/local/apache-tomcat-8.0.27/ /usr/local/tomcat
#配置Tomcat環境變量
[root@localhost ~]# echo 'export TOMCAT_HOME=/usr/local/tomcat' >> /etc/profile
[root@localhost ~]# source /etc/profile
#對jdk及Tomcat安裝目錄遞歸授權root
[root@localhost ~]# chown -R root.root /usr/local/jdk/ /usr/local/tomcat/
#檢查環境變量配置情況
[root@localhost ~]# tail -4 /etc/profile
export JAVA_HOME=/usr/local/jdk
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar
export TOMCAT_HOME=/usr/local/tomcat
2.4 Tomcat目錄介紹
[root@localhost tomcat]# cd /usr/local/tomcat/
[root@localhost tomcat]# tree -L 1
.
├── bin #用以啟動,關閉Tomcat或者其他功能的腳本(.bat文件和.sh文件)
├── conf #用以配置Tomcat的XML及DTD文件
├── lib #存放web應用能訪問的JAR包
├── LICENSE
├── logs #Catalina和其他Web應用程序的日志文件
├── NOTICE
├── RELEASE-NOTES
├── RUNNING.txt
├── temp #臨時文件
├── webapps #Web應用程序根目錄
└── work #用以產生有JSP編譯出的Servlet的.java和.class文件
7 directories, 4 files
[root@localhost tomcat]# cd webapps/
[root@localhost webapps]# ll
total 20
drwxr-xr-x. 14 root root 4096 Oct 24 09:07 docs #tomcat幫助文檔
drwxr-xr-x. 6 root root 4096 Oct 24 09:07 examples #web應用實例
drwxr-xr-x. 5 root root 4096 Oct 24 09:07 host-manager #管理
drwxr-xr-x. 5 root root 4096 Oct 24 09:07 manager #管理
drwxr-xr-x. 3 root root 4096 Oct 24 09:07 ROOT #默認網站根目錄
2.5 啟動Tomcat
啟動程序:/usr/local/tomcat/bin/startup.sh
關閉程序:/usr/local/tomcat/bin/shutdown.sh
[root@localhost webapps]# /usr/local/tomcat/bin/startup.sh #程序啟動
Using CATALINA_BASE: /usr/local/tomcat #檢查環境變量CATALINA_BASE
Using CATALINA_HOME: /usr/local/tomcat #檢查環境變量CATALINA_HOME
Using CATALINA_TMPDIR: /usr/local/tomcat/temp #檢查環境變量CATALINA_TMPDIR
Using JRE_HOME: /usr/local/jdk #檢查環境變量JRE_HOME
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.
[root@localhost webapps]# netstat -antup | grep java
tcp 0 0 :::8080 :::* LISTEN 1352/java
tcp 0 0 ::ffff:127.0.0.1:8005 :::* LISTEN 1352/java
tcp 0 0 :::8009 :::* LISTEN 1352/java
2.6 訪問網站
網址:10.0.0.134:8080(訪問時請注意關閉iptables)
#查看Tomcat的日志
[root@localhost webapps]# cd /usr/local/tomcat/logs/
[root@localhost logs]# ls
catalina.2017-10-24.log localhost.2017-10-24.log
catalina.out localhost_access_log.2017-10-24.txt
host-manager.2017-10-24.log manager.2017-10-24.log
[root@localhost logs]# cat catalina.out
24-Oct-2017 09:20:13.718 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version: Apache Tomcat/8.0.27
24-Oct-2017 09:20:13.720 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built: Sep 28 2015 08:17:25 UTC
24-Oct-2017 09:20:13.723 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server number: 8.0.27.0
24-Oct-2017 09:20:13.723 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name: Linux
24-Oct-2017 09:20:13.723 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version: 2.6.32-431.el6.x86_64
24-Oct-2017 09:20:13.723 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture: amd64
24-Oct-2017 09:20:13.724 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home: /usr/local/jdk1.8.0_60/jre
24-Oct-2017 09:20:13.724 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version: 1.8.0_60-b27
24-Oct-2017 09:20:13.724 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor: Oracle Corporation
24-Oct-2017 09:20:13.725 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE: /usr/local/apache-tomcat-8.0.27
24-Oct-2017 09:20:13.725 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME: /usr/local/apache-tomcat-8.0.27
24-Oct-2017 09:20:13.725 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties
第三章 Tomcat的配置文件
3.1 Tomcat配置文件
[root@localhost logs]# cd /usr/local/tomcat/conf/
[root@localhost conf]# ll -h
total 216K
drwxr-xr-x. 3 root root 4.0K Oct 24 09:20 Catalina
-rw-------. 1 root root 13K Sep 28 2015 catalina.policy
-rw-------. 1 root root 7.0K Sep 28 2015 catalina.properties
-rw-------. 1 root root 1.6K Sep 28 2015 context.xml
-rw-------. 1 root root 3.4K Sep 28 2015 logging.properties
-rw-------. 1 root root 6.4K Sep 28 2015 server.xml #主配置文件
-rw-------. 1 root root 1.8K Sep 28 2015 tomcat-users.xml #Tomcat管理用戶配置文件
-rw-------. 1 root root 1.9K Sep 28 2015 tomcat-users.xsd
-rw-------. 1 root root 164K Sep 28 2015 web.xml
3.2 Tomcat管理
測試功能,生產環境不要用:
Tomcat管理功能用於對Tomcat自身以及部署在Tomcat上的應用進行管理的Web應用。在默認情況下是處於禁用狀態的。如果需要開啟這個功能,就需要配置管理用戶,即配置前面說過的tomcat-users.xml。
#找到配置文件的第38行
[root@localhost conf]# cat -n /usr/local/tomcat/conf/tomcat-users.xml | sed -n '38p'
38 </tomcat-users>
#在38行上加入如下三行代碼
[root@localhost conf]# tail -4 /usr/local/tomcat/conf/tomcat-users.xml
<role rolename="manager-gui"/> #加入此行
<role rolename="admin-gui"/> #加入此行
<user username="tomcat" password="tomcat" roles="manager-gui,admin-gui"/> #加入此行
</tomcat-users>
#重啟tomcat服務
[root@localhost conf]# /usr/local/tomcat/bin/shutdown.sh
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/local/jdk
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
[root@localhost conf]# /usr/local/tomcat/bin/startup.sh
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/local/jdk
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.
在瀏覽器里輸入http://10.0.0.134:8080/manager/status進行TOMCAT管理頁面
登陸驗證信息:賬號:tomcat 密碼:tomcat
3.3 Tomcat主配置文件Server.xml詳解
3.3.1 Server.xml組件類別
- 頂級組件:位於整個配置的頂層,如server。
- 容器類組件:可以包含其他組件的組件,如service,engine,host,context
- 連接器組件:連接用戶請求至tomcat,如connector。
- 被嵌套類組件:位於一個容器當中,不能包含其他組件,如Valve,logger。
<server>
<service>
<connector />
<engine>
<host>
<context></context>
</host>
<host>
<context></context>
</host>
</engine>
</service>
</server>
3.3.2 組件詳解
- engine:核心容器組件,catalina引擎,負責通過connector接收用戶請求,並處理請求,將請求轉至對應的虛擬主機host。
- host:類似於httpd中的虛擬主機,一般而言支持基於FQDN的虛擬主機。
- context:定義一個應用程序,是一個最內層的容器類組件(不能再嵌套)。配置context的主要目的指定對應對的webapp的根目錄,類似於httpd的alias,其還能為webapp指定額外的屬性,如部署方式等。
- connector:接收用戶請求,類似於httpd的listen配置監聽端口。
- service(服務):將connector關聯至engine,因此一個service內部可以有多個connector,但只能又一個引擎engine。service內部有兩個connector,一個engine。因此,一般情況下一個server內部只有一個service,一個service內部只有一個engine,但一個service內部可以有多個connector。
- server:表示一個運行於JVM中的tomcat實例。
Valve:閥門,攔截請求並在將其轉至對應的webapp前進行某種處理操作,可以用於任何容器中,比如記錄日志(access log valve),基於IP做訪問控制(remote address filer valve)。- logger:日志記錄器,用於記錄組件內部的狀態信息,可以用於除context外的任何容器中。
- realm:可以用於任意容器類的組件中,關聯一個用戶認證庫,實現認證和授權。可以關聯的認證庫有兩種:UserDatabaseRealm,MemoryRealm和JDBCRealm。
- UserDatabaseRealm:使用JNDI自定義的用戶認證庫。
- MemoryRealm:認證信息定義在tomcat-users.xml中。
- JDBCRealm:認證信息定義在數據庫中,並通過JDBC連接至數據庫中查找認證用戶。
3.3.3 配置文件注釋
<?xml version='1.0' encoding='utf-8'?>
<!--
<Server>元素代表整個容器,是Tomcat實例的頂層元素.由org.apache.catalina.Server接口來定義.它包含一個<Service>元素.並且它不能做為任何元素的子元素.
port指定Tomcat監聽shutdown命令端口.終止服務器運行時,必須在Tomcat服務器所在的機器上發出shutdown命令.該屬性是必須的.
shutdown指定終止Tomcat服務器運行時,發給Tomcat服務器的shutdown監聽端口的字符串.該屬性必須設置
-->
<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服務組件-->
<Service name="Catalina">
<!--
connector:接收用戶請求,類似於httpd的listen配置監聽端口.
port指定服務器端要創建的端口號,並在這個端口監聽來自客戶端的請求。
address:指定連接器監聽的地址,默認為所有地址(即0.0.0.0)
protocol連接器使用的協議,支持HTTP和AJP。AJP(Apache Jserv Protocol)專用於tomcat與apache建立通信的, 在httpd反向代理用戶請求至tomcat時使用(可見Nginx反向代理時不可用AJP協議)。
minProcessors服務器啟動時創建的處理請求的線程數
maxProcessors最大可以創建的處理請求的線程數
enableLookups如果為true,則可以通過調用request.getRemoteHost()進行DNS查詢來得到遠程客戶端的實際主機名,若為false則不進行DNS查詢,而是返回其ip地址
redirectPort指定服務器正在處理http請求時收到了一個SSL傳輸請求后重定向的端口號
acceptCount指定當所有可以使用的處理請求的線程數都被使用時,可以放到處理隊列中的請求數,超過這個數的請求將不予處理
connectionTimeout指定超時的時間數(以毫秒為單位)
-->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<!--engine,核心容器組件,catalina引擎,負責通過connector接收用戶請求,並處理請求,將請求轉至對應的虛擬主機host
defaultHost指定缺省的處理請求的主機名,它至少與其中的一個host元素的name屬性值是一樣的
-->
<Engine name="Catalina" defaultHost="localhost">
<!--Realm表示存放用戶名,密碼及role的數據庫-->
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<!--
host表示一個虛擬主機
name指定主機名
appBase應用程序基本目錄,即存放應用程序的目錄.一般為appBase="webapps" ,相對於CATALINA_HOME而言的,也可以寫絕對路徑。
unpackWARs如果為true,則tomcat會自動將WAR文件解壓,否則不解壓,直接從WAR文件中運行應用程序
autoDeploy:在tomcat啟動時,是否自動部署。
xmlValidation:是否啟動xml的校驗功能,一般xmlValidation="false"。
xmlNamespaceAware:檢測名稱空間,一般xmlNamespaceAware="false"。
-->
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!--
Context表示一個web應用程序,通常為WAR文件
docBase應用程序的路徑或者是WAR文件存放的路徑,也可以使用相對路徑,起始路徑為此Context所屬Host中appBase定義的路徑。
path表示此web應用程序的url的前綴,這樣請求的url為http://localhost:8080/path/****
reloadable這個屬性非常重要,如果為true,則tomcat會自動檢測應用程序的/WEB-INF/lib 和/WEB-INF/classes目錄的變化,自動裝載新的應用程序,可以在不重啟tomcat的情況下改變應用程序
-->
<Context path="" docBase="" debug=""/>
<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>
第四章 WEB站點部署
上線的代碼有兩種方式,第一種方式是直接將程序目錄放在webapps目錄下面,這種方式同學們已經明白了,就不多說了。第二種方式是使用開發工具將程序打包成war包,然后上傳到webapps目錄下面。下面讓我們見識一下這種方式。
4.1 使用war包部署web站點
#部署war包
[root@localhost ~]# ls -l memtest.war
-rw-r--r--. 1 root root 643 Oct 24 13:39 memtest.war #同學們將此war包拷貝到Linux虛擬機中
[root@localhost ~]# cp memtest.war /usr/local/tomcat/webapps/
[root@localhost ~]# ls /usr/local/tomcat/webapps/
docs examples host-manager manager memtest.war ROOT
#重啟tomcat服務
[root@localhost ~]# /usr/local/tomcat/bin/startup.sh
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr/local/jdk
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.
[root@localhost ~]# netstat -antup | grep java
tcp 0 0 :::8080 :::* LISTEN 1972/java
tcp 0 0 ::ffff:127.0.0.1:8005 :::* LISTEN 1972/java
tcp 0 0 :::8009 :::* LISTEN 1972/java
#查看war包的解壓縮情況
[root@localhost webapps]# ls /usr/local/tomcat/webapps/
docs examples host-manager manager memtest memtest.war ROOT #war包已經被解壓出來了
用瀏覽器訪問:http://10.0.0.134:8080/memtest/meminfo.jsp如下:
4.2 自定義默認網站目錄
上面訪問的網址為:http://10.0.0.134:8080/memtest/meminfo.jsp
現在我想訪問格式為:http://10.0.0.134:8080/meminfo.jsp
方法一:
將meminfo.jsp或其他程序放在tomcat/webapps/ROOT目錄下即可。因為默認網站根目錄為tomcat/webapps/ROOT
方法二:
[root@tomcat ~]# vim /application/tomcat/conf/server.xml
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Context path="" docBase="/usr/local/tomcat/webapps/memtest" debug="0" reloadable="false" crossContext="true"/> #在虛擬主機這里添加一行代碼限定web站點的根目錄路徑
[root@tomcat ~]# /application/tomcat/bin/shutdown.sh
[root@tomcat ~]# /application/tomcat/bin/startup.sh
第五章 Tomcat多實例及集群架構
5.1 Tomcat多實例
5.1.1 復制Tomcat目錄
[root@localhost ~]# cd /usr/local/
[root@localhost local]# ls
apache-tomcat-8.0.27 etc include jdk1.8.0_60 lib64 sbin src
bin games jdk lib libexec share tomcat
[root@localhost local]# cp -a apache-tomcat-8.0.27 tomcat8_1
[root@localhost local]# cp -a apache-tomcat-8.0.27 tomcat8_2
5.1.2 修改多實例配置文件
#創建多實例的網頁根目錄
[root@localhost local]# mkdir -p /data/www/www/ROOT
#將網頁程序拷貝到,多實例根目錄ROOT下
[root@localhost local]# cp /usr/local/tomcat/webapps/memtest/meminfo.jsp /data/www/www/ROOT/
#修改多實例配置文件的以下三行
[root@localhost local]# cat -n /usr/local/tomcat/conf/server.xml | sed -n '22p;69p;123p'
22 <Server port="8005" shutdown="SHUTDOWN"> #管理端口及停止命令
69 <Connector port="8080" protocol="HTTP/1.1" #對外提供服務的端口
123 <Host name="localhost" appBase="webapps" #網站域名及網頁根目錄路徑
#修改第一個多實例配置文件
[root@localhost local]# sed -i '22s#8005#8011#;69s#8080#8081#;123s#appBase=".*"#appBase="/data/www/www"#' /usr/local/tomcat8_1/conf/server.xml
[root@localhost local]# sed -n '22p;69p;123p' /usr/local/tomcat8_1/conf/server.xml
<Server port="8011" shutdown="SHUTDOWN">
<Connector port="8081" protocol="HTTP/1.1"
<Host name="localhost" appBase="/data/www/www"
#修改第二個多實例配置文件
[root@localhost local]# sed -i '22s#8005#8012#;69s#8080#8082#;123s#appBase=".*"#appBase="/data/www/www"#' /usr/local/tomcat8_2/conf/server.xml
[root@localhost local]# sed -n '22p;69p;123p' /usr/local/tomcat8_2/conf/server.xml
<Server port="8012" shutdown="SHUTDOWN">
<Connector port="8082" protocol="HTTP/1.1"
<Host name="localhost" appBase="/data/www/www"
5.1.3 啟動多實例
#啟動多實例服務
[root@localhost ~]# /usr/local/tomcat8_1/bin/startup.sh
Using CATALINA_BASE: /usr/local/tomcat8_1
Using CATALINA_HOME: /usr/local/tomcat8_1
Using CATALINA_TMPDIR: /usr/local/tomcat8_1/temp
Using JRE_HOME: /usr/local/jdk
Using CLASSPATH: /usr/local/tomcat8_1/bin/bootstrap.jar:/usr/local/tomcat8_1/bin/tomcat-juli.jar
Tomcat started.
[root@localhost ~]# /usr/local/tomcat8_2/bin/startup.sh
Using CATALINA_BASE: /usr/local/tomcat8_2
Using CATALINA_HOME: /usr/local/tomcat8_2
Using CATALINA_TMPDIR: /usr/local/tomcat8_2/temp
Using JRE_HOME: /usr/local/jdk
Using CLASSPATH: /usr/local/tomcat8_2/bin/bootstrap.jar:/usr/local/tomcat8_2/bin/tomcat-juli.jar
Tomcat started.
#查看多實例進程啟動情況
[root@localhost ~]# netstat -antup | grep java
tcp 0 0 ::ffff:127.0.0.1:8011 :::* LISTEN 2295/java
tcp 0 0 ::ffff:127.0.0.1:8012 :::* LISTEN 2321/java
tcp 0 0 :::8080 :::* LISTEN 2031/java
tcp 0 0 :::8081 :::* LISTEN 2295/java
tcp 0 0 :::8082 :::* LISTEN 2321/java
tcp 0 0 ::ffff:127.0.0.1:8005 :::* LISTEN 2031/java
tcp 0 0 :::8009 :::* LISTEN 2031/java
瀏覽器可以分別訪問http://10.0.0.134:8081/meminfo.jsp和http://10.0.0.134:8082/meminfo.jsp
5.2 Tomcat集群
使用nginx+Tomcat反向代理集群
5.2.1 安裝nginx
[root@localhost ~]# yum -y install pcre-devel openssl-devel
[root@localhost ~]# wget -q http://nginx.org/download/nginx-1.10.2.tar.gz
[root@localhost ~]# useradd -s /sbin/nologin -M nginx
[root@localhost ~]# tar xf nginx-1.10.2.tar.gz -C /usr/src/
[root@localhost ~]# cd /usr/src/nginx-1.10.2/
[root@localhost nginx-1.10.2]# ./configure --user=nginx --group=nginx --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
[root@localhost nginx-1.10.2]# make && make install
5.2.2 修改nginx配置文件如下
#創建配置文件模版
[root@localhost nginx]# egrep -v "#|^$" /usr/local/nginx/conf/nginx.conf.default > /usr/local/nginx/conf/nginx.conf
#修改配置文件內容如下:
[root@localhost nginx]# cat /usr/local/nginx/conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream web_pools {
server 127.0.0.1:8081;
server 127.0.0.1:8082;
}
server {
listen 80;
server_name localhost;
location / {
root html;
index index.jsp index.html index.htm;
proxy_pass http://web_pools;
}
}
}
#檢測語法並啟動nginx
[root@localhost nginx]# /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@localhost nginx]# /usr/local/nginx/sbin/nginx
[root@localhost nginx]# netstat -antup | grep nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 4833/nginx
同學們自行測試負載均衡效果
5.3 使用Tomcat安裝Jpress
JPress,一個wordpress的java代替版本,使用JFinal開發。需要maven支持
[root@localhost ~]# tar xf apache-maven-3.3.9-bin.tar.gz -C /usr/local/
[root@localhost ~]# ln -s /usr/local/apache-maven-3.3.9 /usr/local/maven
[root@localhost ~]# tail -2 /etc/profile
export MAVEN_HOME=/usr/local/maven
export PATH="$MAVEN_HOME/bin:$PATH"
[root@localhost ~]# source /etc/profile
[root@localhost ~]# mvn -version #出現這個表示成功
Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-10T11:41:47-05:00)
Maven home: /usr/local/maven
Java version: 1.8.0_60, vendor: Oracle Corporation
Java home: /usr/local/jdk1.8.0_60/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "2.6.32-431.el6.x86_64", arch: "amd64", family: "unix"
將 jpress-web-newest.war包放到Tomcat網站根目錄下
#將war包放到網站根目錄下
[root@localhost ~]# ls -l jpress-web-newest.war
-rw-r--r--. 1 root root 20797013 Oct 24 17:04 jpress-web-newest.war
[root@localhost ~]# mv jpress-web-newest.war /data/www/www/ROOT/
#解壓war包
[root@localhost ~]# which jar
/usr/local/jdk/bin/jar
[root@localhost ~]# cd /data/www/www/ROOT/
[root@localhost ROOT]# jar xf jpress-web-newest.war #jar是war包的解壓命令
[root@localhost ROOT]# ls
jpress-web-newest.war META-INF static WEB-INF
meminfo.jsp robots.txt templates
用瀏覽器訪問:http://10.0.0.134/install進入jpress安裝向導
特別提示:
- 雖然,Tomcat已經打開了自動解壓縮war包的功能,但是細心的同學會發現我並沒有重啟Tomcat服務,因此,war包並沒有被自動解壓縮。故,我們需要通過jar命令進行解壓縮,命令的參數和tar是一樣的。
- 接下來我們就需要為jpress安裝數據庫了,之后的所有流程和閱讀材料LNMP的章節完全一樣。因此,我這里就不繼續操作了。
第六章 Tomcat安全優化和性能優化
6.1 安全優化
最重要的優化為如下4項,但並不止這四種
- 降權啟動
- telnet管理端口保護
- ajp連接端口保護
- 禁用管理端
具體操作如下:
(1)降權啟動(同nginx優化部分的監牢模式)
降權的原則就是利用普通用戶來啟動Tomcat
(1)將Tomcat程序目錄拷貝到普通用戶家目錄下
(2)修改家目錄下程序的配置文件(啟動端口,檢測端口等),並重新指定網頁根目錄路徑。
(3)遞歸授權拷貝后的Tomcat程序的屬主屬組為普通用戶。
(4)用su命令切換為普通用戶,啟動Tomcat進程
(5)此時Tomcat進程的權限為普通用戶權限
(6)如果利用/etc/rc.local文件配置普通用戶程序的開機啟動,那么需要利用su -c臨時切換身份啟動。具體可參考linux基礎教案里的用戶管理部分
(2)telnet管理端口保護
[root@localhost ~]# sed -n '22p' /usr/local/tomcat/conf/server.xml
<Server port="8005" shutdown="SHUTDOWN"> #表示通過8005端口來接受SHUTDOWN,用來停止Tomcat進程。默認的方式是非常危險的。需要進行修改
[root@localhost ~]# netstat -antup | grep java
tcp 0 0 ::ffff:127.0.0.1:8011 :::* LISTEN 2295/java #本地8011端口接收SHUTDOWN命令
tcp 0 0 ::ffff:127.0.0.1:8012 :::* LISTEN 2321/java #本地8012端口接收SHUTDOWN命令
tcp 0 0 :::8080 :::* LISTEN 2031/java
tcp 0 0 :::8081 :::* LISTEN 2295/java
tcp 0 0 :::8082 :::* LISTEN 2321/java
tcp 0 0 ::ffff:127.0.0.1:8005 :::* LISTEN 2031/java #本地8005端口接收SHUTDOWN命令
tcp 0 0 :::8009 :::* LISTEN 2031/java
Tomcat默認通過8005端口來接收SHUTDOWN這個字符串來關閉Tomcat進程,但這是非常危險的,因此需要修改端口號來防護。否則,通過telnet命令即可強行關閉Tomcat進程
#利用Telnet來關閉Tomcat進程
[root@localhost ~]# telnet 127.0.0.1 8005 #通過telnet連接本地8005端口
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
SHUTDOWN #發送SHUTDOWN字符串
Connection closed by foreign host.
[root@localhost ~]# netstat -antup | grep java #可以發現8005端口和8080端口的Tomcat進程沒了
tcp 0 0 ::ffff:127.0.0.1:8011 :::* LISTEN 2295/java
tcp 0 0 ::ffff:127.0.0.1:8012 :::* LISTEN 2321/java
tcp 0 0 :::8081 :::* LISTEN 2295/java
tcp 0 0 :::8082 :::* LISTEN 2321/java
[root@localhost ~]#
(3)ajp連接端口保護
[root@localhost ~]# sed -n '91p' /usr/local/tomcat/conf/server.xml
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /> #這是AJP協議打開的端口,我們並不需要開啟這個端口,因此注釋掉本行
(4)禁用管理端
Tomcat默認在安裝完成后的網頁目錄里有很多多余的目錄,刪除所有不需要用到的目錄,並清空ROOT網頁默認根目錄下的所有東西,規避可能的代碼漏洞
[root@localhost ~]# cd /usr/local/tomcat/webapps/
[root@localhost webapps]# ls
docs examples host-manager manager memtest memtest.war ROOT #有很多多余的東西,只留下ROOT目錄,其他都刪掉或者mv移走
[root@localhost webapps]# ls ROOT/ #很多多余的東西,因此清空本目錄,或者都移走
asf-logo.png bg-button.png bg-nav-item.png bg-upper.png favicon.ico meminfo.jsp tomcat.css tomcat.png tomcat.svg
asf-logo-wide.gif bg-middle.png bg-nav.png build.xml index.jsp RELEASE-NOTES.txt tomcat.gif tomcat-power.gif WEB-INF
6.2 性能優化
6.2.1 屏蔽DNS查詢 enableLookups="false"
DNS查詢非常消耗時間,如果開啟會影響Tomcat性能,因此關閉。
#默認沒有,需添加配置文件如下代碼段,在Connector標簽位置。表示禁止DNS查詢
<Connector port="8081" protocol="HTTP/1.1"
connectionTimeout="6000" enableLookups="false" acceptCount="800"
redirectPort="8443" />
6.2.2 jvm調優
Tomcat最吃內存,只要內存足夠,這只貓就跑的很快。
如果系統資源有限,那就需要進行調優,提高資源使用率。
#優化catalina.sh初始化腳本。在catalina.sh初始化腳本中添加以下代碼:
#catalina.sh的路徑為:/usr/local/tomcat/bin/catalina.sh
#此行優化代碼需要加在腳本的最開始,聲明位置。不要放在后邊
JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1024m -Xmx1024m -XX:NewSize=512m -XX:MaxNewSize=512m -XX:PermSize=512m -XX:MaxPermSize=512m"
#代碼說明:
server:一定要作為第一個參數,在多個CPU時性能佳
-Xms:初始堆內存Heap大小,使用的最小內存,cpu性能高時此值應設的大一些
-Xmx:初始堆內存heap最大值,使用的最大內存
上面兩個值是分配JVM的最小和最大內存,取決於硬件物理內存的大小,建議均設為物理內存的一半。
-XX:PermSize:設定內存的永久保存區域
-XX:MaxPermSize:設定最大內存的永久保存區域
-XX:MaxNewSize:
-Xss 15120 這使得JBoss每增加一個線程(thread)就會立即消耗15M內存,而最佳值應該是128K,默認值好像是512k.
+XX:AggressiveHeap 會使得 Xms沒有意義。這個參數讓jvm忽略Xmx參數,瘋狂地吃完一個G物理內存,再吃盡一個G的swap。
-Xss:每個線程的Stack大小
-verbose:gc 現實垃圾收集信息
-Xloggc:gc.log 指定垃圾收集日志文件
-Xmn:young generation的heap大小,一般設置為Xmx的3、4分之一
-XX:+UseParNewGC :縮短minor收集的時間
-XX:+UseConcMarkSweepGC :縮短major收集的時間
JVM的調優比較復雜,對於初學的同學們來說掌握這些就足夠了。如果想要更詳細的理解JVM如何調優,那么請參考網友文章:http://www.cnblogs.com/xingzc/p/5756119.html
附錄1:企業案例:Linux下java/http進程高解決案例
生產環境下某台tomcat7服務器,在剛發布的時候一切都很正常,在運行一段時間后就出現CPU占用很高的問題,基本上是負載一天比一天高。諸如此類問題,請排查!
問題分析:
(1)程序屬於CPU密集型,和開發溝通過,排除此類情況
(2)程序代碼有問題,出現死循環,可能性極大
問題解決:
(1)開發那邊無法排查代碼某個模塊有問題,從日志上也無法分析得出
(2)我們可以嘗試通過jstack命令來精確定位出現錯誤的代碼段,從而拿給開發排查。
(1)首先查找進程高的PID號(先找到是哪個PID號的進程導致的)
top -H
(2)查看這個進程所有系統調用(再找到是哪個PID號的線程導致的)
strace -p 進程的PID
(3)如果是Web應用,可以繼續打印該線程的堆棧信息(找出有問題的代碼塊)
printf "%x\n" 線程的PID
--->#將有問題的線程的PID號轉換成16進制格式
jstack 進程的PID | grep 線程PID號的十六進制格式 -A 30
#過濾出有問題的線程的堆棧信息,找出問題代碼塊
實際操作演示:
[root@localhost ROOT]# pgrep -l java
2031 java #java進程及對應PID號
2295 java
2321 java
[root@localhost ROOT]# strace -p 2031 #查看PID號為2031的java進程的所有線程調用情況
Process 2031 attached - interrupt to quit
futex(0x7f4cdd0e79d0, FUTEX_WAIT, 2032, NULL #只有一個線程,線程的PID號為2032
^C <unfinished ...>
Process 2031 detached
[root@localhost ROOT]# printf "%x\n" 2032 #將線程的PID號2032轉換成十六進制格式
7f0
[root@localhost ROOT]# jstack 2031 | grep 7f0 -A 30 #追蹤進稱號為2031的進程的所有線程調用,從里面過濾出16進制為7f0的線程的代碼調用情況
"main" #1 prio=5 os_prio=0 tid=0x00007f4cd4008800 nid=0x7f0 runnable [0x00007f4cdd0e5000]
java.lang.Thread.State: RUNNABLE
at java.net.PlainSocketImpl.socketAccept(Native Method)
at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409) #圓括號里顯示的是(代碼類名:具體調用的代碼行號)
at java.net.ServerSocket.implAccept(ServerSocket.java:545)
at java.net.ServerSocket.accept(ServerSocket.java:513)
at org.apache.catalina.core.StandardServer.await(StandardServer.java:446)
at org.apache.catalina.startup.Catalina.await(Catalina.java:713)
at org.apache.catalina.startup.Catalina.start(Catalina.java:659)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:351)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:485)
"VM Thread" os_prio=0 tid=0x00007f4cd406d000 nid=0x7f1 runnable
"VM Periodic Task Thread" os_prio=0 tid=0x00007f4cd40b8800 nid=0x7f8 waiting on condition
JNI global references: 244
附錄2:jstack命令(Java stack Trace)
(1)介紹
- jstack用於打印出給定的java進程ID或core file或遠程調試服務的Java堆棧信息,如果是在64位機器上,需要指定選項"-J-d64",Windows的jstack使用方式只支持以下的這種方式:
jstack [-l] pid- 如果java程序崩潰生成core文件,jstack工具可以用來獲得core文件的java stack和native stack的信息,從而可以輕松地知道java程序是如何崩潰和在程序何處發生問題。另外,jstack工具還可以附屬到正在運行的java程序中,看到當時運行的java程序的java stack和native stack的信息, 如果現在運行的java程序呈現hung的狀態,jstack是非常有用的。
(2)命令格式
jstack [ option ] pid
jstack [ option ] executable core
jstack [ option ] [server-id@]remote-hostname-or-IP
(3)常用參數說明
1)、options:
executable Java executable from which the core dump was produced.
(可能是產生core dump的java可執行程序)
core 將被打印信息的core dump文件
remote-hostname-or-IP 遠程debug服務的主機名或ip
server-id 唯一id,假如一台主機上多個遠程debug服務
2)、基本參數:
-F:當’jstack [-l] pid’沒有相應的時候強制打印棧信息
-l:長列表. 打印關於鎖的附加信息,例如屬於java.util.concurrent的ownable synchronizers列表.
-m:打印java和native c/c++框架的所有棧信息.
-h | -help:打印幫助信息
pid :需要被打印配置信息的java進程id,可以用jps查詢.