Haproxy 与 Cookie
?
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 | yes
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"共用。
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) :
-------------------------
描述:
-------------
- 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總是高于負載平衡的優先級:
轉載于:https://blog.51cto.com/250688049/1117678
總結
以上是生活随笔為你收集整理的Haproxy 与 Cookie的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux psftp,使用PSFTP实
- 下一篇: ASP.NET MVC 的多国语系支持