1. 程式人生 > >Linux下Nginx+Resin負載均衡,session問題解決例項

Linux下Nginx+Resin負載均衡,session問題解決例項

                     Linux下Nginx+Resin負載均衡,session問題解決例項

 

轉載:http://blog.chinaunix.net/uid-14007440-id-3150269.html
https://guying1028.iteye.com/blog/1746685

本文通過cookie_session來判別,解決了Nginx session不同步問題。
 

 nginx_upstream_jvm_route模組(打補丁時可能會失敗,需要查詢到合適的nginx版本)

這個模組通過session cookie的方式來獲取session粘性。如果在cookie和url中並沒有session,則這只是個簡單的round-robin 負載均衡。

1. 一開始請求過來,沒有帶session資訊,jvm_route就根據round robin的方法,發到一臺resin上面。

2. resin新增上session 資訊,並返回給客戶。
3. 使用者再提交此請求,jvm_route看到session中有後端伺服器的名稱,它就把請求轉到對應的伺服器上。

暫時jvm_route模組還不支援預設fair的模式。jvm_route的工作模式和fair是衝突的。對於某個特定使用者,當一直為他服務的 resin宕機後,

預設情況下它會重試max_fails的次數,如果還是失敗,就重新啟用round robin的方式,而這種情況下就會導致使用者的session丟失。

總的說來,jvm_route是通過session_cookie這種方式來實現session粘性,將特定會話附屬到特定resin上,從而解決session不同步問題,

但無法解決宕機後會話轉移問題。

 

測試環境:

server1   伺服器上安裝了  nginx + resin

server2  伺服器上只安裝了 resin          

 

server1  IP 地址: 192.168.179.200

server2  IP 地址: 192.168.179.201

 在server1 上安裝配置 nginx + nginx_upstream_jvm_route

nginx-0.7.59.tar.gz的下載地址:
http://nginx.org

使用nginx-upstream-jvm-route-read-only模組(下載地址需要翻牆才能下載):

https://code.google.com/archive/p/nginx-upstream-jvm-route/downloads

resin的下載地址:
http://caucho.com/download/resin-4.0.53.tar.gz

安裝nginx
首先
缺少輔助環境(pcre、zlib、openssl、gcc)

yum -y install pcre-devel
yum -y install openssl openssl-devel
yum install -y zlib-devel
yum -y install gcc

 

 #nginx放在/usr/local目錄下

cd nginx

#給nginx打補丁,檔案在當前目錄

patch -p0 < ../nginx_upstream_jvm_route/jvm_route.patch

新增使用者

 useradd www

安裝nginx

#配置
./configure --user=www --group=www  --with-http_ssl_module  --add-module=/usr/local/nginx_upstream_jvm_route
#編譯 
make
#安裝
make install


打補丁時可能報錯

bash: patch: command not found...


安裝patch即可

 yum -y install patch 


執行補丁命令再報錯(版本不相容)

[[email protected] nginx]# patch -p0 < ../nginx_upstream_jvm_route/jvm_route.patch
patching file src/http/ngx_http_upstream.c
Hunk #1 succeeded at 5670 with fuzz 1 (offset 1933 lines).
Hunk #2 succeeded at 5768 with fuzz 2 (offset 1939 lines).
Hunk #3 succeeded at 5787 with fuzz 1 (offset 1918 lines).
Hunk #4 FAILED at 3922.
Hunk #5 succeeded at 5901 with fuzz 1 (offset 1949 lines).
1 out of 5 hunks FAILED -- saving rejects to file src/http/ngx_http_upstream.c.rej
patching file src/http/ngx_http_upstream.h
Hunk #1 FAILED at 85.
Hunk #2 FAILED at 97.
Hunk #3 FAILED at 111.
3 out of 3 hunks FAILED -- saving rejects to file src/http/ngx_http_upstream.h.rej


檢視官網的wiki
nginx-upstream-jvm-route - nginx_with_resin.wiki
地址:https://code.google.com/archive/p/nginx-upstream-jvm-route/wikis/nginx_with_resin.wiki

Nginx's configure
``` upstream backend { server 192.168.0.100 srun_id=a; server 192.168.0.101 srun_id=b;

jvm_route $cookie_JSESSIONID;
} ```

Resin's configure
For all resin servers <server id="a" address="192.168.0.100" port="8080"> <http id="" port="80"/> </server> <server id="b" address="192.168.0.101" port="8080"> <http id="" port="80"/> </server>

And start each resin instances like this:

server a

shell $> /usr/local/resin/bin/httpd.sh -server a start

server b

shell $> /usr/local/resin/bin/httpd.sh -server b start



分別在兩臺機器上 安裝 resin

