官术网_书友最值得收藏!

  • Linux集群之美
  • 余洪春
  • 2072字
  • 2021-01-08 10:57:43

1.3.5 基于cookie的會(huì)話保持處理機(jī)制

這里用HAProxy來(lái)舉例說(shuō)明。

任何一個(gè)L7的HTTP負(fù)載均衡器都應(yīng)該具備一個(gè)功能:會(huì)話保持。會(huì)話保持是保證客戶端對(duì)動(dòng)態(tài)應(yīng)用程序正確請(qǐng)求的基本要求。

還是用那個(gè)最有說(shuō)服力的例子:客戶端A向服務(wù)端B請(qǐng)求將C商品加入它的賬戶購(gòu)物車,加入成功后,服務(wù)端B會(huì)在某個(gè)緩存區(qū)域中記錄下客戶端A和它的商品C,這個(gè)緩存的內(nèi)容就是Session上下文環(huán)境。而識(shí)別客戶端的方式一般是設(shè)置Session ID(如PHPSESSID、JSESSIONID),并將其作為cookie的內(nèi)容交給客戶端。客戶端A再次請(qǐng)求的時(shí)候(比如為購(gòu)物車中的商品下訂單),只要攜帶這個(gè)cookie,服務(wù)端B就可以從中獲取Session ID并找到屬于客戶端A的緩存內(nèi)容(商品C),也就可以繼續(xù)執(zhí)行下訂單部分的代碼。

假如這時(shí)使用負(fù)載均衡軟件對(duì)客戶端的請(qǐng)求進(jìn)行負(fù)載均衡,就必須要保證能將客戶端A的請(qǐng)求再次引導(dǎo)到服務(wù)端B,而不能引導(dǎo)到服務(wù)端X、服務(wù)端Y,因?yàn)閄、Y上并沒(méi)有緩存與客戶端A對(duì)應(yīng)的Session內(nèi)容,也就無(wú)法為客戶端A下訂單。

因此,反向代理軟件必須具備將客戶端和服務(wù)端“綁定”的功能,也就是所謂的提供會(huì)話保持,讓客戶端A后續(xù)的請(qǐng)求一定轉(zhuǎn)發(fā)到服務(wù)端B上。

在LB上配置好HAProxy后,HAProxy將接受用戶的所有請(qǐng)求。如果一個(gè)用戶請(qǐng)求不包含任何cookie,那么這個(gè)請(qǐng)求將被HAProxy轉(zhuǎn)發(fā)到一臺(tái)可用的Web服務(wù)器上,可能是WebA、WebB、WebC或WebD。然后HAProxy將把處理這個(gè)請(qǐng)求的Web服務(wù)器的cookie值插入請(qǐng)求響應(yīng)中,如SERVERID=A,若這個(gè)客戶端再次訪問(wèn)并在HTTP請(qǐng)求頭中帶有SERVERID=A,HAProxy將會(huì)把它的請(qǐng)求直接轉(zhuǎn)發(fā)給WebA處理。下面介紹實(shí)驗(yàn)的系統(tǒng)及開(kāi)源軟件的版本。

系統(tǒng)及開(kāi)源軟件版本:

·CentOS 7.6 x86_64

·HAProxy 1.7.9

·Nginx 1.12.2

·PHP 5.6.40

機(jī)器IP地址分配情況如下。

·HAProxy:192.168.100.22

·Nginx+PHP-1:192.168.100.23

·Nginx+PHP-2:1921.68.100.24

HAProxy代理兩臺(tái)Nginx機(jī)器,物理拓?fù)漭^簡(jiǎn)單,如圖1-5所示。

圖1-5 HAProxy代理Nginx物理拓?fù)鋱D

首先,源碼安裝HAProxy 1.7.9,由于CentOS 7.6系統(tǒng)自帶的HAProxy版本過(guò)低,這里想采用較高的開(kāi)源版本,所以以源碼方式進(jìn)行安裝:


