haproxy的stick table複製

来源:https://www.cnblogs.com/f-ck-need-u/archive/2018/03/14/8565998.html
-Advertisement-
Play Games

在上一篇文章中,分析了haproxy的stick table特性和用法,其中特性之一也是很實用的特性是stick table支持在haproxy多個節點之間進行複製(replication)。 本文僅討論如何配置實現stick table的複製功能,不考慮在什麼環境下實現它,以及它的雙主模型如何配置 ...


在上一篇文章中,分析了haproxy的stick table特性和用法,其中特性之一也是很實用的特性是stick table支持在haproxy多個節點之間進行複製(replication)。

本文僅討論如何配置實現stick table的複製功能,不考慮在什麼環境下實現它,以及它的雙主模型如何配置。

本文實驗環境:

1.stick table複製特性

只要設置好haproxy的節點組,haproxy就會自動將新插入的、剛更新的stickiness記錄通過TCP連接推送到節點組中的非本地節點上。這樣一來,stickiness記錄不會丟失,即使某haproxy節點出現了故障,其他節點也能將客戶端按照粘性映射關係引導到正確的後端伺服器上。

由於每條stickiness記錄占用空間都很小(平均最小50位元組,最大166位元組,由是否記錄額外統計數據以及記錄多少來決定占用空間大小),使得即使在非常繁忙的環境下多個節點之間推送都不會出現壓力瓶頸和網路阻塞(可以按節點數量、stickiness記錄的大小和平均併發量來計算每秒在網路間推送的數據流量)。

它不像被人詬病的session複製(copy),因為session複製的數據量比較大,而且是在各應用程式伺服器之間進行的。而一個稍大一點的核心應用,提供服務的應用程式伺服器數量都不會小,這樣複製起來很容出現網路阻塞。

此外,stick table還可以在haproxy重啟時,在新舊兩個進程間進行複製,這是本地複製。當haproxy重啟時,舊haproxy進程會和新haproxy進程建立TCP連接,將其維護的stick table推送給新進程。這樣新進程不會丟失粘性信息,和其他節點也能最大程度地保持同步,使得其他節點只需要推送該節點重啟過程中新增加的stickiness記錄就能完全保持同步。

如果後端使用了session共用,在大多數情況下沒必要在代理層實現會話保持。如果此時使用stick table,一般只是為了收集統計數據進行採樣調查,但這樣的狀態統計數據無需在各節點之間進行複製。

2.如何定義haproxy節點成員

haproxy提供了peers指令,用於定義節點組,peer指令用於定義節點組中的成員。

例如,定義本文測試環境的節點組:

peers my_peers    # 節點組名
    peer haproxy1 192.168.100.59:12138  # 定義對端名稱,以及和對端建立tcp連接的埠,用於推送stickiness記錄
    peer haproxy2 192.168.100.54:12138
    peer haproxy3 192.168.100.42:12138

然後在stick-table指令中引用節點組。例如:

stick-table type ip size 100k expire 5m peers my_peers

註意,應當讓每個haproxy節點的節點組內容一致,然後使用haproxy命令的"-L"選項指定本地節點成員,這樣方便管理每個節點和本地節點。

haproxy -D -L haproxy1 -f /etc/haproxy/haproxy.cfg

如果不指定"-L",則在解析配置文件時將預設以主機名作為本地節點名進行解析,但很可能它不會定義在peers中,因此會報錯。

因此,如果要實現stick table的複製,還想使用sysV或systemctl管理haproxy服務,需要修改這些服務管理腳本,在啟動、重啟和語法檢查項上加上"-L"選項。例如,systemd的haproxy服務管理腳本改為如下內容:

[root@xuexi ~]# cat /usr/lib/systemd/system/haproxy.service 
[Unit]
Description=HAProxy Load Balancer
After=syslog.target network.target

[Service]
EnvironmentFile=/etc/sysconfig/haproxy
ExecStartPre=/usr/sbin/haproxy -L haproxy2 -f /etc/haproxy/haproxy.cfg -c -q
ExecStart=/usr/sbin/haproxy-systemd-wrapper -L haproxy2 -f /etc/haproxy/haproxy.cfg -p /var/run/haproxy.pid $OPTIONS
ExecReload=/usr/sbin/haproxy -L haproxy2 -f /etc/haproxy/haproxy.cfg -c -q
ExecReload=/bin/kill -USR2 $MAINPID
KillMode=mixed

