1. 程式人生 > >nginx會話保持之sticky模塊

nginx會話保持之sticky模塊

pat gif nginx日誌 exp group name 請求分發 tar art

nginx會話保持之nginx-sticky-module模塊

在使用負載均衡的時候會遇到會話保持的問題,常用的方法有:
1.ip hash,根據客戶端的IP,將請求分配到不同的服務器上;
2.cookie,服務器給客戶端下發一個cookie,具有特定cookie的請求會分配給它的發布者,
註意:cookie需要瀏覽器支持,且有時候會泄露數據

1.Sticky工作原理 :

Sticky是nginx的一個模塊,它是基於cookie的一種nginx的負載均衡解決方案,通過分發和識別cookie,來使同一個客戶端的請求落在同一臺服務器上,默認標識名為route
1.客戶端首次發起訪問請求,nginx接收後,發現請求頭沒有cookie,則以輪詢方式將請求分發給後端服務器。
2.後端服務器處理完請求,將響應數據返回給nginx。
3.此時nginx生成帶route的cookie,返回給客戶端。route的值與後端服務器對應,可能是明文,也可能是md5、sha1等Hash值
4.客戶端接收請求,並保存帶route的cookie。
5.當客戶端下一次發送請求時,會帶上route,nginx根據接收到的cookie中的route值,轉發給對應的後端服務器。

2.重新編譯nginx增加nginx-sticky-module模塊

查詢bitbucket.org上的該模塊相關文檔

https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/overview

# 查詢當前的nginx編譯參數可以使用以下命令:

技術分享圖片
[root@nginx ~]# mkdir -p /server/tools
[root@nginx ~]# cd /server/tools
[root@nginx tools]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.8.0
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) 
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module 
技術分享圖片

# 下載該模塊的軟件包()
# 其他平臺上的nginx-sticky-module模塊包多是國外的資源的不方便下載,找到GITHUB上面的該軟件包

[root@nginx tools]# wget https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng/get/08a395c66e42.zip

# 解壓

[root@nginx tools]# unzip -D nginx-goodies-nginx-sticky-module-ng-08a395c66e42.zip 
[root@nginx tools]# mv nginx-goodies-nginx-sticky-module-ng-08a395c66e42 nginx-sticky-module-ng

# 備份之前的nginx目錄(註意:nginx日誌可能很大)

[root@nginx tools]# cp -rf /usr/local/nginx/ /server/backup/

# 進入到之前編譯好的nginx目錄下,重新進行編譯安裝

# 註意:是覆蓋安裝

[root@nginx tools]# cd nginx-1.8.0
[root@nginx nginx-1.8.0]# ./configure --prefix=/usr/local/nginx  --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module --add-module=/server/tools/nginx-sticky-module-ng
[root@nginx nginx-1.8.0]# make
[root@nginx nginx-1.8.0]# make install

# 安裝完再次查看nginx編譯參數

技術分享圖片
[root@nginx tools]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.8.0
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC) 
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-http_ssl_module --add-module=/server/tools/nginx-sticky-module-ng
技術分享圖片

# 需要重新啟動nginx才可以使用sticky模塊

[root@nginx tools]# service nginx restart

# 編輯配置文件,實例:

upstream www_web_com {
#   ip_hash;
   sticky expires=1h domain=web.com path=/;
   server 10.0.0.16:8080;
   server 10.0.0.17:8080;
}

# 具體的配置根據公司的相關業務配置即可

# 之後打開網站進行測試,使用sticky的情況下,不管怎麽刷新都是如下結果

# 不使用Nginx sticky模塊時,刷幾次就變了(有時候刷一次,有時候多刷幾次)

技術分享圖片

備註:每臺後端真實服務器都會有一個唯一的route值,所以不管你真實服務器前端有幾個裝了sticky的nginx代理,他都是不會變化的.

3.sticky模塊的使用

# 位置:upstream標簽內

upstream {
  sticky;
  server 127.0.0.1:9000;
  server 127.0.0.1:9001;
  server 127.0.0.1:9002;
}

# 參數,解析

sticky [name=route] [domain=.foo.bar] [path=/] [expires=1h] 
       [hash=index|md5|sha1] [no_fallback] [secure] [httponly];
技術分享圖片
[name=route]       設置用來記錄會話的cookie名稱
[domain=.foo.bar]    設置cookie作用的域名
[path=/]          設置cookie作用的URL路徑,默認根目錄
[expires=1h]        設置cookie的生存期,默認不設置,瀏覽器關閉即失效,需要是大於1秒的值
[hash=index|md5|sha1]   設置cookie中服務器的標識是用明文還是使用md5值,默認使用md5
[no_fallback]       設置該項,當sticky的後端機器掛了以後,nginx返回502 (Bad Gateway or Proxy Error) ,而不轉發到其他服務器,不建議設置
[secure]          設置啟用安全的cookie,需要HTTPS支持
[httponly]         允許cookie不通過JS泄漏,沒用過
技術分享圖片

