Nginx 服務器 之Nginx與tomcat實現負載均衡

 

 

本文講解咱們如何使用Nginx作反向帶服務器,實現nginx與tomcat服務器集羣作負載均衡。css

1、nginx與tomcat實現負載均衡

一、在/usr/local/ngnix/conf  建立文件 nginx-tomcat.confhtml

文件內容:java

user  nobody;
worker_processes  2;
events {   
    worker_connections  1024;    
}
http{
    # upstream 配置一組後端服務器,
    # 請求轉發到upstream後,nginx按策略將請求指派出某一服務器
    # 即配置用於負載均衡的服務器羣信息
    upstream tomcats{
        fair;
        server 121.42.41.143:8080;
        server 219.133.55.36;
    }
    server {
        listen       80;
        server_name  121.42.41.143;
        access_log  logs/tomcat-nginx.access.log  combined;
        # 反向代理設置,將全部/路徑下請求發給本機上的tomcat
        location / {
            #root   html;
            index  index.html index.htm;
            #==========Nginx提供的代理============
            proxy_set_header X-Forwarded-Host $host;
            proxy_set_header X-Forwarded-Server $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://tomcats;
        }
   }
}

二、使用該配置文件啓動nginx (啓動前先關閉nginx)nginx

    [root@iZ28b4kreuaZ bin]# /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx-tomcat.confweb

2、配置文件詳解:

worker_processes  2;

events {   
    worker_connections  1024;    
}


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

    # upstream 配置一組後端服務器,
    # 請求轉發到upstream後,nginx按策略將請求指派出某一服務器
    # 即配置用於負載均衡的服務器羣信息
    upstream backends {
        #=========均衡策略=============
        #none 輪詢(權重由weight決定)
        #ip_hash  經過hash算法將用戶的請求與第一次請求的服務器進行綁定,後續該用戶全部的請求都將被分配到該服務器上。除非該服務器掛掉。
        #==============  第三方 均衡策略===========
        #fair  根據各個服務器的性能的不一樣,自動選擇使用響應能力強的服務器。
        #url_hash 根據url選擇服務器。 

        #===============服務器集==============
        server 192.168.1.62:8080;
        server 192.168.1.63;
        
        #==========weight權重策略:權重值越高負載越大==========
        # server 192.168.1.64 weight=5;

        
        #===============backup:備份機,只有非備份機都掛掉了才啓用===============
        server 192.168.1.64 backup;
        
        #==============down: 停機標誌,不會被訪問(對臨時維護的服務器設置)=============
        server 192.168.1.65 down;

        # max_fails:達到指定次數認爲服務器掛掉;
        # fail_timeout:掛掉以後過多久再去測試是否已恢復
        server 192.168.1.66 max_fails=2 fail_timeout=60s;
    }

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }
        
        # 反向代理設置,將全部/proxy_test/路徑下請求發給本機上的tomcat
        location /proxy_test/ {
            proxy_pass http://localhost:8080;
        }
        
        # 負載均衡設置,將全部jsp請求發送到upstream backends指定的服務器羣上
        location ~ \.jsp$ {
            proxy_pass http://backends;
            
            # 真實的客戶端IP
            proxy_set_header   X-Real-IP        $remote_addr; 
            # 請求頭中Host信息
            proxy_set_header   Host             $host; 
            # 代理路由信息,此處取IP有安全隱患
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
            # 真實的用戶訪問協議
            proxy_set_header   X-Forwarded-Proto $scheme;
            # 默認值default,
            # 後端response 302時 tomcat header中location的host是http://192.168.1.62:8080
            # 由於tomcat收到的請求是nginx發過去的, nginx發起的請求url host是http://192.168.1.62:8080
            # 設置爲default後,nginx自動把響應頭中location host部分替換成當前用戶請求的host部分
            # 網上不少教程將此值設置成 off,禁用了替換,
            # 這樣用戶瀏覽器收到302後跳到http://192.168.1.62:8080,直接將後端服務器暴露給瀏覽器
            # 因此除非特殊須要,不要設置這種多此一舉的配置
            proxy_redirect default;
        }
        
        # 一個url重寫的例子,瀏覽器請求 /page.go時,url被重寫成/test/page.jsp
        location ~ \.go$ {
            rewrite ^(.*)\.go$ /test/$1\.jsp last;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }
}
View Code

 

3、fair策略的安裝