[Install]
WantedBy=multi-user.target

另外個人建議,每個節點要麼完全使用sysV、systemctl管理haproxy的啟動、停止,要麼完全使用haproxy命令手動管理服務的啟動和停止,否則可能會出現記錄不同步的現象。至今沒找到會出現這個問題的原因。

3.完成配置

如下,是每個haproxy節點的配置文件內容。

global
    log         127.0.0.1 local2
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     20000
    user        haproxy
    group       haproxy
    daemon
    stats socket /var/run/haproxy.sock mode 600 level admin
    spread-checks 2

    peers mypeers 
        peer haproxy1 192.168.100.59:12138
        peer haproxy2 192.168.100.54:12138
        peer haproxy3 192.168.100.42:12138
defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    timeout http-request    2s
    timeout queue           3s
    timeout connect         1s
    timeout client          10s
    timeout server          2s
    timeout http-keep-alive 10s
    timeout check           2s
    maxconn                 18000 

frontend http-in
    bind             *:80
    mode             http
    log              global
    default_backend  dynamic_group

backend dynamic_group
    stick-table type string len 32 size 5k expire 5m peers mypeers
    stick on req.cook(PHPSESSID)
    stick store-response res.cook(PHPSESSID)
    balance roundrobin
    option http-server-close
    option httpchk     GET /index.php
    option redispatch
    http-check expect  status 200
    server app1 192.168.100.60:80 check rise 1 maxconn 3000 
    server app2 192.168.100.61:80 check rise 1 maxconn 3000

然後分別在3個節點上啟動haproxy,註意加上"-L"選項。

haproxy -D -L haproxy1 -f /etc/haproxy/haproxy.cfg    # exec on haproxy1
haproxy -D -L haproxy2 -f /etc/haproxy/haproxy.cfg    # exec on haporxy2
haproxy -D -L haproxy3 -f /etc/haproxy/haproxy.cfg    # exec on haproxy3

分別在haproxy1、haproxy2、haproxy3上監控stick table。如果下麵命令執行失敗,見查看stick table信息

watch -n 1 'echo "show table dynamic_group" | socat unix:/var/run/haprox.sock -'

由於上面的配置文件中,stick table中存儲和匹配的記錄是響應報文中名為PHPSESSID的cookie,因此在瀏覽器上測試時,能實現會話粘性。但如果使用curl命令進行測試,由於curl每次執行結束進程就退出,無法緩存cookie,因此curl的每次請求都是新連接。此處正好利用curl這一點特性,來生成多個stickiness記錄,方便觀察stick table記錄推送的情況。

找一臺Linux主機,分別對三個haproxy節點進行5次curl請求。

ip1=192.168.100.59
ip2=192.168.100.54
ip3=192.168.100.42
for i in $ip1 $ip2 $ip3;do
    for j in `seq 1 5`;do 
        curl http://$i/index.php &>/dev/null
        usleep 500000
    done
done

以下是截取自三個節點的stick table內容。

###################### haproxy1 ########################
# table: dynamic_group, type: string, size:5120, used:15
0x1551cc4: key=1t1lr3s5s7pm4tuu3476c40jk3 use=0 exp=286311 server_id=2
0x1551f04: key=3m3o6qkfvk8l4lenk0k8to2bd6 use=0 exp=288500 server_id=2
0x1551904: key=8bg6ej7md7453sp0rrgi5vsiu7 use=0 exp=281350 server_id=1
0x1552144: key=9c4lf1tncd290mjl7vnjafnqe2 use=0 exp=287418 server_id=2
0x1552744: key=b3gqn2i3emi43rfh3i8t0jhln4 use=0 exp=283523 server_id=1
0x15519c4: key=cskoqa8vbb7fbac4eko27hnk70 use=0 exp=281897 server_id=2
0x1550c54: key=ejjgpe1j99nv7hqmnlpib5osq6 use=0 exp=286867 server_id=1
0x1550fc4: key=immqb6ocsq8m5982o28hatk6c2 use=0 exp=285187 server_id=2
0x1550e44: key=lg78n74u0dj51m3cvkn9qhce66 use=0 exp=287953 server_id=1
0x15522c4: key=livn0t62bthpfvp5motknhb934 use=0 exp=284620 server_id=1
0x1551b44: key=mhkh0c4lpisr9kgdb3ggmplpk1 use=0 exp=285745 server_id=1
0x1552384: key=ovfoprd6p91sjbf22qo5jjd4u0 use=0 exp=289035 server_id=1
0x1552204: key=rvt3fnhr51sfrqu1aefjceqlu4 use=0 exp=282978 server_id=2
0x1550d84: key=snkm72pvasr36ut39qopd3jmb1 use=0 exp=282442 server_id=1
0x1552084: key=ucj2pkve527nt39mejp1n7jdu5 use=0 exp=284084 server_id=2

