天天看點

haproxy裡的逾時配置and負載均衡

一,haproxy 裡的逾時

用戶端請求階段

timeout client
    haproxy 和用戶端通信時,連接配接不活躍的時間,既不發送資料,也不ack接收的資料
    如果未設定,則永不逾時,此時連接配接是否逾時依賴于tcp連接配接本身的機制
timeout http-request
    tcp 連接配接建立後,直到所有頭部發送完畢的時間
    如果未設定,則使用 timeout client 的值
    如果 frontend 是 tcp 模式,則使用 backend 中的 timeout http-request
timeout http-keep-alive
    當開啟 option http-keep-alive 時,haproxy 處理完請求 A ,等待連接配接上請求 B ,請求 A 結束到請求 B 開始之間的間隔時間
    如果未設定,則使用 timeout client
    如果 frontend 是 tcp 模式,則使用 backend 中的 timeout http-keep-alive
timeout client-fin
    當用戶端和 haproxy 的連接配接的一端已經 shutdown 時,該連接配接不活躍的時間
    如果未設定
        非隧道連接配接,使用 timeout client
        隧道連接配接,如 RDB/WebSocket ,使用 timeout tunnel
           

haproxy 轉發階段

timeout queue
    當 haproxy 接受用戶端請求後,如果暫時找不到可以立即轉發的後端,此時會将該連接配接放置在 backend 或者 server 的請求隊列中,等待有 server 可以處理請求時,就轉發過去
    timeout queue 指定的是,某個請求被放置在隊列中的最大時間,如果逾時,則認為該請求不能被處理,傳回 503 給用戶端
    如果未設定,則使用 timeout connect
timeout connect
    haproxy 和後端建立 tcp 連接配接的逾時時間
    如果未設定則永不逾時
           

後端響應階段

timeout server
    haproxy和後端通信時,連接配接不活躍的時間,即既不發送資料,也不 ack 接收的資料
timeout server-fin
    當 haproxy 和後端的連接配接的一端已經 shutdown 時,該連接配接不活躍的時間
    如果未設定
        非隧道連接配接,使用 timeout server
        隧道連接配接,使用 timeout tunnel
           

特殊場景

timeout tunnel
    隧道連接配接的場景
        http 連接配接更新後 WebSocket 之後
        轉發 CONNECT 請求 給http 代理
        tcp 連接配接
    隧道連接配接建立後,該連接配接雙向不活躍的時間,即連接配接上既不發送資料,也不接收資料
    當連接配接轉換為隧道連接配接後,timeout client/timeout server 都将被 timoeut tunnel 取代

timeout tarpit
    當 http 請求被 http-request tarpit 指令标記後,haproxy 會将連接配接維持 timeout tarpit 的時間,如果逾時後,該連接配接仍然未關閉,就回複 500 響應碼給用戶端,參看 http-request tarpit 的說明
           

二,配置負載均衡政策

HAProxy中配置負載均衡政策非常簡單。甚至我們不配置,預設使用的就是輪詢了。

隻需要在backend中加上"balance roundrobin"即可。

backend servers
        balance roundrobin
        server tomcat1 127.0.0.1:8081
        server tomcat2 127.0.0.1:8082
        server tomcat3 127.0.0.1:8083
           

格式為:balance [ ]

常見的政策有:

roundrobin
static-rr
leastconn
source
url_param
uri
hdr(<name>)
random
rdp-cookie
           

常用負載均衡政策

1. roundrobin 輪詢

這個非常簡單,顧名思義就是按照server清單,按server1、server2、server3的順序輪流來接收請求。

這個也是HAProxy的預設政策,我們不配置"balance roundrobin",使用的也是輪詢政策。

backend servers
        balance roundrobin
        server tomcat1 127.0.0.1:8081
        server tomcat2 127.0.0.1:8082
        server tomcat3 127.0.0.1:8083
           

weight 權重

其實還有一個參數,weight權重。

如果我們配置server的weight,輪詢還是1 2 3嗎?

backend servers
        balance roundrobin
        server tomcat1 127.0.0.1:8081 weight 1
        server tomcat2 127.0.0.1:8082 weight 2
        server tomcat3 127.0.0.1:8083 weight 3
           

上面我們給server1/2/3的權重分别是1 2 3,表示server3的權重是最大的,server1的權重是最小的。

意思是,更優先選擇server3.

修改haproxy.cfg的配置為上面所示,我們連續發送請求,觀察一下輪詢下的負載均衡。

Server 3
Server 2
Server 3
Server 1
Server 3
Server 2
Server 3
Server 2
Server 3
Server 1
Server 3
Server 2
           

可以看到12次請求中,server1被通路6次,server2被通路4次,server1被通路2次。

這個比例剛好和server的權重比是一緻的!!!

如果沒有指定server的權重,那麼他們的weight都是相等的,是以預設下是server1 server2 server3(這裡不是按數字大小,而是server清單中前後順序)的輪流接收請求。

2. static-rr 靜态輪詢

