1. 程式人生 > >nginx 在瀏覽器端保持cookie 一致

nginx 在瀏覽器端保持cookie 一致

http 內存 11.11 proxy con backup 用戶登陸 需要 etc

一般來說,我們在java中都通過如下代碼進行用戶登錄後的服務端註冊,並且在用戶下次請求時無需再登陸一遍,這就是Servlet的Session。使用了這種Session策略,那麽Web容器比如tomcat就為當前用戶生成一個SessionID,並且以這個SessionID為索引,存儲這個用戶相關的鍵值對,比如用戶名,登陸時間一類的。存儲在服務器的內存中。同時再response裏向用戶瀏覽器中設置一個cookie,這個cookie的名字為jsessionid,內容為服務器生成的隨機數SessionID。在用戶第二次請求時,將這個cookie發給服務器,服務器根據這個SessionID到內存中尋找相關數據,把用戶名什麽的提取出來,服務器就可以在本來無狀態的HTTP連接中識別出這是哪個客戶發出的請求,然後繪制相關頁面。
這中Session機制使用簡單方便,被使用了很長時間。但是一旦做成集群,這種方式就不靈了。以NGINX默認的輪詢方式為例,用戶在A服務器上登陸成功,SessionID和用戶名等相關信息寫入了A服務器的內存中,該用戶第二次請求時被NGINX分發到了B服務器,而B服務器沒用該用戶的SessionID和用戶名等相關信息,於是要求用戶再登陸一遍。用戶第二次登陸之後發送第三次請求,被NGINX分配到了A或者C服務器,於是用戶又必須登陸一遍,總之這個用戶一直沒法登陸成功。

基於以上現象,有幾種存儲session 的方法,如下:

1. 數據庫存儲session

2.使用 memcached,redis等存儲session

3. 使用nginx 內置模塊,ip_hash

4. 使用cookie的HASH來區分同一個用戶的不同鏈接

前面我們已經知道了如果使用Servlet Session的話,Web容器會自動的在用戶瀏覽器上建立名為jsessionid的cookie,並且值就是服務器端的SessionID。另一方面,新版的NGINX不光可以通過IP的hash來分發流量,也可以通過url的hash,cookie的hash,header的hash等等進行鏈接的固定分配。由於用戶登陸成功以後名為jsessionid的cookie就有了一個短期固定的值,而且每個用戶都不一樣,那麽我們就可以根據這個sessionid的hash值為它分配一個服務器。在當前sessionID起作用的時候那麽分配的服務器也是同一個,並且不需要安裝第三方的插件。

本次使用第4種方法,使用cookie 是用戶分配的服務器是同一個。nginx 配置如下:

[root@www vhosts]# cat load.conf

upstream tomcat_server {

hash $cookie_jsessionid;

# hash $request_uri;

server 172.16.31.16:8080;

server 172.16.31.17:8080;

}

#error_page配置備份:

upstream backup {

server 11.11.11.14:80; }

error_page 404 500 502 503 504 =200 @fetch; #註意:=200裏的等號,左邊有空格,右邊沒空格

server {

listen 80;

server_name www.load.com;

root /data/wwwroot/www.load.com;

index index.html index.htm index.php;

access_log /usr/local/nginx/logs/www.load.com-access.log gufan;

error_log /usr/local/nginx/logs/www.load.com-error.log;

location /stat {

proxy_pass

http://tomcat_server;

proxy_set_header

Host $http_host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_intercept_errors on;

proxy_next_upstream off;

}

location @fetch {

proxy_pass http://backup;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

}

nginx 在瀏覽器端保持cookie 一致