cd resin
 ./configure --prefix=/usr/local/resin
make
make install

配置兩臺機器 的 resin
 

cd /usr/local/resin/conf
vim resin.conf

 

##  查詢     <http address="*" port="8080"/>

## 註釋掉 <!--http address="*" port="8080"/-->

## 查詢      <server id="" address="127.0.0.1" port="6800">

## 替換成       

server1

    <server id="a" address="192.168.179.200" port="8080">
    <http id="" port="80"/>
    </server>

  


server2

  <server id="b" address="192.168.179.201" port="8080">
    <http id="" port="80"/>
    </server>


編寫index.jsp的內容

cd /usr/local/resin/webapps/ROOT/

#備份
mv index.jsp   index.jsp.bak

vim index.jsp


index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
%>
<html>
  <head>
    </head>
      <body>
        121
       <!--server2  這裡為 162 -->
        <br />
       <%out.print(request.getSession()) ;%>
       <!--輸出session-->
        <br />
        <%out.println(request.getHeader("Cookie")); %>
      <!--輸出Cookie--> 
      </body>
 </html>

 

重啟

4.整合 ngxin  resin

cd /usr/local/nginx/conf
mv nginx.conf nginx.bak
vim nginx.conf

## 以下是配置 ###

user  www www;
worker_processes 4;
error_log  logs/nginx_error.log  crit;
pid        /usr/local/nginx/nginx.pid;
#Specifies the value for maximum file descriptors that can be opened by this process.
worker_rlimit_nofile 51200;
events
{
 use epoll;
 worker_connections 2048;
}
http
{
  upstream backend {
    server 192.168.179.200:8080 srun_id=a; 
    ####  這裡 srun_id=a   對應的是 server1  resin 配置裡的 server id="a"
    server 192.168.179.201:8080 srun_id=b;
    ####  這裡 srun_id=b   對應的是 server2 resin 配置裡的 server id="b"
    jvm_route $cookie_JSESSIONID|sessionid;
  }
 include       mime.types;
 default_type  application/octet-stream;
 #charset  gb2312;
 charset UTF-8;
 server_names_hash_bucket_size 128;
 client_header_buffer_size 32k;
 large_client_header_buffers 4 32k;
 client_max_body_size 20m;
 limit_rate  1024k;
 sendfile on;
 tcp_nopush     on;
 keepalive_timeout 60;
 tcp_nodelay on;
 fastcgi_connect_timeout 300;
 fastcgi_send_timeout 300;
 fastcgi_read_timeout 300;
 fastcgi_buffer_size 64k;
 fastcgi_buffers 4 64k;
 fastcgi_busy_buffers_size 128k;
 fastcgi_temp_file_write_size 128k;
 gzip on;
#gzip_min_length  1k;
 gzip_buffers     4 16k;
 gzip_http_version 1.0;
 gzip_comp_level 2;
 gzip_types       text/plain application/x-javascript text/css application/xml;
 gzip_vary on;
 #limit_zone  crawler  $binary_remote_addr  10m;
server
 {
   listen       80;
   server_name  192.168.179.200;
   index index.html index.htm index.jsp;
   root  /var/www;

   location ~ .*\.jsp$
   {
     proxy_pass  http://backend ;
     proxy_redirect    off;
     proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
     proxy_set_header  X-Real-IP  $remote_addr;
     proxy_set_header  Host $http_host;
   }
   location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
   {
     expires      30d;
   }
   location ~ .*\.(js|css)?$
   {
     expires      1h;
   }
   location /stu {
     stub_status on;
     access_log   off;
   }
  log_format  access  '$remote_addr - $remote_user [$time_local] "$request" '
             '$status $body_bytes_sent "$http_referer" '
             '"$http_user_agent" $http_x_forwarded_for';
#  access_log  off;
  }

}

重啟nginx

5.測試,開啟瀏覽器,輸入 http://192.168.179.200/index.jsp
session  顯示 aXXXXX  訪問的是 200 伺服器也就是  server1,因為是第一次訪問所以Cookie 沒有獲得,重新整理一下看他是否輪詢會訪問到201 server2.
重新整理 N 遍後仍然是 200,也就是補丁起作用了,cookie 值 也獲得了,為了測試,我又打開了 “火狐瀏覽器”(因為session 和 cookie問題所以從新開啟別的瀏覽器),輸入網址:
 http://192.168.179.200/index.jsp
顯示的是 201,session 值 是以 bXXX 開頭的,重新整理 N遍後:

仍然是 201  server 2伺服器!!大家測試的時候如果有疑問可一把 nginx 配置檔案的

srun_id=a  srun_id=b 去掉,然後在訪問,就會知道 頁面是輪詢訪問得了!!