nginx+tomcat+memcache實現負載均衡、session共享

實驗架構圖:

 

Table of Contents

1、配置tomcat

2、安裝memcache

3、查看tomcat和memcache是否配置好

4、nginx實現負載均衡:

5、客戶端進行測試:

6、驗證結論:

7、總結:


實驗環境

linux  redhat6.5   防火牆關閉,三臺虛擬機和一臺物理機

                  主機

                      操作系統

                           IP地址

                nginx

    

                     redhat6.5

 

                        test1:  172.25.1.11

              tomcat1  

                        test2:  172.25.1.12

              tomcat2  

                        test3:  172.25.1.13

            memcache1

                        test2:  172.25.1.12

            memcache2

                        test3:  172.25.1.13

 解釋: nginx做爲反向代理,實現靜動分離,將客戶動態請求根據權重隨機分配給兩臺tomcat服務器,memcache做爲兩臺tomcat的共享session數據服務器。

1、配置tomcat

在test2和test3分別配置tomcat服務(這裏只演示test2的配置,配置有區別的地方已經用紅色標出來)

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

[root@test2 ~]# tar zxf jdk-7u79-linux-x64.tar.gz -C /usr/local
[root@test2 ~]# ln -s /usr/local/jdk1.7.0_79/ /usr/local/jdk
[root@test2 ~]# vim /etc/profile

export JAVA_HOME=/usr/local/jdk
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$PATH:$JAVA_HOME/bin

[root@test2 ~]# source /etc/profile             //刷新環境變量

[root@test2 ~]# which java             //查看java路徑
/usr/local/jdk/bin/java
[root@test2 ~]# which javac
/usr/local/jdk/bin/java

此時java環境就搭建好了

[root@test2 ~]# vim test.java            //寫一個java程序試試看能否運行,內容如下:

public class test
{
        public static void main(String[] args)
        {
                System.out.println("hello world");
        }
}

[root@test2 ~]# javac test.java          //進行編譯
[root@test2 ~]# java test             //運行java

此時我們安裝tomcat

[root@test2 ~]# tar zxf apache-tomcat-7.0.37.tar.gz -C /usr/local/
[root@test2 ~]# cd /usr/local/
[root@test2 local]# ln -s apache-tomcat-7.0.37/ tomcat              //做個軟鏈接

[root@test2 local]# cd tomcat/apache-tomcat-7.0.37/

[root@test2 apache-tomcat-7.0.37]# mv * ..

[root@test2 apache-tomcat-7.0.37]# cd

session 的序列化方案官方推薦的有 4 種:
1. java serialization
2. msm-kryo-serializer
3. msm-javolution-serializer
4. msm-xstream-serializer
其中性能最好的序列化方案是 Kryo,此實驗我們採用 kryo 方式

把如下jar軟件包下載好放置到/usr/local/tomcat/lib 目錄中,jar軟件包包含如下內容:

[root@test2 jar]# cd
[root@test2 ~]# mv jar/  /usr/local/tomcat/lib
[root@test2 ~]# cd /usr/local/tomcat/lib/jar/
[root@test2 jar]# mv * ..
[root@test2 jar]# cd ..
[root@test2 lib]# ls

[root@test2 ~]# rm -rf jar

[root@test2 ~]# vim /usr/local/tomcat/conf/context.xml                 //配置memcache緩存

......

<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
  memcachedNodes="n1:172.25.1.12:11211,n2:172.25.1.13:11211" //memcache的兩個節點,11211是memcache的端口號
    failoverNodes="n1"             //test3和test2的區別是在這裏寫n2
      requestUriIgnorePattern=".*\.(ico|png|gif|jpg|css|js)$"
        transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
          />
</Context>

[root@test2 local]# cd tomcat/
[root@test2 tomcat]# bin/startup.sh                 //開啓tomcat服務; /usr/local/tomcat/bin/shutdown.sh 爲關閉tomcat服務

   //查看tomcat的端口號

此時,瀏覽器分別輸入test2和test3對應的ip及服務端口號8080進行查看:

均可以訪問到,此時test2和test3兩主機的tomcat服務就搭建完成啦。

溫馨提示:如果訪問時出現網頁空白的情況,可以嘗試用ps命令查看tomcat(java)的進程id號,然後kill -9 id 將進程殺掉,然後重啓服務,再次查看應該就可以了,網頁還是出不來你可以先將配置memcache的配置文件剛纔添加的內容刪掉,看是否可以訪問,若可以,則說明是配置文件添加的內容的問題;若不能訪問,則是下載過程中的問題。

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

2、安裝memcache

test2和test3上執行:

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""'

[root@test2 ~]# yum install -y memcache

[root@test2 ~]# /etc/init.d/memcached start

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

3、查看tomcat和memcache是否配置好

[root@test2 ~]# cd /usr/local/tomcat/logs/
[root@test2 logs]# > catalina.out
[root@test2 logs]# cd -
/usr/local/tomcat
[root@test2 tomcat]# ./bin/startup.sh
Using CATALINA_BASE:   /usr/local/tomcat
Using CATALINA_HOME:   /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME:        /usr/local/jdk
Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
[root@test2 tomcat]# cd -
/usr/local/tomcat/logs
[root@test2 logs]# cat catalina.out                    //看到如下結果,說明已經配置成功

