tomcat企業級Web應用伺服器配置與實戰 環境背景:公司業務經過長期發展,有了很大突破,已經實現盈利,現公司要求加強技術架構應用功能和安全性以及開始向企業應用、移動APP等領域延伸,此時原來開發web服務的php語言已經不適應新的場景,需要上java技術架構,現要求你根據公司需要,實現基於jav ...
環境背景:公司業務經過長期發展,有了很大突破,已經實現盈利,現公司要求加強技術架構應用功能和安全性以及開始向企業應用、移動APP等領域延伸,此時原來開發web服務的php語言已經不適應新的場景,需要上java技術架構,現要求你根據公司需要,實現基於java平臺的web應用服務選型、搭建、實現和應用,此時你如何選擇?
項目實戰系列,總架構圖 http://www.cnblogs.com/along21/p/8000812.html
本篇實戰所需的包,都存放在我的網盤中 http://pan.baidu.com/s/1c2B7BO0,需要的私聊我。
實戰一:在linux上,安裝tomcat
1、下載安裝java所需要的環境和開發工具包
JRE顧名思義是java運行時環境,包含了java虛擬機,java基礎類庫。是使用java語言編寫的程式運行所需要的軟體環境,是提供給想運行java程式的用戶使用的。
JDK顧名思義是java開發工具包,是程式員使用java語言編寫java程式所需的開發工具包,是提供給程式員使用的。JDK包含了JRE,同時還包含了編譯java源碼的編譯器javac,還包含了很多java程式調試和分析的工具:jconsole,jvisualvm等工具軟體,還包含了java程式編寫所需的文檔和demo例子程式。如果你需要運行java程式,只需安裝JRE就可以了。如果你需要編寫java程式,需要安裝JDK。JRE根據不同操作系統(如:windows,linux等)和不同JRE提供商(IBM,ORACLE等)有很多版本,最常用的是Oracle公司收購SUN公司的JRE版本。
(2)安裝相應版本的rpm包 jdk-VERSION-OS-ARCH.rpm
yum -y localinstall jdk-8u144-linux-x64.rpm
centos7系統自帶:jdk-1.8.0_25-linux-x64.rpm
export JAVA_HOME=/usr/java/jdk1.8.0_144 export JRE_HOME=$JAVA_HOME/jre export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
2、下載安裝tomcat
(1)從官網下載tomcat二進位安裝包 http://tomcat.apache.org/
https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.23/bin/
tar xvf apache-tomcat-8.5.11.tar.gz -C /usr/local/
② 為了方便管理,設置軟連接,若以後換版本了,可以很容易切換
ln -s /usr/local/apache-tomcat-7.0.78/ /usr/local/tomcat
export CATALINA_BASE=/usr/local/tomcat export PATH=$CATALINA_BASE/bin:$PATH source /etc/profile.d/tomcat.sh 執行載入環境配置
yum install tomcat -y #安裝tomcat主程式 yum install -y tomcat-admin-webapps tomcat-docs-webapp tomcat-webapps #安裝tomcat對應的頁面 mkdir /var/lib/tomcat/webapps/{ROOT,test}/{WEB-INF,META-INF,classes,lib} -pv #創建頁面所需要的工作目錄
webapps存放位置:/var/lib/tomcat/webapps/
環境配置文件:/etc/sysconfig/tomcat #調整jdk記憶體使用大小等初始值
3、啟動tomcat
實戰二:基於tomcat佈署一個開源java產品
1、去網上下載開源Java 代碼
可以去開源中國下載自己需要的https://www.oschina.net/
我已經下好一個,需要的私密我http://pan.baidu.com/s/1c2B7BO0
2、解包、佈署和查看使用說明
① unzip zchuanzhao-jeesns-master.zip
② mv /jeesns/war/jeesns.war .../webapps 把jeesns.war移到你的tomcat的webapps 下
如果你是自動佈署,會自動在/webapps 下生成jeesns目錄;若不是,可以自己unzip 解包,佈署
3、同步數據到資料庫
MariaDB [(none)]> create database along;
cd /jeesns/jeesns-web/database/
mysql -uroot -p -D along < jeesns.sql
4、修改資料庫連接
vim /webapps/jeesns/WEB-INF/classes/jeesns.properties
5、訪問頁面,佈署成功
① 登錄首頁 http://192.168.30.107:8080/jeesns
② 進入後臺管理 http://192.168.30.107:8080/jeesns/manage/login
實戰三:實現LNMT,nginx代理tomcat
1、直接在nginx 上設置跳轉
location / { proxy_pass http://192.168.30.107:8080; } location ~* \.(jsp|do)$ { proxy_pass http://192.168.30.107:8080; }
2、訪問測試,http://192.168.30.107/
3、實現集群代理服務
upstream tomcat_srv { server 192.168.30.107:8080 weight=1; server 192.168.30.7:8080 weight=2; }
location / { proxy_pass http://tomcat_srv; } location ~* \.(jsp|do)$ { proxy_pass http://tomcat_srv; }
<%@ page language="java" %> <%@ page import="java.util.*" %> <html> <head> <title>Test Page</title> </head> <body> <% out.println("hello world");%> </body> </html>
<%@ page language="java" %> <%@ page import="java.util.*" %> <html> <head> <title>Test Page</title> </head> <body> <% out.println("hello world2");%> </body> </html>
實戰四:LNMT的會話保持原理及基於ip_hash實現
1、原理:有三種類型的方法,實現會話保持的方法
(1) session sticky(貼) 基於hash 和cookie 來實現會話保持,簡單的負載均衡演算法
nginx: ip_hash 、 haproxy: source 、 lvs: sh
② 基於cookie nginx基於cookie實現,需載入cookie模塊,cookie 力度更新
(2) session cluster:delta session manager 基於tomcat集群會話保持
分析:tomcat自身帶的機制 session cluster,基於組播的方式,一個tomcat 被用戶登錄訪問,記錄session;通過組播給集群中的其他機器複製一份;那麼當用戶再次訪問時,每個機器都有session 會話記錄;從而實現了會話保持
(3) session server:redis(store), memcached(cache) 共用存儲
分析:新建立一個存放各個tomcat session記錄的server,每台tomcat伺服器都將自己的session記錄在這個伺服器中,用戶再次訪問,每台tomcat 都從這個server中獲取;實現會話保持
2、簡單實現基於ip hash 實現會話保持
vim /etc/nginx/nginx.conf 只需加一條ip_hash即可
upstream tomcat_srv { ip_hash; server 192.168.30.107:8080 weight=1; server 192.168.30.7:8080 weight=2; }
3、測試
訪問頁面,一直匹配到107的server 上,沒有輪詢;會話保持成功
實戰四:基於tomcat會話集群實現LNMT的會話保持
原理:Tomcat集群的會話管理器,它通過將改變了會話數據同步給集群中的其它節點實現會話複製。這種實現會將所有會話的改變同步給集群中的每一個節點
機器名稱 |
IP配置 |
服務角色 |
備註 |
nginx |
192.168.30.107 |
代理伺服器 |
開啟代理功能 |
tomcat-srv1 |
192.168.30.106 |
web服務 |
配置集群會話 |
tomcat-srv2 |
192.168.30.7 |
web服務 |
配置集群會話 |
2、配置nginx代理
upstream tomcat_srv { #在http 段配置 server 192.168.30.106:8080 weight=1; server 192.168.30.7:8080 weight=2; } location / { #在server 段配置 proxy_pass http://tomcat_srv; } location ~* \.(jsp|do)$ { proxy_pass http://tomcat_srv; }
3、tomcat 集群會話的配置
註意:兩台tomcat-srv的配置是一模一樣的,除了測試的頁面設置不同
cd /usr/local/tomcat/ 進入自己的tomcat 的目錄下
vim conf/server.xml 在Engine 引擎段中,添加下麵代碼,註意:註釋千萬別加去
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8"> 定義集群節點,“8”表示非同步 <Manager className="org.apache.catalina.ha.session.DeltaManager" 定義Manger採用DeltaManager 會話管理器 expireSessionsOnShutdown="false" 一個節點關閉,不影響集群其他session notifyListenersOnReplication="true"/> 複製、刪除操作通知session listener <Channel className="org.apache.catalina.tribes.group.GroupChannel"> <Membership className="org.apache.catalina.tribes.membership.McastService" address="228.0.0.4" port="45564" frequency="500" dropTime="3000"/> <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="auto" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6"/> <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> </Sender> <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/> <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/> </Channel> <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter="/"/> <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> </Cluster>
4、配置註釋
(1)Cluster配置:
Cluster(集群,族) 節點,如果你要配置tomcat集群,則需要使用此節點.
className 表示tomcat集群時,之間相互傳遞信息使用那個類來實現信息之間的傳遞.
channelSendOptions可以設置為2、4、8、10,每個數字代表一種方式
2 = Channel.SEND_OPTIONS_USE_ACK(確認發送)
4 = Channel.SEND_OPTIONS_SYNCHRONIZED_ACK(同步發送)
8 = Channel.SEND_OPTIONS_ASYNCHRONOUS(非同步發送)
在非同步模式下,可以通過加上確認發送(Acknowledge)來提高可靠性,此時channelSendOptions設為10,半同步
例:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8">
(2)Manager
Manger對象用於實現HTTP會話管理的功能,Tomcat中有4種Manger的實現:
Tomcat6的預設會話管理器,用於非集群環境中對單個處於運行狀態的Tomcat實例會話進行管理。當Tomcat關閉時,這些會話相關的數據會被寫入磁碟上的一個名叫SESSION.ser的文件,併在Tomcat下次啟動時讀取此文件。
當一個會話長時間處於空閑狀態時會被寫入到swap會話對象,這對於記憶體資源比較吃緊的應用環境來說比較有用。
用於Tomcat集群的會話管理器,它通過將改變了會話數據同步給集群中的其它節點實現會話複製。這種實現會將所有會話的改變同步給集群中的每一個節點,也是在集群環境中用得最多的一種實現方式。
用於Tomcat集群的會話管理器,與DeltaManager不同的是,某節點會話的改變只會同步給集群中的另一個而非所有節點
className-指定實現org.apache.catalina.ha.ClusterManager介面的類,信息之間的管理
expireSessionsOnShutdown-設置為true時,一個節點關閉,將導致集群下的所有Session失效
notifyListenersOnReplication-集群下節點間的Session複製、刪除操作,是否通知session listeners
(3)Channel 頻道的介紹和配置
Channel是Tomcat節點之間進行通訊的工具。Channel包括4個組件:
① Membership:維護集群的可用節點列表,它可以檢查到新增的節點,也可以檢查到沒有心跳的節點
⑤ frequency-發送心跳(向組播地址發送UDP數據包)的時間間隔(單位:ms)。預設值為500
⑥ dropTime-Membership在dropTime(單位:ms)內未收到某一節點的心跳,則將該節點從可用節點列表刪除。預設值為3000
註:組播(Multicast):一個發送者和多個接收者之間實現一對多的網路連接。
一個發送者同時給多個接收者傳輸相同的數據,只需複製一份相同的數據包。
<Membership className="org.apache.catalina.tribes.membership.McastService" address="228.0.0.4" port="45564" frequency="500" dropTime="3000"/>
接收器分為兩種:BioReceiver(阻塞式)、NioReceiver(非阻塞式)
className-指定Receiver使用的類
address-接收消息的地址
port-接收消息的埠
autoBind-埠的變化區間
如果port為4000,autoBind為100,接收器將在4000-4099間取一個埠,進行監聽
selectorTimeout-NioReceiver內輪詢的超時時間
maxThreads-線程池的最大線程數
<Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="auto" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6"/>
Sender內嵌了Transport組件,Transport真正負責發送消息
Transport分為兩種:bio.PooledMultiSender(阻塞式)、nio.PooledParallelSender(非阻塞式)
<Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> </Sender>
① TcpFailureDetector-網路、系統比較繁忙時,Membership可能無法及時更新可用節點列表,此時TcpFailureDetector可以攔截到某個節點關閉的信息,並嘗試通過TCP連接到此節點,以確保此節點真正關閉,從而更新集群可以用節點列表
② MessageDispatch15Interceptor-查看Cluster組件發送消息的方式是否設置為Channel.SEND_OPTIONS_ASYNCHRONOUS(Cluster標簽下的channelSendOptions為8時)。 設置為Channel.SEND_OPTIONS_ASYNCHRONOUS時,MessageDispatch15Interceptor先將等待發送的消息進行排隊,然後將排好隊的消息轉給Sender
<Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/> <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
(4)ClusterListener 配置
ClusterListener : 監聽器,監聽Cluster組件接收的消息
使用DeltaManager時,Cluster接收的信息通過ClusterSessionListener傳遞給DeltaManager
<ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
5、創建測試頁面
cp /usr/local/tomcat/conf/web.xml WEB-INF/
vim WEB-INF/web.xml 在</web-app>上加一行
② vim session.jsp 創建測試頁面,在tomcat-srv1上是TomcatA;在tomcat-srv1上是TomcatB
<%@ page language="java" %> <html> <head><title>TomcatA</title></head> //TomcatA的標題 <body> <h1><font color="blue">TomcatA </h1> <table align="centre" border="1"> <tr> <td>Session ID</td> <% session.setAttribute("abc","abc"); %> <td><%= session.getId() %></td> </tr> <tr> <td>Created on</td> <td><%= session.getCreationTime() %></td> </tr> </table> </body> </html>
6、測試
頁面訪問http://192.168.30.107/test/session.jsp;輪詢,但是session ID是一樣的,會話保持成功
實戰五:基於共用存儲實現LNMT的會話保持
原理:新建立一個存放各個tomcat session記錄的server,每台tomcat伺服器都將自己的session記錄在這個伺服器中,用戶再次訪問,每台tomcat 都從這個server中獲取;實現會話保持
1、環境準備
機器名稱 |
IP配置 |
服務角色 |
備註 |
nginx |
192.168.30.107 |
代理伺服器 |
開啟代理功能 |
tomcat-srv1 |
192.168.30.106 |
web服務 |
指向共用存儲 |
tomcat-srv2 |
192.168.30.7 |
web服務 |
指向共用存儲 |
memcached |
192.168.30.6 |
共用存儲 |
|
2、下載提供,實驗所依賴的.jar包
memcached-session-manager項目地址,http://code.google.com/p/memcached-session-manager/, https://github.com/magro/memcached-session-manager
① 下載如下jar文件至各tomcat節點的tomcat安裝目錄下的lib目錄中,尋找自己需要的版本號,tc的版本號要與tomcat版本相同。
memcached-session-manager-1.8.3.jar
memcached-session-manager-tc7-1.8.3.jar
spymemcached-2.11.1.jar
msm-javolution-serializer-1.8.3.jar
javolution-5.4.3.1.jar
我已經下到了我的網盤,有需要的私聊 http://pan.baidu.com/s/1nvGFgKD
3、配置nginx代理
upstream tomcat_srv { #在http 段配置 server 192.168.30.106:8080 weight=1; server 192.168.30.7:8080 weight=2; } location / { #在server 段配置 proxy_pass http://tomcat_srv; } location ~* \.(jsp|do)$ { proxy_pass http://tomcat_srv; }
4、在server.xml 中配置
vim /usr/local/tomcat/conf/server.xml
<Context path="/test" docBase="test" reloadable="true"> <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" memcachedNodes="192.168.30.106:11211" requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$" transcoderFactoryClass="de.javakaffee.web.msm.serializer.javolution.JavolutionTranscoderFactory"/> </Context>
5、和上實驗一樣,創建測試頁面並測試
頁面訪問http://192.168.30.107/test/session.jsp;輪詢,但是session ID是一樣的,會話保持成功