cd /usr/local/src
wget http://www.haproxy.org/download/1.7/src/haproxy-1.7.9.tar.gz
tar xvf haproxy-1.7.9.tar.gz
cd haproxy-1.7.9
make TARGET=linux2628 PREFIX=/usr/local/haproxy
# TARGET指定編譯OS對(duì)應(yīng)的內(nèi)核版本,這里寫Linux2628即可
make install PREFIX=/usr/local/haproxy

為了實(shí)現(xiàn)基于cookie的會(huì)話保持,HAProxy配置文件中必須增加cookie的配置,如下所示:


# 需要轉(zhuǎn)發(fā)的IP及端口
balance roundrobin
cookie SERVERID insert  indirect nocache
server web1 192.168.100.23:80 cookie server1
server web2 192.168.100.24:80 cookie server2

在這個(gè)示例配置中,cookie指令中指定的是insert命令,表示在將響應(yīng)報(bào)文交給客戶端之前,先插入一個(gè)屬性名為SERVERID的cookie,這個(gè)cookie在響應(yīng)報(bào)文的頭部獨(dú)占一個(gè)Set-Cookie字段(因?yàn)槭遣迦胄耤ookie),而SERVERID只是cookie名稱,它的值是由server指令中的cookie選項(xiàng)指定的,這里是server1或server2。

除了insert命令,cookie指令中還支持rewrite和prefix這兩種設(shè)置cookie的方式,不過(guò),對(duì)于這三種cookie的操作方式,只能三選一。

·insert:表示如果客戶端沒(méi)有cookie信息且有權(quán)限訪問(wèn)服務(wù)器時(shí),持久性cookie必須通過(guò)HAProxy穿插在服務(wù)器的響應(yīng)報(bào)文中。當(dāng)服務(wù)器收到相同名稱的cookie并且沒(méi)有“preserve(保存)”選項(xiàng)時(shí),將會(huì)移除之前已存的cookie信息。因此,insert可視作rewrite的升級(jí)版。cookie信息僅僅作為會(huì)話cookie且不會(huì)存到客戶端的磁盤上。默認(rèn)除非加了“indirect(間接)”選項(xiàng),否則服務(wù)器端會(huì)看到客戶端發(fā)送的cookie信息。由于緩存的影響,最好加上nocache或postonly選項(xiàng)。

·rewrite:表示cookie由服務(wù)器生成并且HAProxy會(huì)在其值中注入該服務(wù)器的標(biāo)識(shí)符;此關(guān)鍵字不能在HTTP隧道模式下工作。

·prefix:表示不依賴專用的cookie做持久性,而是依賴現(xiàn)成的;用在某些特殊的場(chǎng)景中,如客戶端不支持一個(gè)以上的cookie和應(yīng)用程序?qū)λ行枨髸r(shí)。每當(dāng)服務(wù)器建立一個(gè)名為<name>的cookie時(shí),它將以服務(wù)器的標(biāo)識(shí)符和分隔符作為前綴。來(lái)自客戶端的請(qǐng)求報(bào)文中的前綴將會(huì)被刪除以便服務(wù)器端能識(shí)別出它所發(fā)出的cookie,由于請(qǐng)求和響應(yīng)報(bào)文都被修改過(guò),所以此模式不能工作在隧道模式中,且不能與indirect共用,否則服務(wù)器端更新的cookie將不會(huì)被發(fā)到客戶端。

這里參考一下HAProxy官方文檔,它提供了cookie相關(guān)的配置說(shuō)明,如下所示。

HAProxy將在客戶端沒(méi)有cookie時(shí)(比如第一次請(qǐng)求),在響應(yīng)報(bào)文中插入一個(gè)cookie。

當(dāng)沒(méi)有使用關(guān)鍵詞preserve選項(xiàng)時(shí),如果后端服務(wù)器設(shè)置了一個(gè)與此處名稱相同的cookie,則首先刪除服務(wù)端設(shè)置的cookie。