4、nginx實現負載均衡:

用nginx默認自帶的proxy和upstream模塊來實現後端web負載均衡,用nginx的sticky模塊實現session共享

這裏要用到sticky模塊,所以提前下載nginx及nginx-sticky-module壓縮包,進行源碼編譯,具體步驟看上一篇博客的後半片(擴展模塊sticky部分),這裏不再贅述。

上文博客連接:https://blog.csdn.net/weixin_41922887/article/details/89421210

只在test1上進行:

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

[root@test1 ~]# useradd -s /sbin/nologin nginx                //創建nginx程序用戶,編譯的時候用到

[root@test1 ~]# id nginx

nginx已經實現sticky模塊的負載均衡

[root@test1 ~]# /opt/nginx/sbin/nginx -t                 //查看nginx的狀態

修改配置文件

[root@test1 ~]# vim /opt/nginx/conf/nginx.conf

user  nginx   nginx;                                 //剛纔創建的nginx用戶

worker_processes  2;
events {
    worker_connections  65535;
}

http {
    upstream server {
    sticky;                             //sticky模塊,目的是當同一個用戶動態訪問時將請求發到同一個tomcat上,實現session的共享
    server 172.25.1.12:8080;
    server 172.25.1.13:8080;
    }
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    #gzip  on;

    server{
        listen       80;
        server_name  www.westos.org;                         //訪問時的域名
    location / {
              root   html;
              index  index.html index.htm;
    }
        location ~ \.jsp$ {                                                //所有 jsp 頁面交給 tomcat 處理,動靜分離
                proxy_pass http://server;
    }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

[root@test1 ~]# /opt/nginx/sbin/nginx -t            //檢查語法是否有錯誤

[root@test1 ~]# /opt/nginx/sbin/nginx           //開啓服務

此時,我們的所有服務就搭建完成了。

5、客戶端進行測試:

測試nginx服務:

靜態測試:

在test1上執行:

[root@test1 ~]# cd /opt/nginx/html/                   //nginx的默認發佈路徑
[root@test1 html]# ls
50x.html index.html
[root@test1 html]# vim cxx.html                     //寫一個靜態的文件cxx.html
<h1>it's a static nginx</h1>

此時在網頁進行測試:

動態測試:
test2和test3都執行(這裏只演示test2):

[root@test2 ~]# cd /usr/local/tomcat/webapps/ROOT/
[root@test2 ROOT]# vim test.jsp

The time is:<%=new java.util.Date() %>

客戶端進行訪問:

再如:

[root@test2 ROOT]# vim cxx.jsp                       

<%@ page contentType="text/html; charset=GBK" %>
<%@ page import="java.util.*" %>
<html><head><title>Cluster App Test</title></head>
<body>
Server Info:
<%
out.println(request.getLocalAddr() + " : " + request.getLocalPort()+"<br>");%>
<%
out.println("<br> ID " + session.getId()+"<br>");
String dataName = request.getParameter("dataName");
if (dataName != null && dataName.length() > 0) {
String dataValue = request.getParameter("dataValue");
session.setAttribute(dataName, dataValue);
}
out.print("<b>Session list</b>");
Enumeration e = session.getAttributeNames();
while (e.hasMoreElements()) {
String name = (String)e.nextElement();
String value = session.getAttribute(name).toString();
out.println( name + " = " + value+"<br>");
System.out.println( name + " = " + value);
}
%>
%<form action="test.jsp" method="POST">
%name:<input type=text size=20 name="dataName">
%<br>
%key:<input type=text size=20 name="dataValue">
%<br>
%<input type=submit>
%</form>
%</body>
%</html>

[root@test2 ROOT]# scp westos.jsp root@test3:/usr/local/tomcat/webapps/ROOT      //test2和test3同時添加,scp直接發過去就好

可以看出,訪問動態頁面時用到後端服務器,這裏接受訪問請求的是test2,對應的memcache是test3

也可以看出,不管怎麼刷新或者重新訪問,只要是同一臺主機,則接受請求的服務器不會變,和第一次訪問時是同一臺服務器。

6、驗證結論:

現在將test3的memcache服務關閉並進行刷新操作,則此時:

[root@test3 tomcat]# /etc/init.d/memcached stop           //可以看出此時memcache變爲test2節點,而請求還是會交給test2的 tomcat,沒有因爲test3的memcache掛掉而丟掉

將test3的memcache恢復狀態

[root@test3 tomcat]# /etc/init.d/memcached start

刷新時memcache不會變回去

此時將test2的tomcat服務宕掉,並刷新:

[root@test2 tomcat]# /usr/local/tomcat/bin/shutdown.sh

訪問結果爲:

此時,memcache仍然爲test2

7、總結:

不同的主機訪問時會調度到不同的 tomcat 實例上處理,來自同一主機的請求會交給同一個 tomcat 實例處理,此時你 down 掉當前正在響應的 tomcat 實例,nginx 會自動把用戶的請求調度到另一個 tomcat 實例上,同時 session 也沒有丟掉。

原理:當test2中tomcat宕機後,test3接管會話後從本地的memcache處讀取memcache的信息。

           當test2的memcache宕機後,test3的tomcat中會將會話信息存至本地,以致session不會丟失。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章