fair策略:根據各個服務器的性能的不一樣,自動選擇使用響應能力強的服務器。該策略是第三方提供的,因此要先安裝。ajax

安裝步驟redis

一、下載 gnosek-nginx-upstream-fair-a18b409.tar.gz算法

二、解壓  tar zxvf gnosek-nginx-upstream-fair-a18b409.tar.gzapache

三、將解壓後的文件移動到 /usr/local目錄下並 更名爲 nginx-upstream-fairjson

四、將該模塊添加到咱們安裝的nginx中

a、首先進入nginx-1.8.1源文件目錄下在執行:

[root@iZ28b4kreuaZ nginx-1.8.1]# ./configure --prefix=/usr/local/nginx --add-module=/usr/local/nginx-upstream-fair/

b、執行:make    進行編譯

c、進入 nginx-1.8.1/objs/下將最新的nginx啓動項 覆蓋原來的 /usr/local/nginx/sbin/nginx啓動項。

    [root@iZ28b4kreuaZ objs]# cp nginx /usr/local/nginx/sbin

d、開啓Nginx 看看是可使用

 4、在分佈式服務器集羣中session共享問題

問題:當咱們的用戶在tomcat1服務器上登陸後,tomcat1會保存用戶的登陸信息,但當用戶的請求被代理服務器分配給tomcat2/tomcat3服務器時,這時就會出現tomcat2/tomcat3沒法獲取用戶登陸信息,從而致使用戶須要從新登陸的現象。咱們有三種解決方案:

一、同一個用戶的請求鎖定在同一臺服務器上,這樣就不會存在session在不一樣服務器之間共享問題。這種方案簡單,但缺少容錯性(一旦服務器故障,那用戶的請求將被分配給其餘服務器,這時就須要從新登陸)

實現方式:設置集羣策略爲 ip_hash ;

 upstream tomcats{
        ip_hash;
    }

二、session複製方式: 當任何服務器中session值發生改變,他都會將該改變廣播給其餘服務器,當其餘服務器收到廣播後也作相應的改變,從而實現session在全部服務器中一直。缺點 當集羣中tomcat服務器不少時會增長網絡負荷,性能低下。實現方式:

a、在tomcat的server.xml中配置session廣播

      <!-- 基於網絡廣播的策略,一個節點session變化,其它節點同步複製,節點多或數據量大時性能低下 -->
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster">
        <Channel className="org.apache.catalina.tribes.group.GroupChannel">   
            <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"  
                      address="192.168.6.223"  
                      port="8080"/> 
        </Channel>
      </Cluster>

b、在咱們的分佈式應用的web.xml 中添加 <distributable/>標籤

<distributable/>:做用是公告咱們的應用能夠處於集羣環境中。

 三、經過建立額外的共享空間用來管理session,通常咱們使用分佈式緩存技術redis、memcached緩存技術,在這裏我麼使用memcached。

  a、memcached的安裝:http://www.cnblogs.com/jalja/p/6121978.html

  b、memcached 的 session共享原理

   粘性共享:

  非粘性:

c、tomcat訪問memcached的相關環境(咱們使用的是tomcat7)

  1. 複製jar包到tomcat/lib目錄,jar分三類

    1)spymemcached.jar memcached java客戶端        

    2)memcached相關的包  memcached-session-manager-{version}.jar       核心包         memcached-session-manager-tc{tomcat-version}-{version}.jar   Tomcat版本相關的包

    3)序列化工具包,有多種可選方案,不設置時使用jdk自帶序列化,其它可選kryo,javolution,xstream,flexjson等   msm-{tools}-serializer-{version}.jar  其它序列化工具相關包  通常第三方序列化工具不須要實現serializable接口

d、配置Context,加入處理session的Manager  MemcachedBackupSessionManager
 Context配置查找順序:
        1)conf/context.xml 全局配置,做用於全部應用
        2) conf/[enginename]/[hostname]/context.xml.default 全局配置,做用於指定host下所有應用
        3) conf/[enginename]/[hostname]/[contextpath].xml 只做用於contextpath指定的應用
        4) 應用META-INF/context.xml 只做用於本應用
        5) conf/server.xml <Host>下 做用於Context docBase指定的應用
         若是隻但願session管理做用於特定應用,最好用3,4方式設置,但願做用全體,可用1,2,5設置

 conf/context.xml的配置:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 
 3 <Context>
 4 
 5     <WatchedResource>WEB-INF/web.xml</WatchedResource>
 6     <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
 7 
 8     <!-- sticky session 最小配置-->
 9     <!-- className 管理器類名 -->
