Nginx Sticky的使用及踩過的坑(nginx-sticky-module)
#什麼是Sticky?# 為了理解Sticky的工作原理,我們可以先考慮一個問題:負載均衡怎麼做?
DNS解析,在域名解析時分配給不同的伺服器IP;
IP Hash,根據客戶端的IP,將請求分配到不同的伺服器上;
cookie,伺服器給客戶端下發一個cookie,具有特定cookie的請求會分配給它的發行者。
Sticky就是基於cookie的一種負載均衡解決方案,通過cookie實現客戶端與後端伺服器的會話保持, 在一定條件下可以保證同一個客戶端訪問的都是同一個後端伺服器。請求來了,伺服器發個cookie,並說:下次來帶上,直接來找我。
為方便敘述,文中的cookie都指sticky使用的cookie。
#Sticky工作原理 Sticky是nginx的一個模組,通過分發和識別cookie,來使同一個客戶端的請求落在同一臺伺服器上。sticky的處理過程如下(假設cookie名稱為route):
1.客戶端首次發起請求,請求頭未帶route的cookie。nginx接收請求,發現請求頭沒有route,則以輪詢方式將請求分配給後端伺服器。
2.後端伺服器處理完請求,將響應頭和內容返回給nginx。
3.nginx生成route的cookie,返回給客戶端。route的值與後端伺服器對應,可能是明文,也可能是md5、sha1等Hash值。
4.客戶端接收請求,並建立route的cookie。
5.客戶端再次傳送請求時,帶上route。
6.nginx接收到route,直接轉給對應的後端伺服器。
關於sticky的詳細的配置過程在 這裡。
#引數解析
這裡引用淘寶Tengine的文件:
語法: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]
預設值:session_sticky cookie=route mode=insert fallback=on
上下文:upstream
說明:
本指令可以開啟會話保持的功能,下面是具體的引數:
cookie設定用來記錄會話的cookie名稱
domain設定cookie作用的域名,預設不設定
path設定cookie作用的URL路徑,預設不設定
maxage設定cookie的生存期,預設不設定,即為session cookie,瀏覽器關閉即失效
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的最長生存期
fallback設定是否重試其他機器,當sticky的後端機器掛了以後,是否需要嘗試其他機器
hash 設定cookie中server標識是用明文還是使用md5值,預設使用md5
maxage是cookie的生存期。不設定時,瀏覽器或App關閉後就失效。下次啟動時,又會隨機分配後端伺服器。所以如果希望該客戶端的請求長期落在同一臺後端伺服器上,可以設定maxage。
hash不論是明文還是hash值,都有固定的數目。因為hash是server的標識,所以有多少個server,就有等同數量的hash值。
#一些例外#
##同一客戶端的請求,有可能落在不同的後端伺服器上## 如果客戶端啟動時同時發起多個請求。由於這些請求都沒帶cookie,所以伺服器會隨機選擇後端伺服器,返回不同的cookie。當這些請求中的最後一個請求返回時,客戶端的cookie才會穩定下來,值以最後返回的cookie為準。
##cookie不一定生效## 由於cookie最初由伺服器端下發,如果客戶端禁用cookie,則cookie不會生效。
##客戶端可能不帶cookie## Android客戶端傳送請求時,一般不會帶上所有的cookie,需要明確指定哪些cookie會帶上。如果希望用sticky做負載均衡,請對Android開發說加上cookie。
#注意事項 * cookie名稱不要和業務使用的cookie重名。Sticky預設的cookie名稱是route,可以改成任何值。但切記,不可以與業務中使用的cookie重名。 * 客戶端發的第一個請求是不帶cookie的。伺服器下發的cookie,在客戶端下一次請求時才能生效。
Published: August 01 2015
- Category:
- 伺服器 3