看了很多文章,這個政策都是一筆帶過,基本就是翻譯了官方文檔。于是懷着好奇的心理,深入了解了一下這個政策。

先看名字,static就是靜态的意思,rr就是roundrobin,組合起來,就是靜态輪詢的意思。

既然它叫靜态輪詢,那麼我們預設的roundrobin就是動态輪詢喽,dynamic roundrobin。

輪詢好了解,就是你我他一個個排着隊接收請求。

那麼靜态和動态是啥意思呢。

官方文檔:

It is static, which means that changing a server's weight on the fly will have no effect.
           

官方說了,也就是在運作時修改server的權重是無效的。本文前面roundrobin中說過,權重會影響輪詢。

那就涉及haproxy運作過程中修改權重了。

本系列的第六篇就到如何運作時修改server的權重《HAProxy快速入門(六)—— 管理HAProxy》

用socat連接配接socket,在執行指令:

set server servers/tomcat1 weight 10
           

這樣我們就修改了server的權重了。

我們先把負載均衡政策改成靜态輪詢:

然後我們重新開機haproxy:

service haproxy restart

預設下配置下,我們沒有給server聲明權重,是以預設權重是1. 我們可以用指令查詢一下:

可以看到,預設權重都是1

接下來,我們修改tomcat1的權重,我們把權重修改成2:

非常遺憾,指令行提示backend的靜态負載政策就能把權重設定成0%或者100%。

為什麼能設定成0%和100%呢?那是因為設定0%時,就相當于把這台server禁用掉。如果設定成100%就相當于啟用它。

我們不妨來測試一下:

通路http://localhost/,我們會發現請求不到server1了,我們交替通路server2和server3.

設定成weight 100,就能通路到了,這裡不一一示範了。

但是如果我們用的是roundrobin,就可以動态修改server的權重。這就是static rr和roundrobin的差別!

3. leastconn 最少連接配接數

這個比較好了解,目前多個伺服器之中,選擇接收連接配接最少的那台伺服器,也就是最閑的那台伺服器。這樣保證不會澇的澇死,旱的旱死。

如果有多台是相同負載呢?這時候就在它們之間用輪詢政策。總之要保證大家都有活幹。

用戶端和服務端的連接配接是長連接配接時比較有效。因為短連接配接很快就結束了,可能請求一直進來,很快結束,導緻出現一直是一台伺服器處理請求的情況,其他伺服器都空閑着。你細品。

這個負載政策測試需要并發才要展現,是以這裡不便示範。

4. source 源IP

這種政策會對源IP做散列,好處是同一個IP會一直通路同一台server。

我們修改負載均衡政策成source

然後重新開機haproxy後。

通路http://localhost,不管通路100次還是一萬次,我們始終通路的是server1(當然不一定是server1,但可以肯定是同一台server)。

我是在PC上通路通路的是server1,因為我的HAProxy是部署在虛拟機中,是以直接在CentOS通路時 curl http://localhost,得到的結果一直是server3.

5. url_param URL參數

格式:balance url_param [check_post]

我們會在負載均衡政策中聲明一個參數,然後haproxy将會對參數值做hash,然後路由到某一台伺服器。

是以相同參數會始終通路同一台伺服器。

本例中,我們聲明一個“app”的參數

backend servers
        balance url_param app
        server tomcat1 127.0.0.1:8081
        server tomcat2 127.0.0.1:8082
        server tomcat3 127.0.0.1:8083
           

我們通路:http://localhost?app=app1會發現一直通路的是某一台伺服器。如果改變其他的參數,也是始終通路同一台伺服器。

6. url URL

這種政策會對URL路徑做散列。

注意我們的URL通常包括兩部分,第一部分是URL前部分,通常是/分隔的,後部分是參數,也就是從問号開始

是以url負載均衡政策也考慮到了這兩種情況:

如果配置:balance url,将對問号前的url做hash,是以相同的不帶參數的url會始終通路同一台伺服器。
如果配置:balance url whole,将會完整的url做hash,完全相同的url才會始終通路同一台伺服器。
           

還有兩個額外的參數可以配置:

depth:深度,如果指定深度,則會對指定層級的URL路徑做hash,每個斜杠就是一層,如http://localhost/web/pic/food/....
len:長度,如果指定一個長度,則會對截取後的URL做hash
           

7. hdr() header

hdr是header的簡寫。

指定一個header,對每個請求的header做hash,和前面一樣的道理。帶了相同header的的請求會被指定到同一台伺服器。

我們來測試一下。

backend servers
        balance hdr(flag)
        server tomcat1 127.0.0.1:8081
        server tomcat2 127.0.0.1:8082
        server tomcat3 127.0.0.1:8083
           

為了測試友善編輯header,我們使用postman作為httpclient。

測試發現,隻要我們的請求中帶了flag這個header,他的值是相等的話,就會一直通路一台伺服器。

如果request沒有帶這個header,則會使用輪詢。

8. random 随機

這個就不用多說了,随機選擇一台。

9. rdp-cookie

對會cookie做散列,相同cookie的請求會被路由到同一伺服器。

繼續閱讀