10     <!-- memcachedNodes memcached服務器節點,以節點名:主機:端口形式表示,其中節點名隨意命名,但不一樣tomcat間要一致 -->
11     <!-- sticky隱含默認值爲true,此時爲sticky session模式 -->
12     <!-- failoverNodes 僅適用於sticky模式, n1表示主要將session備份到n2,若是n2不可用,再用n1-->
13     <!-- 另外一臺服務器配置正好相反,這樣保證將session保存到其它機器,避免整個機器崩潰時tomcat與session一塊兒崩潰-->
14     <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
15         memcachedNodes="n1:192.168.1.62:11211,n2:192.168.1.63:11211"
16         failoverNodes="n1"
17     />
18     
19     <!-- 常常用到的生產環境sticky(粘性)模式配置 -->
20     <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
21         memcachedNodes="n1:192.168.1.62:11211,n2:192.168.1.63:11211"
22         failoverNodes="n1"
23         requestUriIgnorePattern=".*\.(jpg|png|css|js)$" 
24         memcachedProtocol="binary"
25         transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
26     />
27     
28     <!-- 常常用到的生產環境non-sticky(非粘性模式)模式配置 -->
29     <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
30         memcachedNodes="n1:192.168.1.62:11211,n2:192.168.1.63:11211"
31         sticky="false"
32         sessionBackupAsync="false"
33         lockingMode="auto"
34         requestUriIgnorePattern=".*\.(jpg|png|css|js)$" 
35         memcachedProtocol="binary"
36         transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
37     />
38     
39     <!--
40     <Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
41         memcachedNodes="n1:192.168.1.62:11211,n2:192.168.1.63:11211"
42         
43         #sticky模式,默認true
44         sticky="false"
45         
46         #僅適用於sticky模式,n1表示主要將session備份到n2,若是n2不可用,再用n1
47         failoverNodes="n1"
48         
49         #忽略的請求類型,這些類型請求不處理session
50         requestUriIgnorePattern=".*\.(jpg|png|css|js)$" 
51         
52         #例如context中設置sessionPath=/時,一個host下多個應用可能有相同session_id,
53         #此時向memcached寫入時會形成混亂,可經過如下方式加前綴區分不一樣應用
54         storageKeyPrefix="static:name|context|host|webappVersion|context.hash|host.hash|多項組合,以,間隔"
55         
56         #設置mecached協議數據傳輸方式,默認text,設爲binary有助力性能提高
57         memcachedProtocol="binary"
58         
59         #是否異步存儲session變化,默認true,性能好,適用於sticky模式,
60         #non-sticky時建議設置爲false,避免延遲形成信息不一致
61         sessionBackupAsync="false"
62         
63         #僅適用於non-sticky模式,爲避免同步編輯衝突,在修改session時鎖定
64         #同步編輯一種可能發生的狀況是在ajax請求時,同一頁多個請求同時發起,可能會訪問不一樣後端
65         #auto 讀模式不鎖寫模式鎖
66         #uriPattern模式,將URI+"?"+queryString與模式Regex匹配,若是匹配則鎖定
67         lockingMode="none|all|auto|uriPattern:Regex"
68         
69         #使用第三方序列化工具,提升序列化性能
70         #經常使用的第三方工具kryo, javolution, xstream等
71         #此時須要向tomcat/lib下添加相關jar包
72         transcoderFactoryClass="de.javakaffee.web.msm.serializer.kryo.KryoTranscoderFactory"
73         
74     />
75     -->
76    
77 </Context>
View Code

 4、集羣環境開發注意事項

一、實體類要序列化( implements Serializable)

private static final long serialVersionUID = 3349238980725146825L;

二、獲取客戶端請求地址的方式 。在nginx-tomcat.conf中添加以下配置:

   server {
        location / {
            proxy_set_header   X-Real-IP        $remote_addr; # 真實的客戶端IP
        }
   }

java代碼:

public static String  getIp(HttpServletRequest request){
        String remoteIp =request.getRemoteAddr();
        String headIp=request.getHeader("X-Real-IP");
        return headIp==null?remoteIp:headIp;
    }

三、動靜分離   把靜態文件放在nginx服務器中(css、js、圖片)

相關文章
相關標籤/搜索