#IT明星不是夢#nginx+tomcat集羣redis共享session方案實戰案例

1、常見的session一致性方案

在web集羣系統中,爲了使web能適應大規模的訪問,須要實現應用的集羣部署. 而實現集羣部署首先要解決session的統一,即須要實現session的一致性,目前,實現session一致性主要有兩個方案,分別是session複製和session共享。php

session複製,是指session信息會在集羣節點之間複製,每一個節點服務器上都會有相同的session信息。 這種方案的優勢是即便一個節點服務器宕機了,只要還有服務器存活,session信息就不會丟失,也就不影響用戶使用。而缺點是集羣節點之間通訊頻繁,對應用的響應速度有影響,在高併發、高頻操做的狀況下性能降低會更厲害。html

第二種方案是session共享,也就是將session信息保存在內存數據庫中,而後多個節點均可以來訪問內存中的session信息,最多見的就是基於Memcache/Redis等數據庫的session共享。java

tomcat自帶集羣中,提供了session複製功能,session信息會在各個tomcat中同步,session複製對網絡要求較高,session內存的消耗對tomcat影響很是大,對於小集羣來講,這種session複製基本夠用了,而對於大型集羣,仍是建議使用redis或者memcache進行session共享。linux

所以,在構建tomcat集羣時,推薦使用tomcat基於redis的session共享機制。
在經過nginx構建集羣時,也會涉及session的問題,根據設置的nginx負載均衡算法的不一樣,session的實現機制也不相同,例如輪詢(默認),指定權重,fair(第三方),url_hash(第三方)負載算法時,集羣各個節點之間必須經過session共享來實現。而使用IP綁定的 ip_hash算法時,用戶的請求都會綁定在同一個節點服務器上,可不考慮session問題。可是,節點服務器宕機後,用戶須要關掉瀏覽器從新打開登陸才能恢復正常,這樣體驗會變得不好。所以,session共享在集羣架構中有很大的用途。nginx

2、應用環境介紹

一、session應用工具git

Tomcat集羣在企業應用中使用比較多,所以,必需要解決session共享的問題。這裏主要介紹一個簡單的session共享方案:redisson工具。github

redisson是redis官網推薦的java語言實現分佈式鎖的項目。固然,redisson遠不止分佈式鎖,還包括其餘一些分佈式結構。例如,分佈式應用,分佈式緩存,分佈式回話管理,分佈式服務(任務,延遲任務,執行器),分佈式redis客戶端等。而咱們這裏要使用的是redisson提供的Tomcat Session Manager功能。它支持最新的JDK和各個版本的tomcat(6/7/8/9),redisson官網地址爲https://redisson.org/ 。
而Tomcat session共享的github地址爲:
https://github.com/redisson/redisson/tree/master/redisson-tomcat
讀者可根據本身不一樣的tomcat版本,選擇下載不一樣的redisson便可。web

二、環境準備redis

首先說明下此案例的應用環境,以下表所示:算法

操做系統    IP地址    安裝軟件    用途
centos7.6   172.16.213.37   Nginx1.14   負載均衡服務器
centos7.6   172.16.213.120  Redis五、tomcat9.0    Tomcat、redis服務器
centos7.6   172.16.213.106  tomcat9.0   Tomcat服務器

這是一個nginx與tomcat組合的web架構,兩臺tomcat組成集羣,經過nginx實現負載均衡,而在這個集羣中的session機制咱們經過redis來實現session共享,下面就來看看這個集羣架構中如何實現tomcat集羣中的session共享。

3、nginx+tomcat+redis部署過程

這個web架構的部署過程很簡單,主要分爲三個步驟,下面依次介紹。

一、redis安裝部署

redis安裝部署比較簡單,首先從https://redis.io 下載最新版本的redis,這裏下載的是redis5.x版本,而後編譯便可,過程以下:

[root@localhost ~]#wget http://download.redis.io/releases/redis-5.0.3.tar.gz
[root@localhost ~]#tar zxvf redis-5.0.3.tar.gz
[root@localhost ~]#cd redis-5.0.3
[root@localhost redis-5.0.3]#make
[root@localhost redis-5.0.3]#make install
[root@localhost redis-5.0.3]#cp redis.conf  /etc 
[root@localhost redis-5.0.3]#cd src
[root@localhost src]#cp redis-cli  redis-server  redis-sentinel   /usr/sbin/
上面這個安裝過程在前面章節已經作過詳細介紹,這裏再也不過多說明。

二、配置redis並啓動

對redis不須要過多配置,打開redis配置文件/etc/redis.conf,修改兩個配置項的值爲以下內容:

bind 0.0.0.0
daemonize yes

最後,啓動redis服務便可:

[root@localhost ~]#/usr/sbin/redis-server  /etc/redis.conf
這樣redis服務就安裝完畢而且啓動起來了。默認redis的啓動端口爲6379。

