使用Redis存儲Nginx+Tomcat負載均衡集羣的Session

環境:Cent OS 7.0(虛擬機環境)、Nginx 1.9.八、Redis 3.2.1html

1、背景

在使用Nginx+Tomcat實現負載均衡的時候,因爲Nginx對不一樣的請求分發到某一個Tomcat,Tomcat在運行的時候分別是不一樣的容器裏,由於會出現session不一樣步或者丟失的問題。nginx

2、Nginx安裝與配置

一、Nginx安裝git

網上的資源對於安裝Nginx的介紹比較多,例如最簡單的爲:github

(1) 獲取nginx,在http://nginx.org/download/上能夠獲取當前最新的版本下載,例如:

wget http://nginx.org/download/nginx-1.9.8.tar.gz


(2)解壓縮tar -xvf nginx-1.9.8.tar.gz包。

(3)進入解壓縮目錄,執行./configure --prefix=/usr/local/nginx-1.9.8 將Nginx安裝到/usr/local/nginx-1.9.8目錄下

(4)make & make install
  • 安裝的過程會將Nginx安裝到/usr/local/nginx-1.9.8目錄下,啓動Nginx測試是否能夠正常啓動。

二、修改Nginx配置多Tomcat服務器web

2.一、修改conf/nginx.conf文件,在server標籤上邊添加upstream以下:redis

upstream mynginxserver {
    #weigth參數表示權值,權值越高被分配到的概率越大
    #本機上的Squid開啓3128端口
        server 127.0.0.1:8080 weight=1;
        server 127.0.0.1:8060 weight=1;
    }
  • 這裏指定了本機下的兩個Tomcat實例,端口分別爲8080,8060,權重都爲1,後邊配置Tomcat實例,mynginxserver這個是本身隨意命名的,下邊要用到

2.二、配置server標籤;apache

