Tomcat
部署Tomcat環境
環境准備
linux: CentOS 7.3
tomcat: 9.0.0.M21
jdk: 1.8.0_131
ip: 192.168.1.5
tomcat官方下載地址
http://tomcat.apache.org/download-90.cgi
下載tomcat
# cd /usr/local/src
# wget -c http://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-9/v9.0.0.M21/bin/apache-tomcat-9.0.0.M21.tar.gz
添加tomcat的用戶並設置密碼
# useradd -u 601 tomcat
# echo "tomcat" | passwd --stdin tomcat
解壓tomcat的tar包
# tar -zxvf apache-tomcat-9.0.0.M21.tar.gz
移動tomcat到目錄/usr/local下
# mv /usr/local/src/apache-tomcat-9.0.0.M21 /usr/local
最佳實踐方式,軟連接
# ln -sv /usr/local/apache-tomcat-9.0.0.M21/ /usr/local/tomcat
下載JDK的tar包(jdk-8u131-linux-x64.tar.gz)下載到到/usr/local/src目錄中
官方下載地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
解壓JDK的壓縮包
# tar -zxvf jdk-8u131-linux-x64.tar.gz
移動JDK的目錄到/usr/local下
# mv /usr/local/src/jdk1.8.0_131/ /usr/local
最佳實踐方式,創建軟連接
# ln -sv /usr/local/jdk1.8.0_131/ /usr/local/jdk
設置java所需要的運行環境
# cd /etc/profile.d/
# vim tomcat.sh
添加如下內容
export JAVA_HOME=/usr/local/jdk
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib/tools.jar
export TOMCAT_HOME=/usr/local/tomcat
讓tomcat的配置腳本生效
# source /etc/profile.d/tomcat.sh
監測java的環境
# java -version
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
更改jdk及tomcat目錄的屬主屬組
# chown -R tomcat:tomcat /usr/local/jdk/
# chown -R tomcat:tomcat /usr/local/tomcat/
切換到tomcat用戶
# su -l tomcat
啟動tomcat服務
/usr/local/tomcat/bin/startup.sh
tomcat的默認根路徑(生產的代碼)
/usr/local/tomcat/webapps
編輯tomcat的訪問控制xml配置文件
# vim /usr/local/tomcat/conf/tomcat-users.xml
在配置文件中添加用戶tomcat,並設置密碼為1qazxsw2,這樣就可以訪問manager-gui和admin-gui的管理界面了
<role rolename="manager-gui" />
<role rolename="admin-gui" />
<user username="tomcat" password="1qazxsw2" roles="manager-gui,admin-gui" />
重啟tomcat服務
# /usr/local/tomcat/bin/shutdown.sh
# /usr/local/tomcat/bin/startup.sh
這個時候如果是通過其他主機去訪問tomcat的manager管理界面(為了安全考慮,默認是只允許主機訪問),是無法使用的,我們需要再次修改一丟丟的內容
# vim /usr/local/tomcat/webapps/manager/META-INF/context.xml
修改allow的內容如下
allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1|\d+\.\d+\.\d+\.\d+"
瀏覽器可以去訪問我們的tomcat服務的管理頁面了
http://192.168.1.5:8080/manager/html
創建管理tomcat的啟動關閉狀態腳本
vim /usr/bin/tomcat.sh
添加如下內容
#!/bin/bash
TomcatPath=/usr/local/tomcat
usage() {
echo "Usage:$0 [start|stop|status|restart]"
}
start_tomcat(){
/usr/local/tomcat/bin/startup.sh
}
stop_tomcat() {
TomcatPid=$(ps -aux | grep 'java' | grep 'tomcat' | grep -v 'grep' | awk '{print $2}')
kill -9 $TomcatPid
sleep 5;
TomcatStat=$(ps -aux | grep 'java' | grep 'tomcat' | grep -v 'grep' | awk '{print $2}') >> /dev/null
if [ -z $TomcatStat ];then
echo -e "\033[31mtomcat stoping..\033[0m"
else
kill -9 $TomcatStat
fi
cd $TomcatPath
rm -rf temp/*
rm -rf work/*
}
stat_tomcat() {
TomcatStat=$(ps -aux | grep 'java' | grep 'tomcat' | grep -v 'grep') >> /dev/null
if [ -z $TomcatStat ];then
echo -e "\033[31mtomcat stop..\033[0m"
else
echo -e "\033[32mtomcat running...\033[0m"
fi
}
main(){
case $1 in
start)
start_tomcat;;
stop)
stop_tomcat;;
restart)
stop_tomcat && start_tomcat;;
status)
stat_tomcat;;
*)
usage;;
esac
}
main $1
更改腳本的屬組屬組並添加運行權限
# chown tomcat:tomcat /usr/bin/tomcat.sh
# chmod +x /usr/bin/tomcat.sh
測試下寫的tomcat的腳本
# tomcat status
Tomcat的安全管理規范
1. telnet管理端口保護
8005為管理端口,可以通過telnet連接執行SHUTDOWN即可關閉服務,不安全,我們需要換一個其他人未知的端口並調整關閉命令,我們需要做調成
# vim /usr/local/tomcat/conf/server.xml
<Server port="8561" shutdown="dangerous">
2. ajp連接端口的保護,注釋掉ajp
# vim /usr/local/tomcat/conf/server.xml
<!--Connector port="8009" protocol="AJP/1.3" redirectPort="8443" /-->
Tomcat使用遠程監測工具
windows下載並安裝jdk,使用jconsole就可以監控tomcat的狀態
http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
修改tomcat服務端的配置
# vim /usr/local/tomcat/bin/catalina.sh
在第二行添加如下內容
CATALINA_OPTS="$CATALINA_OPTS -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=12345 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=192.168.1.5"
利用jdk中的jconsole實現遠程管理tomcat
使用jvisualvm監控tomcat
JVM原理及調優
-
什么是jvm?
虛擬機、字節碼、跨平台
-
jvm結構
-
JVM運行時的數據區
- 程序計數器-------->線程私有
- Java虛擬機棧----->線程私有
- 本地方法棧-------->線程私有
- Java堆-------------->線程公用
- 方法區-------------->線程公用
-
jVM結構圖
-
jvm內存分配
棧內存分配
1. 保存參數、局部變了、中間計算過程和其他數據,退出方法的時候,修改棧頂指針就可以把棧幀中的內容銷毀 2. 棧的優點:存儲速度比堆快,僅次於寄存器,棧數據可以共享 3. 棧的缺點:存在棧中的數據大小,生存期是在編譯時候就確定的,導致其缺乏靈活性
堆內存分配
1. 堆的優點:動態分配內存大小,生存期不必實現告訴編譯器,它是在運行期動態分配的,垃圾回收器會自動收走不再使用的空間區域 2. 堆的缺點:運行動態分配內存,在分配和銷毀時都要占用時間,因此堆效率較低
-
jvm堆配置參數
1. -Xms初始堆大小 默認物理內存的1/64(<1GB) 2. -Xmx最大堆大小 默認物理內存的1/4(<1GB),實際中建議不大於4GB 3. 一般建議設置-Xms=-Xmx 好處是避免每次在gc后,調整堆的大小,減少系統內存分配開銷 4. 整個堆大小=年輕代大小+年老代大小+持久化大小
-
jvm新生代(young generation)
1. 新生代=1個eden區+2個Survior區 2. -Xmn 年輕代大小(1.4or lator) -XX:NewSize,-XX:MaxNewSize(設置年輕代大小(for 1.3/1.4)) 默認值大小為整個堆的3/8 3. -XX:NewRatio 年輕代(包含Eden和兩個Survivor區)與老年代的比值(除去持久化) Xms=Xmx並且設置了Xmn的情況下,該參數不需要設置 4. -XX:SurviorRatio Eden區與Survivor區的大小比值,設置為8,則兩個Survivor區與一個Eden區的比值為2:8,一個Survivor區占整個年輕代的1/10 5. 用來存放JVM剛分配的Java對象
-
jvm老年代(tenured greneration)
1. 老年代=整個堆-年輕代大小-持久化大小 2. 年輕代中經過垃圾回收沒有回收掉的對象被復制到年老代 3. 老年代存儲對象比年輕代年齡大的多,而且不發達對象(緩存) 4. 新建的對象也有可能直接進入老年代 4.1、大對象,可通過啟動參數設置-XX:PretenureSizeThreshold=1024(單位為字節,默認為0)來代表超過多大時就不再新生代分配,而是直接在老年代分配 4.2、大的數組對象,切數組中無引用外部對象 5. 老年代大小無配置參數
-
java持久代(perm generation)
1. 持久代=整個堆-年輕代大小-老年代大小 2. -XX:PermSize -XX:MaxPermSize 設置持久代的大小,一般情況推薦把-XX:PermSize設置成XX:MaxPermSize的值為相同的值,因為永久代的調整也會導致堆內存需要觸發fgc(Full GC) 3. 存放Class,Method元信息,其大小與項目的規模、類、方法的數量有關。一般設置為128M就夠用,設置原則是預留30%的空間 4. 永久代的回收方式 4.1、常量池的常量,無用的類信息,常量的回收很簡單,沒有引用的就可以被回收 4.2、對無用的類進行回收,必須保證3點: 類的所有實例都已經被回收 加載類的ClassLoader已經被回收 類對象的Class對象沒有被引用(既沒有通過反射引用該類的方法)
-
jvm內存垃圾收集算法
1. 引用計數器 每個對象有一個引用計數器,新增一個引用時計數加1,引用釋放時計數減1,技術為0時可以回收。此方法簡單,無法解決對象相互循環引用的問題,還有一個問題是如何解決精准計數 2. 根搜索法 從GC Roots開始向下搜搜,搜索所走過的路徑成為引用鏈,當一個對象到GC Roots對任何引用鏈相連時,則證明此對象不可用的,不可達對象 在Java語言中,GC Roots包含: 虛擬機棧中引用對象 方法區中類靜態屬性實時引用的對象 方法區中常量引用的對象 本地方法棧中JNI引用的對象 3. 復制算法(Copying) 復制算法采用從根結合掃描,並將存貨對象復制到一塊新的,沒有使用過的空間中,這種算法當控件存貨的對象比較少時,極為高效,但是帶來的成本是需要一塊內存交換空間用於進行對象的移動 注意: 此算法用於新生代內存回收,從E區回收到S0或者S1 4. 標記清除算法(Mark-Sweep) 標記-清除算法采用從根集合進行掃描,對存貨的對象標記,標記完畢后,在掃描整個空間中未被標記的對象,進行回收,標記清楚算法不需要進行對象的移動,並且僅對不存貨的對象進行處理,在存貨對象比較多的情況下極為高效,但由於標記-清除算法會受不存活的對象,因此會造成內存碎片(適用於old區域) 5. 標記壓縮壓縮算法(Mark-Compac) 標記-整理算法采用標記-清除算法一樣的方法進行對象的標記,但是在清除的時不同,在回收不存活的對象占用的空間后,會將所有的存活對象往左端的空間移動,並更新對應的指針,因此成本高,但是卻解決了內存碎片的問題(old區域)
-
名詞解釋
1. 串行回收 GC單線程內存回收,會暫停所有用戶線程 2. 並行回收 手機是指多個GC線程並行工作,蛋姿勢用戶線程是暫停的,所以,Serial是串行的,Parallel收集是並行的,而CMS手機是並發的 3. 並發回收 指用戶線程與GC線程同時執行(不一定是並行,可能是交替,蛋總體上是在同時執行的),不需要停頓用戶線程(其實在CMS中用戶線程還是需要停頓的,只是非常的短暫,GC線程是在另一個CPU上執行)
-
CMS(並發標記清除)回收器
1. 標記-清除算法 同時它又是一個使用多線程並發回收的垃圾回收期 2. -XX:ParallelCMSThreads 手工設置CMS的線程數量,CMS默認啟動的線程數為(ParallelCGThread+3)/4 3. -XX:+UseConcMarkSweepCG開啟 使用過ParNew+CMS+Serial Old的收集器組合進行內存回收,Serial Old作為CMS出現"Concurrent Mode Failure"失敗后的后背收集器使用 4. -XX:CMSInitiatingOccupancyFration 設置CMS收集器在老年代空間被使用多少后觸發垃圾收集,默認為68%,僅在CMS收集器時有效,-XX:CMSInitiatingOccupancyFration=70 5. -XX:+UseCMSCompactAtFullCollection 用於CMS收集器會產生碎片,此參數設置在垃圾收集器后是否需要一次內存碎片整理過程,僅在CMS收集時有效 6. -XX:+CMSFullCGBeforeCompaction 設置CMS收集器在進行若干次垃圾收集后在進行一次內存碎片整理過程,通常與UseCMSCompactATFullCollection參數一起使用 7. -XX:CMSInitiatingPermOccupancyFraction 設置Perm Gen使用達到多少比率時觸發,默認為92%