在nginx實作了負載均衡之后,用戶第一次請求的tomcat和第二次請求的tomcat基本不是同一個,但是你在第一次請求放在session中的值只有一個tomcat1才有,第二個請求的那個tomcat2里面是沒有的,這樣就出現了用戶不停登入的情況,為了解決這個session共享的問題,于是我們提出了以下幾個方案:
文章目錄
- nginx實作session共享
- ip_hash(ip系結)
- 步驟實作
- 大致描述
- 優缺點
- tomcat集群實作session的共享
- 步驟實作
- 創建一個web專案
- 復制一份tomcat到檔案夾中
- 匯出war包
- 修改server.xml
- 修改埠及作業路徑
- 啟動tomcat
- 修改nginx組態檔
- 測驗是否成功
- 關閉nginx
- 優缺點
- redis實作session的共享
nginx實作session共享
ip_hash(ip系結)
原理:每個請求按訪問ip的hash結果分配,這樣每個訪客固定訪問一個后端服務器,可以解決session的問題,
步驟實作
大致描述
直接在組態檔里面添加ip_hash 則可以實作ip系結,ip系結 和什么瀏覽器沒有關系,是和本機電腦ip有關系,A B 兩個客戶端,如果 nginx配置ip系結以后 A 客戶端如果請求的 是8080 服務器,則以后來自客戶端的A 的請求都將交給8080服務器處理,如果是IP 系結,在高并發的情況下,也沒有什么作用,但是 ip系結可以實作 會話共享
upstream backserver {
ip_hash;
server 192.168.0.14:88;
server 192.168.0.15:80;
}
優缺點
優點:實作也比較簡單,需要修改一下nginx的組態檔即可
缺點:
- 一大堆人連同一個網訪問的時候,就沒有負載均衡這一說了,這一大堆的ip都是一樣,都去訪問同一個tomcat,
- 如果這個人訪問的tomcat突然掛了,那nginx的故障轉移機制將會分發給另一個tomcat服務器,這樣一來所有請求這個tomcat的所有用戶就又需要重新登入了,
- 如果這個人用著用著突然在用的網路不穩定,然后這個人換了另一個網,這樣ip一換,這個人又要重新登入了,
小結:這樣的解決方案能簡單的實作,但是不能滿足商業需求,
tomcat集群實作session的共享
原理:這個方法原理比較簡單,就是有幾個tomcat,就復制了幾個session,比如一個tomcat的session發生了改變,其余tomcat的session也會復制發生改變,保證了用戶的session在所有的tomcat中都是相同的,
步驟實作
創建一個web專案
在起始頁index.jsp中寫入以下代碼(便于之后觀察)
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
SessionID:<%=session.getId()%>
<BR>
SessionIP:<%=request.getServerName()%>
<BR>
SessionPort:<%=request.getServerPort()%>
<%
out.println("This is Tomcat Server 111");
%>
</body>
</html>
記得修改一下輸出陳述句,進行不同tomcat的區分
寫入之后,在web.xml中添加一個<distributable/>節點,放在display下面

復制一份tomcat到檔案夾中
(檔案夾用于儲存tomcat)

兩個tomcat內容都是一樣的,只不過檔案夾命名不一樣
匯出war包
放到tomcat的的webapps中
匯出兩次,第二次的時候,把輸出陳述句換成2222,以便于觀察,把第二次匯出的war包放入到tomcat2中,第一次的就是放在tomcat1中,

修改server.xml
打開tomcat的conf檔案夾,對server.xml檔案修改
找到<Engine name="Catalina" defaultHost="localhost">這一條陳述句,在此陳述句后輸入:
<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="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"/>
<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>
修改埠及作業路徑
修改埠
打開tomcat的conf檔案夾,對server.xml檔案修改,修改成不一樣的即可,我為了簡便,修改為如下:
tomcat1:



tomcat2:



修改作業路徑
打開tomcat的bin檔案夾,對startup.bat檔案修改
在@echo off前面加上:
set TLTLE="tomcat002"
set CATALINA_BASE="D:\tomcat_cluster\tomcat002"
set CATALINA_HOME="D:\tomcat_cluster\tomcat002"
記得兩個tomcat都要修改
啟動tomcat
兩個都要啟動(忽略亂碼問題)

修改nginx組態檔
修改conf路徑下的nginx.conf檔案

- 第一個引數為為自己的tomcat地址
- weight:權重
- fail_timeout:失敗時間
- max_fails:失敗次數
fail_timeout與max_fails可以理解為,在fail_timeout的時間內,失敗max_fails次,那就把請求分配給其他服務器
測驗是否成功
在瀏覽器輸入自己的url以及埠測驗

測驗成功:是兩個不同的tomcat,但是是一樣的session,session共享成功
關閉nginx

再次進入已經顯示進不去了,證明nginx關閉了

優缺點
優點:實作簡單,沒有什么花里胡哨的操作,如果集群中的tomcat的個數不多,而且用戶沒有那么多的時候可以選擇這種方式,
缺點:只要Session資料有變化,就需要將資料同步到所有其他機器上,機器越多,同步帶來的網路帶寬開銷就越大;當用戶很多時,每臺機器用于保存Session資料的內容占用會很嚴重,
redis實作session的共享
暫未學習,學習之后再加入,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/249107.html
標籤:其他
上一篇:華為 OSPF鄰居建立的程序
下一篇:釘釘SDK:java.lang.NoClassDefFoundError: com/dingtalk/oapi/lib/aes/DingTalkEncrypto
