haproxy 三種保持客戶端Seesion;
一、源地址hash(用戶IP識別)
haroxy 將用戶IP經過hash計算後 指定到固定的真實服務器上(類似於nginx 的IP hash 指令)。
缺陷,當後端一臺服務器掛了以後會造成部分session丟失。
配置指令
backend SOURCE_srv
mode http
balance source
server app-node1 10.31.1.179:80 check port 80 inter 3000 rise 3 fall 3
server app-node2 10.31.1.191:80 check port 80 inter 3000 rise 3 fall 3
server app-node3 10.31.0.35:80 check port 80 inter 3000 rise 3 fall 3
二、cookie 識別
haproxy 將WEB服務端返回給客戶端的cookie中插入haproxy中特定的字符串(或添加前綴)在後端的服務器COOKIE ID。
backend COOKIE_srv
mode http
cookie SERVERID insert indirectnocache
server app-node1 10.31.1.179:80 check port 80 cookie a inter 3000 rise 3 fall 3
server app-node2 10.31.1.191:80 check port 80 cookie b inter 3000 rise 3 fall 3
server app-node3 10.31.0.35:80 check port 80 cookie c inter 3000 rise 3 fall 3
cookie參數說明:
cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ] [ postonly ] [ preserve ] [ httponly ] [ secure ] [ domain <domain> ]* [ maxidle <idle> ] [ maxlife <life> ]
[ rewrite | insert | prefix ] /*三者互斥,只能選一*/
rewrite //表示cookie由服務器生成並且haproxy會在其值中注入該服務器的標識符;此關鍵字不能在HTTP隧道模式下工作。
insert //表示如果客戶端沒有cookie信息且有權限訪問服務器時,持久性cookie必須通過haproxy穿插在服務器的響應報文中。當服務器收到相同名稱的cookie並且沒有“preserve(保存)”選項時,將會移除之前已存的cookie信息。因此,insert可視作"rewrite"的升級版。cookie信息僅僅作爲會話cookie且不會存到客戶端的磁盤上。默認除非加了“indirect(間接)”選項,否則服務器端會看到客戶端端發送的cookie信息。由於緩存的影響,最好加上“nocache”或“postonly”選項。
prefix //表示不依賴專用的cookie做持久性,而是依賴現成的。用在某些特殊的場景,如客戶端不支持一個以上的cookie和應用程序需求它。每當服務器建立一個名爲<name>的cookie時,它將以服務器的標識符和分隔符爲前綴。來自於客戶端的請求報文中的前綴將會被刪除以便服務器端能識別出它所發出的cookie,由於請求和響應報文都被修改過,所以此模式不能工作在隧道模式中。且不能和“indirect”共用,否則服務器端更新的cookie將不會被髮到客戶端.
[ indirect ] //指定此選項時,將不會向客戶端發送服務器已經處理過請求的且可用的cookie信息。如果服務器設置這樣一個cookie本身,它將被刪除,除非“保存”選項也設置。在“插入”模式下,將從發送給服務器的請求中刪除cookie,使持久機制從應用程序的角度完全透明。
[ nocache ] //當客戶端和haproxy間存在緩存時,使用此選項和insert搭配最好,以便確保如果一個cookie需要被插入時,可被緩存的響應會被標記成不可緩存。這很重要,舉個例子:如果所有的持久cookie被添加到一個可緩存的主頁上,之後所有的客戶將從外部高速緩存讀取頁面並將共享相同的持久性cookie,會造成服務器阻塞。
在LB1上配置好HAProxy後,LB1將接受用戶的所有請求。如果一個用戶請求不包含任何cookie,那這個請求將被HAProxy轉發到一臺可用的WEB服務器。可能是webA,webB,webC或webD。然後HAProxy將把處理這個請求的WEB服務器的cookie值插入到請求響應中。如SERVERID=A。當這個客戶端再次訪問並在HTTP請求頭中帶有SERVERID=A,HAProxy將會把它的請求直接轉發給webA處理。在請求到達webA之前,cookie將被移除,webA將不會看到這個cookie。如果webA不可用,對應的請求將被轉發到其他可用的WEB服務器,相應的cookie值也將被重新設置。
三、基於session
haproxy 將後端服務器產生的session和後端服務器標識存在haproxy中的一張表裏。客戶端請求時先查詢這張表。
配置參數:appsession JSESSIONID len 64 timeout 5h request-learn
backend APPSESSION_srv
mode http
appsession JSESSIONID len 64 timeout 5h request-learn
server REALsrv_70 184.82.239.70:80 cookie 11 check inter 1500 rise 3 fall 3 weight 1
server REALsrv_120 220.162.237.120:80 cookie 12 check inter 1500 rise 3 fall 3 weight 1
注意使用事項;
(1).如果客戶端使用HTTP1.1(keep-alive),只有第一個響應纔會被插入cookie,並且HAProxy只會分析每個session的第一個請求。在使用cookie的插入模式下,可能不會造成什麼問題,因爲HAProxy會立即在第一個響應中插入cookie,同一個session中的所有請求將被轉發到同一臺服務器上。但是,到達服務器端的請求中的cookie不會被刪除,所以這要求後端服務器對來歷不明的cookie不作敏感處理。如果不想引起其他的問題,可以使用以下參數關掉keep-alive
option httpclose
(2).由於一些原因,一些客戶端不能識別多個cookie,並且後端應用已經設置了cookie,如果HAProxy再對響應插入cookie後,這些客戶端可能不能識別cookie。這種情況下,可以使用cookie的prefix模式。
(3).LB1成爲整個架構中的瓶頸,如果LB1不可用,那麼客戶端的所有請求都得不到響應。可以使用Keepalived配置HAProxy解決LB1單點故障的問題。
(4).在以上配置中後端服務器是看不到客戶端的真實IP地址的。可以使用 forwardfor 參數,它能夠在客戶端的請求頭中增加 X-Forwarded-For 字段。同時需要配置使用 httpclose 參數,確保每個請求都被重寫,而不只是第一個請求被重寫。
option httpclose
option forwardfor
後端WEB服務器上的Nginx的日誌格式需要增加$http_x_forwarded_for 變量;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
(5).在有些情況下,一些用戶會將他們的瀏覽器的cookie功能關閉。這時候可能沒法訪問WEB服務器的內容。這種情況下,可以使用HAProxy的 source 負載均衡算法替代 roundroubin算法。source 算法可以確保來自同一個IP的所有請求都到達同一臺WEB服務器,但是前提是,可用的服務器的數量保持不變。
(6).不要在一個小型網絡和代理服務器後面使用source 算法,因爲請求分發會不太公平,但是在大型內部網絡或互聯網上使用source算法,轉發效率很好。對於那些具有動態IP地址的客戶端,只要它們能夠接收cookie,那麼請求轉發就不會受到影響,因爲HAProxy對cookie的處理具有較高優先級。
————————————————————————————————————————————
其餘搭配方法:
backend NOSESSION_srv
mode http
balance roundrobin
server REALsrv_70 184.82.239.70:80 cookie 11 check inter 1500 rise 3 fall 3 weight 1
server REALsrv_12 220.162.23.12:80 cookie 12 check inter 1500 rise 3 fall 3 weight 1
backend ai_server
mode http
balance roundrobin
cookie SERVERID
server REALsrv_70 184.82.239.70:80 cookie 2 check inter 1500 rise 3 fall 3 weight 1
server REALsrv_12 220.162.23.12:80 cookie 1 check inter 1500 rise 3 fall 3 weight 1
————————————————————————————————————————————
cookie與session知識
Session:
Session是由應用服務器維持的一個服務器端的存儲空間,用戶在連接服務器時,會由服務器生成一個唯一的SessionID,用該SessionID 爲標識符來存取服務器端的Session存儲空間。
而SessionID這一數據則是保存到客戶端,用Cookie保存的,用戶提交頁面時,會將這一 SessionID提交到服務器端,來存取Session數據。
服務器也通過URL重寫的方式來傳遞SessionID的值,因此不是完全依賴Cookie。如果客戶端Cookie禁用,則服務器可以自動通過重寫URL的方式來保存Session的值,並且這個過程對程序員透明。
Session--“會話控制”。Session 對象存儲特定用戶會話所需的屬性及配置信息。這樣,當用戶在應用程序的 Web 頁之間跳轉時,存儲在 Session 對象中的變量將不會丟失,而是在整個用戶會話中一直存在下去。當用戶請求來自應用程序的 Web 頁時,如果該用戶還沒有會話,則 Web 服務器將自動創建一個 Session 對象。當會話過期或被放棄後,服務器將終止該會話。Session 對象最常見的一個用法就是存儲用戶的首選項。例如,如果用戶指明不喜歡查看圖形,就可以將該信息存儲在 Session 對象中。有關使用 Session 對象的詳細信息,請參閱“ASP 應用程序”部分的“管理會話”。注意 會話狀態僅在支持 cookie 的瀏覽器中保留。
Cookie:
是在 HTTP 協議下,服務器或腳本可以維護客戶工作站上信息的一種方式。Cookie 是由 Web 服務器保存在用戶瀏覽器(客戶端)上的小文本文件,它可以包含有關用戶的信息。無論何時用戶鏈接到服務器,Web 站點都可以訪問 Cookie 信息。
目前有些Cookie 是臨時的,有些則是持續的。臨時的 Cookie 只在瀏覽器上保存一段規定的時間,一旦超過規定的時間,該 Cookie 就會被系統清除。
持續的Cookie 則保存在用戶的 Cookie 文件中,下一次用戶返回時,仍然可以對它進行調用。在 Cookie 文件中保存 Cookie,有些用戶擔心 Cookie 中的用戶信息被一些別有用心的人竊取,而造成一定的損害。其實,網站以外的用戶無法跨過網站來獲得 Cookie 信息。如果因爲這種擔心而屏蔽 Cookie,肯定會因此拒絕訪問許多站點頁面。因爲,當今有許多 Web 站點開發人員使用 Cookie 技術,例如 Session 對象的使用就離不開 Cookie 的支持。