1. 程式人生 > >tomcat叢集環境下實現負載均衡、session共享

tomcat叢集環境下實現負載均衡、session共享

一、 高可用
     高可用HA(High Availability)是分散式系統穩定執行必須考慮的因素之一,它指的是通過處理減少系統不能提供服務的時間。比如說系統能夠一直正常提供服務,我們就說這個系統可用性為100%。
     我們知道,單點系統是高可用的公敵,線上系統應該儘量避免單點。所以當前更多的線上系統保證高可用的原則是“叢集化”,相同的服務,部署多臺伺服器,若其中一臺伺服器掛了,還有另外一臺可以保證正常服務。
二、 實現原理
在這裡插入圖片描述

三、 專案環境
伺服器(CentOS 7.2 64位)
負載均衡(nginx-1.9.9)
session共享(redis-5.0.0)
web應用伺服器(apache-tomcat-8.5.35)

四、 安裝nginx
nginx需要三個依賴庫pcre、zlib、ssl,所以安裝nginx之前先安裝依賴庫。
(1)安裝pcre
注:不建議使用pcre2***,否則會出現如下異常:
在這裡插入圖片描述
安裝目錄根據自己來定:

①線上獲取pcre:wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.42.tar.gz
②解壓:tar -zxvf pcre2-8.42.tar.gz
③cd pcre-8.42
④./configure
⑤make
⑥make install

(2)安裝zlib

①線上獲取zlib:wget https://zlib.net/fossils/zlib-1.2.11.tar.gz
②解壓:tar -zxvf zlib-1.2.11.tar.gz
③cd zlib-1.2.11
④./configure
⑤make
⑥make install

(3)安裝ssl

①線上獲取ssl:wget http://www.openssl.org/source/openssl-1.0.1j.tar.gz
②tar -zxvf openssl-1.0.1j.tar.gz
③cd openssl-1.0.1j
④./config
⑤make
⑥make install

(4)安裝nginx

①線上獲取nginx:wget http://nginx.org/download/nginx-1.9.9.tar.gz
②解壓:tar -zxvf nginx-1.9.9.tar.gz
③cd nginx-1.9.9
④./configure --with-pcre=/home/button***/pcre-8.42/ --with-zlib=/home/button/***/zlib-1.2.11/ --with-openssl=/home/button/***/openssl-1.0.1j/
⑤make
⑥make install

注:
(a)、with-pcre、with-zlib、with-openssl的路徑根據自己路徑進行修改。
(b)、安裝的過程會將nginx安裝到/usr/local/nginx目錄下

啟動nginx:

cd /usr/local/nginx/sbin
./nginx

看到如下頁面則表示啟動成功(埠預設80):
在這裡插入圖片描述

五、 tomcat部署web專案

    複製兩個tomcat,部署在同一臺機器注意修改埠,將自己的專案複製到tomcat的webapp目錄下。
例如訪問目錄如下:
http://192.168.1.150:8080/web/
http://192.168.1.151:8080/web/
注:為了看起來效果明顯,可以將自己web專案顯示的內容做一些區分,方便觀察效果。

六、 nginx配置tomcat負載均衡
nginx配置多Tomcat伺服器,修改conf/nginx.conf檔案,在server標籤上邊新增upstream如下:

upstream nginxserver{
       server 192.168.1.150:8080 weight=1;
       server 192.168.1.151:8080 weight=1;
}

注:server標籤中listen是nginx監聽的埠,根據自己情況修改。

upstream配置的幾點說明:
weight:為權重,weight越大,負載的權重就越大,訪問被命中的機率就越大。
down:表示當前的server暫時不參與負載
max_fails:允許請求失敗的次數預設為1.當超過最大次數時,返回proxy_next_upstream模組定義的錯誤

在location標籤中新增”proxy_pass”,內容http://***; ***代表upstream名稱。

proxy_pass http://nginxserver;

在這裡插入圖片描述

    說明:這裡指定了部署的兩個tomcat例項,分別為192.168.1.150:8080,192.168.1.151:8080,權重(weight)都為1。權重越大,表示訪問時命中的機率越高。
    配置好之後就可以啟動nginx了,訪問http://nginx_ip:埠/***。不斷重新整理就可以看到兩個tomcat會不斷切換被訪問到。這時發現sessionId不同,接下來實現session共享。
在這裡插入圖片描述

關於nginx的upstream幾種配置方式:
(1)輪詢(預設方式)
每個請求按時間順序逐一分配到不同的伺服器,如果伺服器down掉,能自動剔除。
(2)weight(權重)
指定輪詢的機率,weight和訪問比率成正比,用於伺服器效能不均的情況。
(3)ip_hash
每個請求按訪問ip的hash結果分配,即每個訪客固定訪問一個伺服器,這樣可以解決session共享的問題。
例如:
upstream bakend {
ip_hash;
    server 192.168.1.150:8080;
    server 192.168.1.151:8080;
}
(4)fair(第三方)
按伺服器的響應時間來分配請求,響應時間短的優先分配。
upstream backend {
    server 192.168.1.150:8080;
    server 192.168.1.151:8080;
    fair;
}
關於nginx更多更細緻的配置,有興趣可以自己研究一下。

七、 redis實現session共享
需要兩個jar包,放置在tomcat的lib目錄下:
下載地址:https://download.csdn.net/download/qq_26709459/10790707
在這裡插入圖片描述
redis-session-manager這個jar包原始碼從下面的地址獲取,在此表示感謝。也感謝本次查詢到所有資料的作者,希望大家能夠互相學習。
https://github.com/chexagon/redis-session-manager

注:不同版本的tomcat所使用的jar包和配置可能會不同,根據自己使用環境自己探究吧,學習是永無止境的。
在tomcat/conf/context.xml中新增如下配置:
在這裡插入圖片描述

<Manager className="com.crimsonhexagon.rsm.redisson.SingleServerSessionManager"
        endpoint="redis://*********:6379"
        sessionKeyPrefix="_rsm_"
        saveOnChange="false"
        forceSaveAfterRequest="false"
        dirtyOnMutation="false"
        ignorePattern=".*\\.(ico|png|gif|jpg|jpeg|swf|css|js)$"
        connectionPoolSize="100"
        database="1"
        password="*******"
        timeout="60000"
        pingTimeout="1000"
        retryAttempts="20"
        retryInterval="1000"
    />

注:若redis是叢集環境,使用如下配置:

<Manager className="com.crimsonhexagon.rsm.redisson.ElasticacheSessionManager"
	nodes="redis://******:6379 redis://*****:6379 ..."
	nodePollInterval="1000"
	sessionKeyPrefix="_rsm_"
	saveOnChange="false"
	forceSaveAfterRequest="false"
	dirtyOnMutation="false"
	ignorePattern=".*\\.(ico|png|gif|jpg|jpeg|swf|css|js)$"
	maxSessionAttributeSize="-1"
	maxSessionSize="-1"
	allowOversizedSessions="false"
	masterConnectionPoolSize="100"
	slaveConnectionPoolSize="100"
	database="0"
	password="**********"
	timeout="60000"
	pingTimeout="1000"
	retryAttempts="20"
	retryInterval="1000"
/>

再次訪問並不斷重新整理,這次發現獲取到的sessionId相同,完成session共享效果。
在這裡插入圖片描述