同域名下相同項目(集群環境)實現Session共享
在同一個域名下,比如:www.p2p.com
同一個項目,部署了多臺tomcat,這就是典型的集群。我們的入門案例就屬于這種應用場景,只不過在實際開發的過程中,我們如果存在了tomcat集群,那么肯定會使用nginx進行負載均衡,那么這種情況下我們該如何處理。
我們將上一個階段的p2p項目實現集群部署下的Session共享,因為我們只是演示Session共享,所以我們試用一個簡易版本的p2p,在我給大家提供的資料中,該p2p中只包含p2p和dataservice,在Linux服務器上,我們準備三臺tomcat,其中兩臺部署p2p,并實現session共享,另一臺部署dataservice。
① 使用Xftp將p2p上傳到tomcat9100和9200的webapps目錄下
② 使用Xftp將dataservice上傳到tomcat9300的webapps目錄下
③ 使用資源下的SQL腳本,重新創建數據庫的表
因為目前這個p2p的項目表結構和上一個階段的稍微有些區別,所以我們這里更新一下:
A、 啟動mysql數據庫
B、 通過MySQL客戶端工具Navivat創建新的庫
C、 指定數據庫名字為p2p2,字符集編碼為utf-8
D、 新建查詢,執行p2p-data.sql腳本
E、 執行成功后,表結構如下
④ 通過Xftp工具連接Linux,修改tomcat9300下的dataservice的連接信息
A、 使用記事本打開,修改redis.properties,保存
B、 修改datasource.properties,保存
C、 修改applicationContext-dubbo-provide.xml注冊中心的地址,并保存
⑤ 通過Xftp工具連接Linux,修改tomcat9100下的p2p的連接信息
這里只需要修改applicationContext-dubbo-consumer.xml文件中zk注冊中心的地址即可。
⑥ 通過Xftp工具連接Linux,修改tomcat9200下的p2p的連接信息
這里只需要修改applicationContext-dubbo-consumer.xml文件中zk注冊中心的地址即可。
⑦ 確保Linux系統上的各應用服務器啟動
注意:先通過ps –ef | grep XXX命令查看,如果已經啟動,就不需要再啟動了。
A、 啟動ZooKeeper服務器
B、 啟動MySQL服務器
C、 啟動Redis服務器
D、 啟動tomcat9300服務器(為了避免出錯先關閉,再啟動)
E、 啟動tomcat9100服務器(為了避免出錯先關閉,再啟動)
F、 啟動tomcat9200服務器(為了避免出錯先關閉,再啟動)
G、 直接訪問tomcat的方式,在瀏覽器輸入地址訪問tomcat9100和tomcat9200
⑧ 使用Nginx對tomcat9100和tomcat9200進行負載均衡
A、 負載均衡的配置,這里使用的是輪詢策略
upstream www.p2p.com{
???????? server 127.0.0.1:9100;
???????? server 127.0.0.1:9200;???????
}?
B、location匹配的配置,注意:這里對靜態資源的處理,我們暫時先注釋掉
location /p2p{
?????????????proxy_pass http://www.p2p.com;
????????}
如果要是實現了靜態代理,別忘了啟動所有的nginx服務器(負載|代理)
C、 重啟Nginx
D、 在瀏覽器中輸入地址,直接訪問Nginx服務器,實現負載均衡
⑨ Nginx對集群負載均衡之后,登錄不成功,但是直接訪問tomcat9100或者tomcat9200都是可以成功登錄的(Session丟失),分析原因:
因為默認我們負載均衡使用的是輪詢策略,每次發送請求給nginx服務器,都會切換tomcat服務器,這個時候沒有使用任何session共享策略,所以登錄不成功。
⑩ Nginx對集群負載均衡之后,Session共享方案
A、 修改nginx.conf配置文件,將輪詢策略修改為ip_hash
但是這種情況,一旦ip發生變化,或者某臺服務器出現故障,會重新分配,不穩定;
所以我們看下這種情況后,將ip_hash注釋掉。
B、 使用SpringSession
使用Spring Session實現session共享,我們不需要修改代碼,只要修改一些配置文件即可,為了演示方便,我們直接使用Xftp修改已經發布到tomcat上的項目;
向tomcat9100和tomcat9200的p2p項目中加jar包,這個jar包我已經準備好了。
修改tomcat9100和tomcat9200的p2p項目的web.xml配置文件,添加Spring Session過濾器,因為我們項目本身已經通過springMVC啟動了容器,所以spring監聽器不需要加了,直接從01-springsession-web中拷貝即可;
將01-springsession-web項目中resources下的applicationContext-session.xml和redis.properties拷貝到tomcat9100和tomcat9200的p2p項目WEB-INF/classes下
修改tomcat9100和tomcat9200的p2p項目WEB-INF/classes下applicationContext.xml文件,引入applicationContext-session.xml
重啟三臺tomcat服務器,瀏覽器訪問進行登錄測試,可以實現Session共享。
在同一個域名下,有多個不同的項目(項目的上下文根不一樣)比如:
www.web.com/p2p
www.web.com/shop
如圖:
在01-springsession-web項目的基礎上,將本地tomcat9100的上下文根修改為p2p,將本地tomcat92
① 打開Edit Configurations進行配置
② 在Deployment選項卡下,設置本地tomcat9100的Application context為/p2p
③ 在Deployment選項卡下,設置本地tomcat9200的Application context為/shop???????
④ 在idea中重新啟動本地的兩臺tomcat服務器
⑤ 在瀏覽器中訪問tomcat9100(p2p),設置session
⑥ 在瀏覽器中訪問tomcat9200(shop),獲取session
⑦ 分析Session共享失敗原因
我們通過瀏覽器提供的開發人員工具可以發現,這兩個請求的cookie的路徑(path)不一致,雖然我們已經加了Spring Session共享機制,但是后臺服務器認為這是兩個不同的會話(session),可以通過Redis客戶端工具(Redis Destop Mananger)查看,先清空,然后訪問,發現是維護了兩個不同的session,所以不能實現共享。
⑧ 解決方案 設置Cookie路徑為根/上下文
在applicationContext-session.xml文件中,加如下配置:
⑨ 在idea中重新啟動本地的兩臺tomcat服務器
⑩ 在瀏覽器中訪問tomcat9100(p2p),設置session
? 在瀏覽器中訪問tomcat9200(shop),獲取session
注意:測試的時候要先清空瀏覽器緩存。
同一個根域名,不同的二級子域名
比如:
www.web.com
beijing.web.com
nanjing.web.com
如圖:
• 設置Cookie路徑為根/上下文,項目名一樣的話,此步驟可以省略
• 設置cookie的域名為根域名 web.com
在01-springsession-web項目的基礎上,將本地tomcat9100的上下文根修改為p2p,將本地tomcat9200的上下文根修改為shop;在本機host文件中修改127.0.0.1的映射關系模擬不同的域名訪問。
① 延續上面的案例的配置,兩臺本地tomcat服務器9100和9200,上下文根分別是p2p和shop
② 修改本地hosts文件,加入如下配置
③ 在idea中重新啟動本地的兩臺tomcat服務器
④ 在瀏覽器中訪問tomcat9100(p2p),設置session
注意,這里不再使用localhost訪問,而是使用我們映射的域名
⑤ 在瀏覽器中訪問tomcat9200(shop),獲取session
注意,這里也不再使用localhost訪問,而是使用我們映射的域名
⑥ 分析Session共享失敗原因
我們通過瀏覽器提供的開發人員工具可以發現,雖然這兩個cookie的路徑(path)都設置為了“/”,但是這兩個cookie的域名不一致,雖然我們已經加了Spring Session共享機制,但是后臺服務器同樣認為這是兩個不同的會話(session),可以通過Redis客戶端工具(Redis Destop Mananger)查看,先清空,然后訪問,發現是維護了兩個不同的session,所以不能實現共享,也就是說后臺區分是否同一個session和路徑和域名有關。
⑦ 解決方案 設置Cook ie的域名為根域名 web.com
在applicationContext-session.xml文件中,加如下配置:
注意:域名要和hosts文件中配置的域名后面一樣
⑧ 在idea中重新啟動本地的兩臺tomcat服務器
⑨ 在瀏覽器中訪問tomcat9100(p2p),設置session
⑩ 在瀏覽器中訪問tomcat9200(shop),獲取session
注意:清空瀏覽器緩存???????