官方說明:

技術分享圖片
name: the name of the cookies used to track the persistant upstream srv; default: route
domain: the domain in which the cookie will be valid default: nothing. Let the browser handle this.
path: the path in which the cookie will be valid default: /
expires: the validity duration of the cookie default: nothing. It‘s a session cookie. restriction: must be a duration greater than one second
hash: the hash mechanism to encode upstream server. It cant‘ be used with hmac. default: md5
md5|sha1: well known hash
index: it‘s not hashed, an in-memory index is used instead, it‘s quicker and the overhead is shorter Warning: the matching against upstream servers list is inconsistent. So, at reload, if upstreams servers has changed, index values are not guaranted to correspond to the same server as before! USE IT WITH CAUTION and only if you need to!
hmac: the HMAC hash mechanism to encode upstream server It‘s like the hash mechanism but it uses hmac_key to secure the hashing. It can‘t be used with hash. md5|sha1: well known hash default: none. see hash.
hmac_key: the key to use with hmac. It‘s mandatory when hmac is set default: nothing.
no_fallback: when this flag is set, nginx will return a 502 (Bad Gateway or Proxy Error) if a request comes with a cookie and the corresponding backend is unavailable.
secure enable secure cookies; transferred only via https
httponly enable cookies not to be leaked via js
技術分享圖片

4.其他的參數:語法:

以下內容摘錄於:http://blog.csdn.net/yu870646595/article/details/52056340

session_sticky [cookie=name] [domain=your_domain] [path=your_path] [maxage=time][mode=insert|rewrite|prefix] 
         [option=indirect] [maxidle=time] [maxlife=time] [fallback=on|off] [hash=plain|md5]
技術分享圖片
mode設置cookie的模式:
  insert: 在回復中本模塊通過Set-Cookie頭直接插入相應名稱的cookie。
  prefix: 不會生成新的cookie,但會在響應的cookie值前面加上特定的前綴,當瀏覽器帶著這個有特定標識的cookie再次請求時,模塊在傳給後端服務前先刪除加入的前綴,後端服務拿到的還是原來的cookie值,這些動作對後端透明。如:”Cookie: NAME=SRV~VALUE”。
  rewrite: 使用服務端標識覆蓋後端設置的用於session sticky的cookie。如果後端服務在響應頭中沒有設置該cookie,則認為該請求不需要進行session sticky,使用這種模式,後端服務可以控制哪些請求需要sesstion sticky,哪些請求不需要。
option設置用於session sticky的cookie的選項,可設置成indirect或direct。indirect不會將session sticky的cookie傳送給後端服務,該cookie對後端應用完全透明。direct則與indirect相反。
maxidle設置session cookie的最長空閑的超時時間
maxlife設置session cookie的最長生存期
maxage是cookie的生存期。不設置時,瀏覽器或App關閉後就失效。下次啟動時,又會隨機分配後端服務器。所以如果希望該客戶端的請求長期落在同一臺後端服務器上,可以設置maxage。
hash不論是明文還是hash值,都有固定的數目。因為hash是server的標識,所以有多少個server,就有等同數量的hash值。
技術分享圖片

5.其他需要註意的
1.同一客戶端的請求,有可能落在不同的後端服務器上
如果客戶端啟動時同時發起多個請求。由於這些請求都沒帶cookie,所以服務器會隨機選擇後端服務器,返回不同的cookie。當這些請求中的最後一個請求返回時,客戶端的cookie才會穩定下來,值以最後返回的cookie為準。
2.cookie不一定生效
由於cookie最初由服務器端下發,如果客戶端禁用cookie,則cookie不會生效。
3.客戶端可能不帶cookie
Android客戶端發送請求時,一般不會帶上所有的cookie,需要明確指定哪些cookie會帶上。如果希望用sticky做負載均衡,請對Android開發說加上cookie。
4.cookie名稱不要和業務使用的cookie重名。Sticky默認的cookie名稱是route,可以改成任何值。
5.客戶端發的第一個請求是不帶cookie的。服務器下發的cookie,在客戶端下一次請求時才能生效。

6.Nginx sticky模塊不能與ip_hash同時使用

其他使用方法可以參考以下:

http://tengine.taobao.org/document_cn/http_upstream_session_sticky_cn.html

# 完畢,呵呵呵

nginx會話保持之sticky模塊