###################### haproxy2 ########################
# table: dynamic_group, type: string, size:5120, used:15
0x7fa77ec4c8a4: key=1t1lr3s5s7pm4tuu3476c40jk3 use=0 exp=278032 server_id=2
0x7fa77ec4d4e4: key=3m3o6qkfvk8l4lenk0k8to2bd6 use=0 exp=280404 server_id=2
0x7fa77ec4c2a4: key=8bg6ej7md7453sp0rrgi5vsiu7 use=0 exp=272658 server_id=1
0x7fa77ec4c424: key=9c4lf1tncd290mjl7vnjafnqe2 use=0 exp=279232 server_id=2
0x7fa77ec4be24: key=b3gqn2i3emi43rfh3i8t0jhln4 use=0 exp=275012 server_id=1
0x7fa77ec4c4e4: key=cskoqa8vbb7fbac4eko27hnk70 use=0 exp=273251 server_id=2
0x7fa77ec4c724: key=ejjgpe1j99nv7hqmnlpib5osq6 use=0 exp=278635 server_id=1
0x7fa77ec4d2a4: key=immqb6ocsq8m5982o28hatk6c2 use=0 exp=276814 server_id=2
0x7fa77ec4c964: key=lg78n74u0dj51m3cvkn9qhce66 use=0 exp=279812 server_id=1
0x7fa77ec4d664: key=livn0t62bthpfvp5motknhb934 use=0 exp=276201 server_id=1
0x7fa77ec4d7e4: key=mhkh0c4lpisr9kgdb3ggmplpk1 use=0 exp=277418 server_id=1
0x7fa77ec4c1e4: key=ovfoprd6p91sjbf22qo5jjd4u0 use=0 exp=280984 server_id=1
0x7fa77ec4d724: key=rvt3fnhr51sfrqu1aefjceqlu4 use=0 exp=274422 server_id=2
0x7fa77ec4c664: key=snkm72pvasr36ut39qopd3jmb1 use=0 exp=273842 server_id=1
0x7fa77ec4d424: key=ucj2pkve527nt39mejp1n7jdu5 use=0 exp=275620 server_id=2


###################### haproxy3 ########################
# table: dynamic_group, type: string, size:5120, used:15
0x1372c24: key=1t1lr3s5s7pm4tuu3476c40jk3 use=0 exp=276198 server_id=2
0x1372e64: key=3m3o6qkfvk8l4lenk0k8to2bd6 use=0 exp=278387 server_id=2
0x1372864: key=8bg6ej7md7453sp0rrgi5vsiu7 use=0 exp=271237 server_id=1
0x1373964: key=9c4lf1tncd290mjl7vnjafnqe2 use=0 exp=277304 server_id=2
0x1373f64: key=b3gqn2i3emi43rfh3i8t0jhln4 use=0 exp=273410 server_id=1
0x1372924: key=cskoqa8vbb7fbac4eko27hnk70 use=0 exp=271784 server_id=2
0x13723e4: key=ejjgpe1j99nv7hqmnlpib5osq6 use=0 exp=276753 server_id=1
0x13726e4: key=immqb6ocsq8m5982o28hatk6c2 use=0 exp=275073 server_id=2
0x1372564: key=lg78n74u0dj51m3cvkn9qhce66 use=0 exp=277840 server_id=1
0x1373ae4: key=livn0t62bthpfvp5motknhb934 use=0 exp=274507 server_id=1
0x1372aa4: key=mhkh0c4lpisr9kgdb3ggmplpk1 use=0 exp=275631 server_id=1
0x1373ba4: key=ovfoprd6p91sjbf22qo5jjd4u0 use=0 exp=278922 server_id=1
0x1373a24: key=rvt3fnhr51sfrqu1aefjceqlu4 use=0 exp=272865 server_id=2
0x13724a4: key=snkm72pvasr36ut39qopd3jmb1 use=0 exp=272330 server_id=1
0x13738a4: key=ucj2pkve527nt39mejp1n7jdu5 use=0 exp=273971 server_id=2

