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 去掉,然後在訪問,就會知道 頁面是輪詢訪問得了!!