tomcat是Apache軟件基金會的Jakarta項目中的核心項目,最新的Servlet和JSP規範可以在Tomcat中很好的表現。做爲一個免費的開放源代碼的Web應用服務器,屬於輕量級的應用服務器,在中小型系統和併發量不是很大的場景下被普遍使用,是開發和調試JSP代碼的首選。實際上而言,tomcat是Apache服務器的拓展,可是能夠獨立運行,tomcat能夠獨立的去處理html和jsp頁面。
css
Memcached 是一個高性能的分佈式內存對象緩存系統,用於動態Web應用以減輕數據庫負載。它經過在內存中緩存數據和對象來減小讀取數據庫的次數,從而提升動態、數據庫驅動網站的速度。Memcached基於一個存儲鍵/值對的hashmap。其守護進程(daemon )是用C寫的,可是客戶端能夠用任何語言來編寫,並經過memcached協議與守護進程通訊。這裏主要是作爲tomcat的session存儲設備。
html
在計算機中,尤爲是在網絡應用中,稱爲「會話控制」。Session 對象存儲特定用戶會話所需的屬性及配置信息。這樣,當用戶在應用程序的 Web 頁之間跳轉時,存儲在 Session 對象中的變量將不會丟失,而是在整個用戶會話中一直存在下去。當用戶請求來自應用程序的 Web 頁時,若是該用戶尚未會話,則 Web 服務器將自動建立一個 Session 對象。當會話過時或被放棄後,服務器將終止該會話。前端
在現今的互聯網架構中會話保持愈來愈重要,可是會話的保持卻在必定程度上依賴於提供服務的服務器上,隨着併發量的不斷提高,服務器最終會因爲負載太高而宕機,所以引入了負載均衡機制,可是負載均衡的調度會使得同一用戶的請求被調度到不一樣的主機之上,會嚴重的影響到session的保存。
java
這裏打算實現兩種session會話的保持方案。
一.Tomcat自身的session複製集羣方案;
二.Tomcat+memcached的共享session保持方案。
linux
ip地址 | 操做系統 | |
---|---|---|
nginx代理 | 192.168.99.131 | CentOS7.4 |
tomcat1 | 192.168.99.130 | CentOS7.4 |
tomcat2 | 192.168.99.240 | CentOS7.4 |
環境配置:
清空防火牆規則,關閉selinux,安裝jdknginx
#清空防火牆規則 iptables -F iptables -X #臨時設置關閉selinux setenforce 0 #安裝jdk,centos7的源默認最高支持jdk1.8 yum install java-1.8.0-openjdk-devel -y
在<engine>或者<host>配置啓用集羣,使用Delta Manager to replicate session deltas 啓用全部的會話複製。經過all-to-all,意味着會話會被複制到進羣中的其餘全部節點,這樣是設計適用於較小的集羣,可是,並不建議在較大的集羣上去部署,在使用delta管理器的時候,它將會複製到全部的節點上,甚至是尚未部署應用程序的節點。官方默認提供了一個backupManager的管理器,這個管理器的做用是僅僅將會話數據複製到一個備份節點上,並且,僅僅複製到已經部署了應用的節點,可是這個管理器目前仍在測試階段,不能保證其正常運行。
web
1.安裝nginx並設置代理數據庫
#安裝nginx,nginx在epel源,所以未安裝epel源的話要先安裝epel源 yum instll nginx -y
2.修改默認的nginx配置文件apache
vim /etc/nginx/nginx.conf
3.編輯代理配置文件vim
vim /etc/nginx/conf.d/proxy.conf upstream web { server 192.168.99.130:80; server 192.168.99.240:80; } server { listen 80 default_server; index index.jsp index.html; server_name douma.com; location / { proxy_pass http://web; } }
4.檢查語法並啓動nginx
#檢查語法 nginx -t #檢查無誤後啓動nginx systemctl start nginx
1.安裝tomcat以及對應的其餘管理工具
yum install tomcat tomcat-lib tomcat-admin-webapps tomcat-webapps tomcat-docs-webapp -y
2.配置tomcat顯示session會話信息
mkdir -pv /appdata/webapps/ROOT/{lib,classes,WEB-INF} #編寫session會話顯示頁 vim /appdata/webapps/ROOT/index.jsp <%@ page language="java" %> <html> <head><title>TomcatA</title></head> <body> <h1><font color="red">TomcatA</font></h1> <table align="centre" border="1"> <tr> <td>Session ID</td> <% session.setAttribute("magedu.com","magedu.com"); %> <td><%= session.getId() %></td> </tr> <tr> <td>Created on</td> <td><%= session.getCreationTime() %></td> </tr> </table> </body> </html> #複製全局web.xml到對應目錄並修改 cp /etc/tomcat/web.xml /appdata/webapps/ROOT/WEB-INF/ #編輯web.xml 添加<distributable/>字段
3.修改server.xml配置文件
vim /etc/tomcat/server.xml <Host name="douma.com" appBase="/appdata/webapps" unpackWARs="ture" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="douma.com_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8"> <Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/> <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="192.168.99.130" #這裏改成本機地址 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"/> <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" tempDir="/tmp/war-temp/" deployDir="/tmp/war-deploy/" watchDir="/tmp/war-listen/" watchEnabled="false"/> <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> </Cluster> </Host>
4.啓動tomcat並訪問8080端口
systemctl start tomcat
5.安裝nginx
yum install nginx -y
6.編寫反代配置
#編輯默認配置文件取消default_server
#添加反代配置 vim /etc/nginx/conf.d/proxy.conf upstream web { server 192.168.99.130:8080; } server { listen 80 default_server; server_name douma.com; location / { index index.jsp index.html; proxy_pass http://web; } }
7.啓動nginx
systemctl start nginx
基本配置和tomcat1相同,僅僅須要在編寫頁面,配置nginx代理配置和配置集羣服務時候修改ip地址。
vim /appdata/webapps/ROOT/index.jsp <%@ page language="java" %> <html> <head><title>TomcatB</title></head> <body> <h1><font color="blue">TomcatB</font></h1> <table align="centre" border="1"> <tr> <td>Session ID</td> <% session.setAttribute("magedu.com","magedu.com"); %> <td><%= session.getId() %></td> </tr> <tr> <td>Created on</td> <td><%= session.getCreationTime() %></td> </tr> </table> </body> </html>
驗證
訪問前端nginx調度器
刷新一下
雖然刷新了頁面,也同時由另外一臺服務器響應,可是session會話信息仍是很好的保存下來了。
#classname配置tomcat集羣在進行信息傳遞時互相使用什麼類來進行傳遞;channelsendoptions能夠設置爲2,4,8.10; #2表示確認發送 Channel.SEND_OPTIONS_USE_ACK #4表示同步發送Channel.SEND_OPTIONS_SYNCHRONIZED_ACK #8表示你異步發送Channel.SEND_OPTIONS_ASYNCHRONOUS #10表示 在異步模式下,能夠經過加上確認發送(Acknowledge)來提升可靠性 <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8"> #manager決定如何管理集羣的session信息, #className-指定實現org.apache.catalina.ha.ClusterManager接口的類,信息之間的管理. #expireSessionsOnShutdown-設置爲true時,一個節點關閉,將致使集羣下的全部Session失效 #notifyListenersOnReplication-集羣下節點間的Session複製、刪除操做,是否通知session listeners #maxInactiveInterval-集羣下Session的有效時間(單位:s)。 #maxInactiveInterval內未活動的Session,將被Tomcat回收。默認值爲1800s <Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/> #Channel是Tomcat節點之間進行通信的工具。 #Channel包括5個組件:Membership、Receiver、Sender、Transport、Interceptor <Channel className="org.apache.catalina.tribes.group.GroupChannel"> #Membership維護集羣的可用節點列表。它能夠檢查到新增的節點,也能夠檢查到沒有心跳的節點 #className-指定Membership使用的類 #address-組播地址 #port-組播端口 #frequency-發送心跳(向組播地址發送UDP數據包)的時間間隔(單位:ms)。默認值爲500 #dropTime-Membership在dropTime(單位:ms)內未收到某一節點的心跳,則將該節點從可用節點列表刪除。默認值爲3000 <Membership className="org.apache.catalina.tribes.membership.McastService" address="228.0.0.4" port="45564" frequency="500" dropTime="3000"/> #Receiver : 接收器,負責接收消息BioReceiver(阻塞式)、NioReceiver(非阻塞式) #className-指定Receiver使用的類 #address-接收消息的地址(默認是自動,可是最好手動更改成本地網卡對外ip) #port-接收消息的端口 #autoBind-端口的變化區間 #若是port爲4000,autoBind爲100,接收器將在4000-4099間取一個端口,進行監聽 #selectorTimeout-NioReceiver內輪詢的超時時間 #maxThreads-線程池的最大線程數 <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="192.168.99.240" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6"/> #sender:發送器負責發送消息 sender內嵌了transport組件,transport組件是負責真正傳送消息 <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> #Transport分爲兩種:bio.PooledMultiSender(阻塞式)、nio.PooledParallelSender(非阻塞式) <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> </Sender> #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"/> </Channel> #Valve :能夠做爲過濾器,ReplicationValve-在處理請求先後打日誌;過濾不涉及Session變化的請求。 #vmRouteBinderValve-Apache的mod_jk發生錯誤時,保證同一客戶端的請求發送到集羣的同一個節點 <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/> <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/> #Deployer:同步集羣下的全部節點的一致性 <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" tempDir="/tmp/war-temp/" deployDir="/tmp/war-deploy/" watchDir="/tmp/war-listen/" watchEnabled="false"/> #ClusterListener : 監聽器,監聽Cluster組件接收的消息,使用DeltaManager時,Cluster接收的信息經過ClusterSessionListener傳遞給DeltaManager <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> </Cluster>
圖中的memcached在兩個tomcat節點都會安裝,來實現冗餘。圖中獨立摘出來僅僅是爲了方便理解。
1.安裝nginx並設置代理
#安裝nginx,nginx在epel源,所以未安裝epel源的話要先安裝epel源 yum instll nginx -y
2.修改默認的nginx配置文件
vim /etc/nginx/nginx.conf
3.編輯代理配置文件
vim /etc/nginx/conf.d/proxy.conf upstream web { server 192.168.99.130:80; server 192.168.99.240:80; } server { listen 80 default_server; index index.jsp index.html; server_name douma.com; location / { proxy_pass http://web; } }
4.檢查語法並啓動nginx
#檢查語法 nginx -t #檢查無誤後啓動nginx systemctl start nginx
1.安裝nginx配置本地代理
yum install nginx -y #編輯默認配置文件取消default_server vim /etc/nginx/nginx.conf #建立新的代理配置文件 vim /etc/nginx/conf.d/proxy.conf upstream web { server 192.168.99.130:8080; } server { listen 80 default_server; server_name douma.com; location / { index index.jsp index.html; proxy_pass http://web; } } #語法檢查無誤後啓動nginx nginx -t systemctl start nginx
2.安裝tomcat和其餘管理工具
yum install tomcat tomcat-lib tomcat-admin-webapps tomcat-webapps tomcat-docs-webapp -y
3.建立測試項目
mkdir -pv /appdata/webapps/ROOT/{lib,classes,WEB-INF} #建立測試頁面 vim /appdata/webapps/ROOT/index.jsp <%@ page language="java" %> <html> <head><title>TomcatA</title></head> <body> <h1><font color="red">TomcatA</font></h1> <table align="centre" border="1"> <tr> <td>Session ID</td> <% session.setAttribute("magedu.com","magedu.com"); %> <td><%= session.getId() %></td> </tr> <tr> <td>Created on</td> <td><%= session.getCreationTime() %></td> </tr> </table> </body> </html> #拷貝默認web.xml文件到新建目錄 cp /etc/tomcat/web.xml /appdata/webapps/ROOT/WEB-INF/ #修改web.xml文件添加<distributable/>字段
4.配置memcached的session會話保持
#安裝軟件包 yum install memcached -y #下載msm的對應jar包
將下載的包放置到/usr/share/java/tomcat下
5.修改server.xml文件
vim /etc/tomcat/server.xml #配置虛擬主機 <Host name="douma.com" appBase="/appdata/webapps" unpackWARs="ture" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="douma.com_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> </Host> #在host字段內添加 <Context path="/" docBase="ROOT" reloadable=""> <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" #memcached的節點名(節點名本身定義,僅僅是顯示)和對應ip端口 memcachedNodes="n1:192.168.99.130:11211,n2:192.168.99.240:11211" #備用節點設置 failoverNodes="n1" requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$" transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory" /> </Context>
6.啓動tomcat
systemctl start tomcat
7.驗證
配置基本同配置tomcat1,要注意修改nginx代理後端的ip
nginx proxy.conf upstream web { server 192.168.99.240:8080; } server { listen 80 default_server; server_name douma.com; location / { index index.jsp index.html; proxy_pass http://web; } } server.xml <Host name="douma.com" appBase="/appdata/webapps" unpackWARs="ture" autoDeploy="true"> <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="douma.com_access_log." suffix=".txt" pattern="%h %l %u %t "%r" %s %b" /> <Context path="/" docBase="ROOT" reloadalbe=""> <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager" memcachedNodes="n1:192.168.99.130:11211,n2:192.168.99.240:11211" failoverNodes="n1" requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$" transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory" /> </Context> </Host>
訪問代理服務器192.168.99.131