三、tomcat安裝部署

這裏先在172.16.213.120這臺機器上部署tomcat,部署tomcat以前,須要先安裝JDK,這裏選擇JDK1.8版本,從oracle官網下載linux-64版本的JDK,下載時,選擇適合本身機器運行環境的版本,oracle官網提供的JDK都是二進制版本的,所以,JDK的安裝很是簡單,只需將下載下來的程序包解壓到相應的目錄便可。安裝過程以下:

[root@localhost ~]# mkdir /usr/java
[root@localhost ~]# tar -zxvf jdk-8u181-linux-x64.tar.gz -C /usr/java/

這裏咱們將JDK安裝到了/usr/java/目錄下。接着,要讓程序可以識別JDK路徑,還須要設置JDK的環境變量,這裏咱們將JDK環境變量設置到/etc/profile文件中。添加以下內容到/etc/profile文件最後:

export JAVA_HOME=/usr/java/jdk1.8.0_181
export PATH=$PATH:$JAVA_HOME/bin
exportCLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$CLASSPATH

而後執行以下命令讓設置生效:

[root@localhost ~]# source /etc/profile

最後,在Shell提示符中執行「java -version」命令,若是顯示以下結果,說明安裝成功:

[root@localhost ~]#  java -version
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)

JDK部署成功後,就能夠部署tomcat了,tomcat的安裝很簡單,從http://tomcat.apache.org/ 下載最新的tomcat,而後解壓便可,這裏下載tomcat9版本,安裝到/usr/loca/目錄下,執行以下操做:

[root@localhost ~]# tar zxvf  apache-tomcat-9.0.16.tar.gz -C  /usr/local
[root@localhost ~]# mv /usr/local/apache-tomcat-9.0.16 /usr/local/tomcat9

這樣,tomcat也安裝完成了。因爲還須要配置tomcat和redis的整合,因此tomcat服務暫時先不啓動。

四、tomcat與redis整合實現session共享

tomcat安裝完成後,接下來就是配置tomcat了,要配置tomcat和redis整合,實現session管理,須要以下幾個步驟。

(1)、部署jar包
首先從https://github.com/redisson/redisson/tree/master/redisson-tomcat 下載兩個jar包,根據tomcat版本的不一樣,下載對應的redisson-tomcat的jar包便可,這裏咱們使用的是tomcat9版本,因此下載的redisson-tomcat爲redisson-tomcat-9-3.11.5.jar,還須要下載一個jar包是redisson-all-3.11.5.jar,這兩個jar包的版本會不斷升級更新,具體版本號可能跟本文不徹底相同,但不影響咱們使用,將下載下來的jar包放到$TOMCAT_BASE/lib目錄下,咱們這裏的路徑是/usr/local/tomcat9/lib。

(2)、增長RedissonSessionManager配置
這個步驟是在tomcat的配置文件$TOMCAT_BASE/conf/context.xml中,添加以下配置:

<Manager className="org.redisson.tomcat.RedissonSessionManager"
configPath="${catalina.base}/conf/redisson.json" readMode="REDIS" updateMode="DEFAULT"/>
其中,{catalina.base}/conf/redisson.json文件內容以下:
{
   "singleServerConfig":{
      "idleConnectionTimeout":10000,
      "connectTimeout":10000,
      "timeout":3000,
      "retryAttempts":3,
      "retryInterval":1500,
      "password":null,
      "subscriptionsPerConnection":5,
      "clientName":null,
      "address": "redis://172.16.213.120:6379",
      "subscriptionConnectionMinimumIdleSize":1,
      "subscriptionConnectionPoolSize":50,
      "connectionMinimumIdleSize":32,
      "connectionPoolSize":64,
      "database":0,
      "dnsMonitoringInterval":5000
   },
   "threads":0,
   "nettyThreads":0,
   "codec":{
      "class":"org.redisson.codec.FstCodec"
   },
   "transportMode":"NIO"
}

這個json文件主要是配置tomcat和redis鏈接的屬性信息,須要注意json文件裏面的"address"一項的值,若是tomcat和redis安裝在一塊兒,能夠寫成127.0.0.1:6379,若是redis在獨立的一臺機器上,就寫redis所在機器的IP地址。這裏redis所在的IP爲172.16.213.120,因此上面就寫這個地址便可。

到此爲止,tomcat與redis的互聯配置完成。

五、添加獲取session的jsp文件

在tomcat服務器172.16.213.120上對應的目錄$TOMCAT_BASE/webapps/ROOT下建立一個testsession.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>
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
                <title>tomcat1</title>
        </head>

        <body>
        <center><h1>tomcat1</h1></center>
        <center>
                <h3>sessionId:</h3><%=session.getId()%>
                <h3>session建立時間:</h3><%=session.getCreationTime()%>
        <center>
        </body>