該cookie只能作為會(huì)話保持使用,無(wú)法持久化到客戶端的磁盤上(因?yàn)镠AProxy設(shè)置的cookie沒(méi)有maxAge屬性,無(wú)法持久保存,只能保存在瀏覽器緩存中)。

默認(rèn)情況下,除非使用了indirect選項(xiàng),否則服務(wù)端可以看到客戶端請(qǐng)求時(shí)的所有cookie信息。

由于緩存的影響,建議加上nocache或postonly選項(xiàng)。如果使用nocache選項(xiàng),當(dāng)客戶端和HAProxy間存在緩存時(shí),使用此選項(xiàng)和insert搭配最好,以便確保如果一個(gè)cookie需要被插入時(shí),可被緩存的響應(yīng)會(huì)被標(biāo)記成不可緩存。這很重要,舉個(gè)例子:如果所有的持久cookie被添加到一個(gè)可緩存的主頁(yè)上,之后所有的客戶將從外部高速緩存讀取頁(yè)面并將共享相同的持久性cookie,這會(huì)造成服務(wù)器阻塞。

最后,我們利用后端test.php文件來(lái)區(qū)分客戶端連接的實(shí)際機(jī)器,test.php文件內(nèi)容如下:


<h1>response from webapp 192.168.100.23</h1>
<?php
    session_start();
    echo "Server IP: "."<font color=red>".$_SERVER['SERVER_ADDR']."</font>"."<br>";
    echo "Server Name: "."<font color=red>".$_SERVER['SERVER_NAME']."</font>"."<br data-tomark-pass>";
    echo "SESSIONNAME: "."<font color=red>".session_name()."</font>"."<br data-tomark-pass>";
    echo "SESSIONID: "."<font color=red>".session_id()."</font>"."<br data-tomark-pass>";
?>

另一臺(tái)機(jī)器相對(duì)應(yīng)的內(nèi)容改為:


<h1>response from webapp 192.168.100.24</h1>

接下來(lái)用如下地址訪問(wèn)HAProxy:


http://192.168.100.22/test.php

我們可以看一下訪問(wèn)http://192.168.100.22/test.php的結(jié)果顯示,如圖1-6所示。

圖1-6 test.php訪問(wèn)結(jié)果圖示

第一次訪問(wèn)時(shí)我們用Chrome瀏覽器的F12抓下HTTP的包,如圖1-7所示。

圖1-7 Chrome截圖結(jié)果圖示

再次訪問(wèn)時(shí),對(duì)比一下,Response Headers已經(jīng)沒(méi)有Set_Cookie了,這是什么原因呢?

具體原因?yàn)椋嚎蛻舳嗽诘谝淮问盏巾憫?yīng)后就會(huì)把cookie緩存下來(lái),以后每次http://192.168.100.22/test.php(根據(jù)域名進(jìn)行判斷)都會(huì)從緩存中取出該cookie放進(jìn)請(qǐng)求首部。這樣HAProxy一定會(huì)將其分配給Web1,除非Web1下線了。

這樣就實(shí)現(xiàn)了會(huì)話保持,保證被處理過(guò)的客戶端能被分配到同一個(gè)后端應(yīng)用服務(wù)器上。

參考文檔:

http://www.haproxy.org/#docs

https://www.cnblogs.com/f-ck-need-u/p/8553190.html

主站蜘蛛池模板: 阿勒泰市| 海伦市| 分宜县| 山丹县| 兰考县| 兰州市| 台北市| 合肥市| 大冶市| 吴忠市| 泰宁县| 汽车| 江山市| 凤山县| 米脂县| 新巴尔虎右旗| 顺义区| 华安县| 凌云县| 丹棱县| 双峰县| 厦门市| 松滋市| 洛川县| 翁源县| 舒城县| 信丰县| 虎林市| 达拉特旗| 勃利县| 庆阳市| 登封市| 宁安市| 平谷区| 师宗县| 衡阳县| 普洱| 集安市| 凉山| 雷波县| 军事|