B5-Haproxy 與 Cookie
cookiehtml
1 什麼是cookie ?
參考 cookie
http://baike.baidu.com/view/835.htm
Cookie,有時也用其複數形式Cookies,指某些網站爲了辨別用戶身份、進行session跟蹤而儲存在用戶本地終端上的數據(一般通過加密)。定義於RFC2109(已廢棄),最新取代的規範是RFC2965。
Cookie是由服務器端生成,發送給User-Agent(通常是瀏覽器),瀏覽器會將Cookie的key/value保存到某個目錄下的文本文件內,下次請求同一網站時就發送該Cookie給服務器(前提是瀏覽器設置爲啓用cookie)。Cookie名稱和值能夠由服務器端開發本身定義,對於JSP而言也能夠直接寫入jsessionid,這樣服務器能夠知道該用戶是否合法用戶以及是否須要從新登陸等。
用途
服務器能夠利用Cookies包含信息的任意性來篩選並常常性維護這些信息,以判斷在HTTP傳輸中的狀態。Cookies最典型的應用是斷定註冊用戶是否已經登陸網站,用戶可能會獲得提示,是否在下一次進入此網站時保留用戶信息以便簡化登陸手續,這些都是Cookies的功用。另外一個重要應用場合是「購物車」之類處理。用戶可能會在一段時間內在同一家網站的不一樣頁面中選擇不一樣的商品,這些信息都會寫入Cookies,以便在最後付款時提取信息。
生存週期
Cookie能夠保持登陸信息到用戶下次與服務器的會話,換句話說,下次訪問同一網站時,用戶會發現沒必要輸入用戶名和密碼就已經登陸了(固然,不排除用戶手工刪除Cookie)。而還有一些Cookie在用戶退出會話的時候就被刪除了,這樣能夠有效保護我的隱私。
Cookie在生成時就會被指定一個Expire值,這就是Cookie的生存週期,在這個週期內Cookie有效,超出週期Cookie就會被清除。有些頁面將Cookie的生存週期設置爲「0」或負值,這樣在關閉頁面時,就立刻清除Cookie,不會記錄用戶信息,更加安全。
識別功能
若是在一臺計算機中安裝多個瀏覽器,每一個瀏覽器都會在各自獨立的空間存放cookie。由於cookie中不但能夠確認用戶,還能包含計算機和瀏覽器的信息,因此一個用戶用不一樣的瀏覽器登陸或者用不一樣的計算機登陸,都會獲得不一樣的cookie信息,另外一方面,對於在同一臺計算機上使用同一瀏覽器的多用戶羣,cookie不會區分他們的身份,除非他們使用不一樣的用戶名登陸。
2 haproxy cookie 選項
參考 HAProxy 配置手冊 4.2. session粘連相關
http://hi.baidu.com/maiyudaodao/item/a3cabab79c95847d254b09ea
Examples :
cookie JSESSIONID prefix
cookie SRV insert indirect nocache
cookie SRV insert postonly indirect
cookie SRV insert indirect nocache maxidle 30m maxlife 8h
See also : "appsession", "balance source", "capture cookie", "server" and "ignore-persist".
cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ]
[ postonly ] [ preserve ] [ domain <domain> ]*
[ maxidle <idle> ] [ maxlife <life> ]
sections : defaults | frontend | listen | backend
yes | no | yes | yeslinux
Arguments :
<name> cookie的名稱,用於持久性的監視、修改和增長。cookie在response中經過"Set-Cookie"頭髮送給客戶端,並由客戶端的全部request的"Cookie"頭返回。尤爲注意不要與應用cookie重名。另外,若是相同客戶端使用了相同的後端(如HTTP/HTTPS),若是不但願跨後端的持久性,也要注意使用不一樣的cookie名稱。
rewrite 表示cookie由服務器提供,haproxy一定要修改它的值,以包含服務器的標識符。這種模式便於應用來管理 "Set-cookie" 和 "Cache-control"頭的複雜組合。應用能夠決定是否適合發出一個持久性cookie。若是全部的響應都要被監控,則該模式只能工做在 HTTP close模式下。除非應用的行爲很複雜和/或破碎(broken?),不然建議不要啓動這個新的配置模式。關鍵字不能與"insert" 和 "prefix"共用。web
insert 表示若是客戶端尚未容許訪問服務器的cookie,haproxy會在服務器響應中插入持久性cookie。
若是服務器發送了一個同名的cookie,當沒有同時聲明 "preserve" 選項時,它會在處理前被刪掉。所以,這個模式能夠用於升級「rewrite」模式下的已有配置。cookie只是一個會話cookie,並且不保存在客戶端的磁盤中。 默認的,除非有選項 "indirect" ,服務器纔會看到客戶端發出的cookie。因爲緩存的影響,一般明智的作法是添加關鍵字"nocache" or "postonly" 。關鍵字不能與 "rewrite" 和 "prefix"共用。
prefix 持久性基於現有的cookie就能夠,而沒必要依賴專門的cookie。在一些特殊的環境下須要使用,如客戶端不支持多於一個cookie,而應用已經須要了。這種狀況下,每當服務器設置了cookie名字,haproxy就會在名字前添加一個服務器標識符和分隔符的前綴。前綴在全部客戶端的請求中會被去掉,因此服務器仍是會找到發送的cookie。既然全部的響應和請求都要被修改,這個模式則須要運行在HTTP close模式下。關鍵字不能與 "rewrite" 和 "insert"共用。
indirect 聲明瞭該選項,沒有cookie會被髮送給客戶端,即便客戶端已經有一個合法的cookie給處理響應的服務器。若是服務器自己設置了這樣一個cookie,也會被刪除,除非同時設置了選項"preserve"。在"insert"模式下,還會刪除發送給服務器的request的cookie。持久機制對應用是徹底透明的。
nocache 若是在客戶端和HAProxy之間有緩存,那麼該選項建議與"insert"模式結合使用,若是須要新增cookie,確保可緩存的response標記爲非緩存的。這很重要,由於全部可持久的cookie都被加在實例的一個可緩存的主頁上,那麼全部客戶會從外部緩存獲取頁面,並都共享一樣的持久cookie,致使一個服務器處理了太多的負載。參見"insert" 和 "postonly"選項。
postonly 該選項使cookie只能增長在POST請求的響應中。與 "nocache"選項只能二選一,由於POST響應是不可緩存的,因此持久cookie是毫不會被緩存的。第一個POST通常都是登陸請求,大部分站點在此以前不須要任何持久性的排序,這能夠避免在緩存中查找持久cookie,以有效優化緩存。參見"insert" 和 "nocache" 選項。
preserve 該選項能夠與 "insert" 和/或 "indirect"一塊兒使用。容許服務器本身發送持久cookie。在這種狀況下,若是在response中發現有cookie,則HAProxy會對其保持不變。在實例的註銷請求以後,須要用它來結束持久性。此時,服務器只須要發送一個帶有無效值(如:empty)或過去日期的cookie。與"disable-on-404"檢查選項相結合,能夠實現一個徹底正常的關閉,由於用戶註銷後必定會離開服務器。
domain 該選項用於指定cookie插入的域,後跟一個合法的域名參數。若是域名以點開頭,瀏覽器容許任何以域名結尾的主機使用它。還能夠經過多此調用此選項來指定多個域名,但要注意有的瀏覽器對域的個數是有限制的。有記錄說在MSIE6或Firefox2上發送10個域是能夠的。
maxidle 該選項容許在閒置時間後忽略插入的cookie,只對insert模式的cookie有效。當cookie發送到客戶端,cookie的日期也被髮送過去。進一步講,若是日期早於參數(秒)表示的延遲,cookie會被忽略,不然會根據發送給客戶端的響應進行刷新。尤爲是用戶一直不關閉瀏覽器,能夠避免在一臺服務器上佔用太長時間 (eg: after a farm size change)。若是設置了選項,可是cookie沒有日期,這種狀況是容許的,只是會一直在響應中刷新。這維護了管理員訪問他們站點的能力。cookie的日期若是超過將來24小時也會被忽略掉,使管理員能夠在修復時區問題時沒必要把用戶踢下線。
maxlife 該選項容許在生存時間事後忽略插入的cookie,不論是否還在使用,只對insert模式的cookie有效。當cookie發送到客戶端,cookie的日期也被髮送過去。進一步講,若是日期早於參數(秒)表示的延遲,cookie會被忽略。若是request中的cookie沒有日期,則會被設置一個日期。cookie的日期若是超過將來24小時也會被忽略掉,使管理員能夠在修復時區問題時沒必要把用戶踢下線。與maxidle不一樣,這個值是不刷新的,只在第一次訪問日期計數。maxidle和maxlife能夠一塊兒使用,尤爲是用戶一直不關閉瀏覽器,能夠避免在一臺服務器上佔用太長時間 (eg: after a farm size change)。與maxidle的超時後強行從新分配相比,這個要更好一些。
每一個HTTP後端能夠只有一個持久cookie,並定義在default部分,cookie的值能夠是"server"聲明中"cookie"關鍵字後面的值。若是服務器沒有指定cookie,則不會設置。
3 例子 基於cookie插入的簡單HTTP負載均衡
參考 haproxy架構指南1
http://blog.chinaunix.net/uid-10249062-id-222312.html
1. 基於cookie插入的簡單HTTP負載均衡
192.168.1.1 192.168.1.11-192.168.1.14 192.168.1.2
-------+-----------+-----+-----+-----+--------+----
| | | | | _|_db
+--+--+ +-+-+ +-+-+ +-+-+ +-+-+ (___)
| LB1 | | A | | B | | C | | D | (___)
+-----+ +---+ +---+ +---+ +---+ (___)
haproxy 4 cheap web servers
配置 haproxy (LB1) :
-------------------------算法
- listen webfarm 192.168.1.1:80
- mode http
- balance roundrobin
- cookie SERVERID insert indirect
- option httpchk HEAD /index.html HTTP/1.0
- server webA 192.168.1.11:80 cookie A check
- server webB 192.168.1.12:80 cookie B check
- server webC 192.168.1.13:80 cookie C check
- server webD 192.168.1.14:80 cookie D check
描述:
-------------
- LB1 接收clients的requests
- 若是1個request不包含cookie,則把這個request前傳到分配的一個有效的server
- 做爲回報, 1個擁有server名稱的cookie "SERVERID"會被插入到response中
- 當client帶有cookie "SERVERID=A"再此訪問時,LB1就會知道這個request必須被前傳到server A. 同時刪除這個cookie,server不會看到它
- 當server"webA"宕機時,request會被前傳至另一個有效的server,而且從新分配cookie
數據流:
注意:a 箭頭方向;b HTTP 1.0;
-------
(client) (haproxy) (server A)
>-- GET /URI1 HTTP/1.0 ------------> |
( no cookie, haproxy forwards in load-balancing mode. )
| >-- GET /URI1 HTTP/1.0 ---------->
| <-- HTTP/1.0 200 OK -------------<
( the proxy now adds the server cookie in return )
<-- HTTP/1.0 200 OK ---------------< |
Set-Cookie: SERVERID=A |
>-- GET /URI2 HTTP/1.0 ------------> |
Cookie: SERVERID=A |
( the proxy sees the cookie. it forwards to server A and deletes it )
| >-- GET /URI2 HTTP/1.0 ---------->
| <-- HTTP/1.0 200 OK -------------<
( the proxy does not add the cookie in return because the client knows it )
<-- HTTP/1.0 200 OK ---------------< |
>-- GET /URI3 HTTP/1.0 ------------> |
Cookie: SERVERID=A |
( ... )
限制:
- 若是clients使用keep-alive (HTTP/1.1),只有第1個response會被插入1個cookie,而且在每一個鏈接中只有第1個request會被解析。不過因爲在第1個response中會當即插入cookie,而且在同一個鏈接中會把後續的request分配至同一個server,因此在insertion模式下不會產生問題。然而,haproxy會刪除前傳到servers的cookie,因此server必須不能對未知的cookies敏感。若是這樣會致使問題,能夠經過添加下面的選項關閉keep-alive:
option httpclose
- 若是因爲一些緣由,clients沒法學到多個cookie(例如:clients確實須要一些自制的應用程序或者網關),而且應用程序已經產生了一個cookie,能夠經過是「prefix」模式。
- LB1成爲1個很是敏感的server。若是LB1宕機,再也不正常工做。能夠經過keepalived進行熱備。
- 若是應用程序須要記錄原始的client IP地址,能夠經過使用"forwardfor"選項增長包含原始client IP地址的"X-Forwarded-For" header。一樣也須要使用"httpclose"保證重寫每一個request而不是僅僅每一個鏈接的第1個request:
option httpclose
option forwardfor
- 若是應用程序須要記錄原始的目的IP,能夠經過使用"originalto"選項增長包含原始目的IP地址的"X-Original-To" header。一樣也須要使用"httpclose"保證重寫每一個request而不是僅僅每一個鏈接的第1個request:
option httpclose
option originalto
web serve必須配置爲使用這些可替換的header。例如,apache,能夠經過使用以下LogFormat:
LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b " combined
CustomLog /var/log/httpd/access_log combined
提示:
-------
有時在網絡中,能夠發現有必定比例的client禁用了瀏覽器的cookies。顯然,在網上有無處不在的問題,可是仍然能夠經過使用"source"負載算法代替"roundrobin"從而幫助client訪問你的網站。"source"負載算法能夠在server數目不變的狀況下保證一個給定的IP地址總會被分配至同1臺server。由於會致使分配不均,因此不要在1個proxy或者1個小型網絡後使用"source"負載算法。然而,在一個大型的內部網絡和互聯網,卻能夠工做的很是好。只要clients接受cookie,具備動態地址的Clients將不會受到影響。由於Cookie老是高於負載平衡的優先級:apache
- listen webfarm 192.168.1.1:80
- mode http
- balance source
- cookie SERVERID insert indirect
- option httpchk HEAD /index.html HTTP/1.0
- server webA 192.168.1.11:80 cookie A check
- server webB 192.168.1.12:80 cookie B check
- server webC 192.168.1.13:80 cookie C check
- server webD 192.168.1.14:80 cookie D check
更多請:
linux 相關 274134275 , 37275208(已滿)
vmware 虛擬化相關 166682360後端