server {
        listen       80;
        server_name  192.168.1.149;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
           # root   html;
           # index  index.html index.htm;
           proxy_pass http://mynginxserver;
        }


        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
  • 2.三、配置以後的完整內容以下(1.9.8版本刪去了註釋後的配置內容):
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    upstream mynginxserver {
        server 127.0.0.1:8080 weight=1;
        server 127.0.0.1:8060 weight=1;
    }

    server {
        listen       80;
        server_name  192.168.1.149;

        location / {
           proxy_pass http://mynginxserver; 
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}
  • 2.四、具體的配置項和配置項的具體意義請參考 

https://www.nginx.com/resources/wiki/start/topics/examples/full/tomcat

3、Tomcat多實例的配置

一、解壓apache-tomcat-7.0.67.zip 獲得apache-tomcat-7.0.67服務器

[root@localhost www]# unzip apache-tomcat-7.0.67.zip
  • 二、將apache-tomcat-7.0.67重命名爲tomcat1
[root@localhost www]# mv apache-tomcat-7.0.67 tomcat1
  • 重複一、2過程獲得tomcat1和tomcat2以下所示:

這裏寫圖片描述

三、修改Tomcat1的端口爲8080和部署項目文件session

編輯tomcat下的conf/server.xml,修改端口號爲8080,

本身寫的用於測試Nginx反向代理的web項目war包下載地址:http://download.csdn.net/detail/u010870518/9585683

下載好以後將解壓以後的編譯好的項目文件放到tomcat1/webapps/ROOT/目錄下:

這裏寫圖片描述

修改index.jsp和login.jsp文件分別標識爲具體的Tomcat容器

這裏寫圖片描述

四、修改Tomcat2的端口爲8060和部署項目文件

編輯tomcat下的conf/server.xml,修改端口號爲8060,而後和上述3中的同樣,下載war內容,放在tomcat2/webapps/ROOT/下,修改index.jsp和login.jsp用於標識具體的Tomcat容器

五、分別啓動tomcat1和tomcat2

六、重啓Nginx服務,訪問IP地址:192.168.1.149:80(這個是訪問的虛擬機IP地址)

七、觀看效果

這裏寫圖片描述

這裏寫圖片描述

能夠看出,Nginx已經進行了請求分發,轉發到具體的某一個Tomcat

4、Redis的安裝與配置

因爲篇幅過長,請參考本人寫的:http://blog.csdn.net/xlgen157387/article/details/52022793

5、tomcat-redis-session-manager開源項目的使用

一、開源項目地址:https://github.com/jcoleman/tomcat-redis-session-manager

二、下載代碼以後須要進行從新編譯,生成所須要的jar,任意建立maven項目,將src下的代碼拷貝到具體位置,以下:

這裏寫圖片描述

maven的pom.xml文件以下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.ufind.session</groupId>
    <artifactId>tomcat-redis-session</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.apache.tomcat</groupId>
            <artifactId>tomcat-catalina</artifactId>
            <version>7.0.27</version>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.7.2</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
  • 三、而後打開terminal,執行mvn clean 和mvn install 將編譯好的代碼打包爲:tomcat-redis-session-1.0-SNAPSHOT.jar

四、將tomcat-redis-session-1.0-SNAPSHOT.jar、jedis-2.7.2.jar、commons-pool2-2.0.jar 三個jar包分別放在tomcat1和tomcat2實例下的lib目錄下。

免費下載這三個jar:http://download.csdn.net/detail/u010870518/9585716

五、修改tomcat實例下conf/contex.xml文件

<?xml version='1.0' encoding='utf-8'?>  
<Context>  
    <WatchedResource>WEB-INF/web.xml</WatchedResource>  

    <!-- tomcat-redis-session共享配置 -->  
    <Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />  
        <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"  
         host="192.168.1.149"   
         port="6379"   
         database="0"   
         maxInactiveInterval="60" />  

</Context>
  • 若是Redis配置了訪問權限,請添加密碼爲:
<?xml version='1.0' encoding='utf-8'?>  
<Context>  
    <WatchedResource>WEB-INF/web.xml</WatchedResource>  

    <!-- tomcat-redis-session共享配置 -->  
    <Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />  
        <Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"  
         host="192.168.1.149"   
         port="6379"   
         database="0"  
         password="redispassword" 
         maxInactiveInterval="60" />  

</Context>
  • 若是不設置密碼會報錯,以下:

這裏寫圖片描述

6、效果演示

案例演示的一個登錄請求,登錄成功以後將用戶信息放在session中,在界面中顯示出來(tomcat1實例,tomcat2的實例中只是在 h2 標籤中作了一下標識)

一、login.jsp文件:

<body>
<h2>Session Demo in Tomcat1</h2>
<form action="/user?type=login" method="post">
    用戶名:<input type="text" name="userName"/><br/>
    密碼:<input type="password" name="userPassword"/><br/>
    <input type="submit" value="login">
</form>
</body>
  • 二、index.jsp 將登陸以後的信息顯示在界面上
<body>

<h2>Session Demo in Tomcat1</h2>

<%
    User user = (User) request.getSession().getAttribute("USER");
    if (user == null) {
%>
用戶爲空,沒有登陸!!!
<%
} else {
%>
歡迎: <%=user.getUserName()%>
<%
    }
%>

</body>
  • 三、servlet處理請求代碼
public class UserServlet extends BaseServlet {

    public String login(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        User user = new User();
        user.setUserName(request.getParameter("userName"));
        user.setUserPassword(request.getParameter("userPassword"));
        request.getSession().setAttribute("USER", user);

        return "index.jsp";
    }

}
  • 四、效果以下:

這裏寫圖片描述

能夠看出在登陸界面的時候刷新請求的tomcat已經由Nginx進行分發請求,登陸以後再兩個tomcta中已經共享了session

五、查看Redis對session的存儲

在對contex.xml文件進行配置的時候默認使用的database爲0,經過redis-cli工具可看到

這裏寫圖片描述

這裏寫圖片描述

7、總結

tomcat-redis-session-manager是一個對用戶徹底透明的分佈式session存儲框架,用戶只須要在tomcat中進行簡單的配置,就可使用,咱們的業務代碼是徹底和單實例的時候的代碼是同樣的的,也就是寫代碼的時候徹底不用擔憂你寫的是一個多tomcat實例的代碼,徹底透明。

如何對框架的原理進行簡單的理解,咱們首先要知道,在請求過程當中的session操做,首先要解析請求中的sessionId信息,而後將sessionId存儲到request的參數列表中。而後再從 request獲取session的時候,若是存在sessionId那麼就根據Id從session池中獲取session,若是sessionId不存在或者session失效,那麼則新建session而且將session信息放入session池,供下次使用。

若是咱們想本身寫一個相似於tomcat-redis-session-manager的項目,咱們應該知道Tomcat的Session管理機制,在默認的狀況下Tomcat的Session管理,若是不進行設置的話是由Tomcat自帶的StandardManager類進行控制的,咱們能夠根據這個類自定義一個Manager,主要重寫的就是org.apache.catalina.session.ManagerBase裏邊的具體寫的操做, 
這也是tomcat-redis-session-manager的基本原理,將tomcat的session存儲位置指向了Redis

這裏寫圖片描述

RedisSessionManager繼承了org.apache.catalina.session.ManagerBase並重寫了add、findSession、createEmptySession、remove等方法,並將對session的增刪改查操做指向了對Redis數據存儲的操做

相關文章
相關標籤/搜索