結果符合預期目標,每個表都有15條stickiness,且它們的key和對應的server_id完全相同。

有了stick table的複製功能,在沒有session共用的情況下,為架構設計多提供了幾種方案。至於如何選擇,需要考慮與其配合的軟體特性。特別適用的一種情況是,在haproxy前端使用LVS代理時,由於LVS只能4層負載,很可能將同一客戶端調度到不同的haproxy節點上,如果使用stick table複製,就不用擔心haproxy不能將客戶端引導到同一後端伺服器上的問題。另一種使用stick table複製的場景是結合keepalived實現雙主模型代理不同服務時,為了會話保持也高可用,可以使用stick table的複製保證粘性記錄不丟失。

 

回到Linux系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7048359.html
回到網站架構系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7576137.html
回到資料庫系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7586194.html
轉載請註明出處:http://www.cnblogs.com/f-ck-need-u/p/8565998.html

註:若您覺得這篇文章還不錯請點擊右下角推薦,您的支持能激發作者更大的寫作熱情,非常感謝!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 驅動的完成步驟: ~~~~ 1. 分配一個 gendisk 結構體 2. 註冊塊設備 3. 分配一個 request_queue 隊列 4. 配置 gendisk 5. 完成上一篇框架中提到的 "處理函數" 6. 添加磁碟 add_disk ~~~~ 初始化程式如下 ~~~~ static int ...
  • 系統的輸入與輸出: 方式 | 描述符 | 含義 | | stdin | 0 | 標準輸入 stdout | 1 | 標準輸出 stderr | 2 | 標準錯誤輸出 把 make 輸出的全部信息重定向到某個文件中: ~~~~ make build_output ~~~~ 把錯誤信息都輸出到一個文件中 ...
  • 監控原理: ActiveMQ作為依賴java環境的中間件,同樣可以像tomcat一樣用JMX(java擴展程式)監控。並且與tomcat不同的是,ActiveMQ自帶了JMX,只需在配置文件中開啟即可,在配置好JMX之後,可以通過Jconsole(監控java環境的工具)監控ActiveMQ 環境: ...
  • Redis是我們當下比較流行使用的非關係資料庫,可支持多樣化的數據類型,多線程高併發支持,redis運行在記憶體擁有更快的讀寫。因為redis的表現如此出色,如何能保障redis在運行中能夠應對宕機故障, 所以今天總結了下redis主從高可用的搭建,參考了網上一些大神的博客文章,發現很多都是有坑的,所 ...
  • 伺服器需要換python環境,手賤重裝了,今天湊巧需要測試資料庫,花了一個小時搞了一下MySQL安裝。 1.刪除原有Mariadb 說明:目前centos預設的MySQL是Mariadb,由於習慣了MySQL(Oracle)加上一堆亂七八糟的原因,還是需要MySQL作資料庫。 Linux終端輸入命令 ...
  • 安裝前要關閉防火牆,防止外網不能訪問,這一點很重要,要不然外網訪問不了; ①關閉防火牆:service iptables stop ②永久關閉防火牆:chkconfig iptables off ③查看防火牆狀態:service iptables status 1.安裝Apache [root@lo ...
  • keepalived使用腳本進行健康檢查時的相關配置項。例如keepalived+haproxy實現haproxy的高可用。 keepalived分為vrrp實例的心跳檢查和後端服務的健康檢查。如果要配置後端服務,則後端服務只能是LVS。但vrrp能獨立與lvs存在,例如keepalive結合hap ...
  • 虛擬記憶體 demand paging 如何判斷是否在記憶體里:valid(legal + in memory)invalid(illegal or legal + not in memory)。 如何處理illegal的情況:page fault 到內核 ; 查看internal table(PCB) ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...