</html>

接着,啓動tomcat服務,執行以下命令:

[root@localhost ~]#/usr/local/tomcat9/bin/startup.sh

啓動tomcat後,在瀏覽器訪問:http://172.16.213.120:8080/testsession.jsp, 以下圖所示:
#IT明星不是夢#nginx+tomcat集羣redis共享session方案實戰案例

而後,登陸redis客戶端,查看key信息,操做以下:

[root@localhost tomcat9]# redis-cli  -h 172.16.213.120 -p 6379
172.16.213.120:6379> keys *
1) "redisson:tomcat_session:56BC7C926C3673F8F7CFEC52442B10EA"
172.16.213.120:6379>

能夠看到,redis裏面已經生成了session信息。redis裏面的session信息跟testsession.jsp獲取到的徹底一致。

六、部署第二個tomcat實例

上面已經部署好了第一臺tomcat實例tomcat1,接着在172.16.213.106上部署另外一個tomcat實例tomcat2,最簡單的部署方法是直接拷貝第一個tomcat1實例到172.16.213.106上對應的位置便可。

爲了兩個tomcat實例進行區分,這裏須要修改testsession.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>
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
                <title>tomcat2</title>
        </head>

        <body>
        <center><h1>tomcat2</h1></center>
        <center>
                <h3>sessionId:</h3><%=session.getId()%>
                <h3>session建立時間:</h3><%=session.getCreationTime()%>
        <center>
        </body>
</html>

這裏主要是將testsession.jsp文件中的tomcat1修改成了tomcat2,最後,還須要在172.16.213.106上安裝和配置JDK,這個上面已經作了介紹,這裏再也不說明。

全部修改完成後,啓動tomcat2服務,而後訪問http://172.16.213.106:8080/testsession.jsp, 以下圖所示:

#IT明星不是夢#nginx+tomcat集羣redis共享session方案實戰案例

能夠看到,經過172.16.213.120和172.16.213.106訪問testsession.jsp頁面獲得的session信息是不同的。這是正常的。由於這是不一樣的服務器,獲得的session固然不一樣。

七、部署nginx負載均衡

根據上面的定義,nginx是安裝在172.16.213.37服務器上,從nginx官網http://nginx.org/ 下載最新的nginx版本,這裏是nginx-1.14版本,而後進行編譯安裝,過程以下:

[root@centos ~]# yum -y install zlib pcre pcre-devel openssl openssl-devel
[root@centos ~]# useradd -s /sbin/nologin www
[root@centos ~]#tar zxvf nginx-1.14.1.tar.gz
[root@centos ~]#cd nginx-1.14.1 
[root@centos nginx-1.14.1]# ./configure \
--user=www \
--group=www \
--prefix=/usr/local/nginx \
--sbin-path=/usr/local/nginx/sbin/nginx \
--conf-path=/usr/local/nginx/conf/nginx.conf \
--error-log-path=/usr/local/nginx/logs/error.log \
--http-log-path=/usr/local/nginx/logs/access.log \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/lock/subsys/nginx \
--with-http_stub_status_module \
--with-http_ssl_module \
--with-http_gzip_static_module \
--with-pcre
[root@centos nginx-1.14.1]# make
[root@centos nginx-1.14.1]# make install

這樣,nginx就安裝完成了。接下來,就是配置nginx了,打開nginx配置文件nginx.conf,重點修改以下部份內容:

user  www;
worker_processes  8;
events {
    worker_connections  65536;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
   upstream tomcat {
     server 172.16.213.120:8080 weight=1;
     server 172.16.213.106:8080 weight=1;
    }

    server {
        listen       80;
        server_name  localhost;

        location / {
            proxy_pass http://tomcat;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        location ~ \.php$ {
            root           html;
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /usr/local/nginx/html$fastcgi_script_name;
            include        fastcgi_params;
        }

    }
}

這個nginx配置中,啓用了nginx的負載均衡功能,集羣的後端節點就是兩臺tomcat服務器,配置完成,啓動nginx服務,操做以下:

[root@centos nginx-1.14.1]# /usr/local/nginx/sbin/nginx

4、測試nginx+tomcat+redis的session共享功能

nginx配置完成後,就能夠經過http://172.16.213.37/testsession.jsp 訪問兩個tomcat實例了,以下圖所示:

#IT明星不是夢#nginx+tomcat集羣redis共享session方案實戰案例

能夠嘗試不停刷新這個頁面的話,頁面會在兩個tomcat實例之間來回輪詢切換,但session值並不發生變化,這說明兩個tomcat實例都共享了redis裏面存儲的session信息,也就是實現了nginx+tomcat+redis的session共享功能。

相關文章
相關標籤/搜索