HAProxy是由WillyTarreau開發的一款具備高可用性、負載均衡、虛擬主機支持以及基于TCP和HTTP的應用代理開源軟件,基于HAProxy的負載均衡架構是最為常見的免費、快速且具備可靠性的集群負載均衡架構解決方案。HAProxy特別適合應用于需要會話保持或七層處理的高負載Web站點,如淘寶、Twitter、Instagram、Github和Amazon等大型網站都是HAProxy的使用者。就當前常見的硬件體系架構,基于HAProxy的負載均衡系統完全可以支撐數以萬計的并發連接,同時,HAProxy的運行模式使得將其整合到用戶當前的基礎架構中是個非常簡單且安全的過程。
HAProxy概述
HAProxy實現的是一種事件驅動、單一進程的架構模型,此類模型的優點在于能夠支撐高并發大規模的連接。反之,多進程或多線程模型受內存和系統調度器的限制以及無處不在的鎖限制,很難應對數以萬計的高并發連接。HAProxy支持連接拒絕,通過拒絕連接,可以限制某些非法或有意的攻擊型連接,從而降低其對網站帶來的危害。HAProxy的這一功能已成為目前應對小型DDoS攻擊的主要方法之一,并且其他負載均衡器很難做到這點。此外,HAProxy還支持全透明代理,即可以將客戶端IP地址或者任何指定地址直接連接到后端服務器,通過全透明代理,可以不用修改某些特殊服務器地址而使其直接接收并處理部分特定流量。
HAProxy主要為基于HTTP和TCP訪問的應用服務提供負載均衡,如基于Internet的連接服務和基于Web的應用服務。通過負載均衡算法,HAproxy能夠接受數以萬計的訪問請求并將其轉發到后端服務器池中進行處理,而后端服務器池就如一個強大的虛擬服務器接受HAProxy轉發的請求并進行處理。HAproxy的請求調度器(Scheduler)決定了后端服務器中每個服務器接受和處理的請求量,在沒有權重的調度算法下,調度器為每臺服務器分配相同數量的請求,而在加權調度算法下,調度器根據每臺服務器的權重為每個后端服務器分配不同數量的請求。HAproxy允許用戶自定義多個代理,并為每個代理提供負載均衡服務,代理由一個前端和一個或多個后端構成,前端定義了代理監聽的IP地址(VirtualIP)和端口,同時還需在前端定義中關聯與其相關的后端,而在HAProxy中,后端主要用于定義服務器池和負載均衡算法。HAproxy的負載均衡服務在7層,即應用層,在很多情況下,由于商業應用連續性的要求,管理員通常需要部署HAproxy,從而為基于HTTP的應用提供負載均衡和高可用性。
在大多數情況下,用戶通常將HAproxy和Keepalived/LVS結合共用以構建更具穩定性和擴展性的高可用環境,如淘寶的CDN架構便是如此。在利用HAProxy的高性能和可擴展性來對基于HTTP和TCP的服務進行負載均衡的同時,結合Keepalived的Failover功能,用戶系統在應對大規模訪問請求時候,不僅可以通過HAProxy實現高效的負載均衡,還可以利用Keepalived的Failover功能保證業務系統的連續性。
Haproxy配置
配置文件/etc/haproxy/haproxy.cfg,該文件是HAProxy功能配置的集中文件,其代理和負載均衡功能的配置均位于該配置文件中。HAProxy的配置文件主要分為四個部分,即全局功能配置段、默認屬性配置段、前端代理配置段、后端負載均衡配置段,各個配置段常見屬性設置和功能描述如下。
1) 全局配置段的參數將被應用到全部運行HAProxy的節點中,全局配置段并不針對具體的代理和負載均衡進行設置。用戶為HAProxy常用的全局變量配置了參數,這些參數通常是進程級別并與操作系統相關的參數,在全局上限定了HAProxy的工作特性:
?Daemon:指定HAProxy以后臺進程的形式運行。
?Group:運行HAproxy的用戶屬組,此處為HAProxy。
?Maxconn:HAProxy代理允許的最大并行連接數,此處為4000,默認為2000。
?User:運行HAProxy的用戶,此處為HAProxy。
?Pidfile:HAProxy的進程文件,此處為/var/run/haproxy.pid。
?Log:設置HAProxy運行日志的輸出設備,通常默認為本機的/var/log/syslog,并默認記錄INFO級別的日志,用戶可以將HAProxy的日志輸出到本機或者遠程主機的日志設備上,并設置需要記錄的日志級別,如ERROR和WARN。
對于大規模集群,負載均衡器可能會由運行HAProxy的多個節點組成,如果每個HAProxy節點都將日志存放到本地,則日志監控和查看極為不便,因此通常會借助遠程日志記錄功能(如rsyslog)將分散的節點日志集中到某臺日志服務器上,這時就需要在每個HAProxy的全局配置段中指定遠程日志服務器的地址和對應的日志記錄設備,同時在遠程日志記錄服務器上進行相應的設置。
2) 默認(default)配置段設置的參數會被haproxy.cfg的其他配置段繼承,如frontend 、backend和listen配置段都會繼承default配置段參數,同時這些配置段也可以寫default配置段的參數值,通常情況下,用戶可以將具有共性的參數放到default段進行統一配置,然后再到各個配置段中進行個性修改,常見的default配置段如下:
?Mode:指定HAProxy實例使用的連接協議,即源請求到后端服務器之間的連接協議,可能值為HTTP和TCP。對基于HTTP的Web應用服務,通常使用HTTP模式,對于其他應用服務,通常使用TCP模式。
?Log:指定日志地址和記錄日志條目的syslog/rsyslog日志設備,此處的global表示使用global配置段中設定的log值。
?Option:日志記錄選項,httplog表示記錄與HTTP會話相關的各種屬性值,包括HTTP請求、會話狀態、連接數、源地址以及連接時間等。dontlognull表示不記錄空會話連接日志,即HAProxy不會記錄沒有數據傳輸的會話連接日志,基于互聯網的Web應用中不推薦使用dontlognull,因為很多空會話連接可能包含有惡意行為,如惡意的端口漏洞掃描就是一種沒有數據傳輸的空連接。
?Retries:在連接失敗后重新嘗試請求連接的次數,超過設置的嘗試次數將認為連接失敗。
?Timeout:設置各種請求、連接、響應的Timeout時間,單位為秒(s)或者毫秒(m)。
?HTTP-Request:等待客戶端完整HTTP請求的時間,此處為等待10s。
?Queue:設置刪除連接和客戶端收到503或服務不可用等提示信息前的等待時間,此處等待時間為10毫秒。
?Connect:設置等待服務器連接成功的時間,此處為等待10s。
?Client:設置允許客戶端處于非活動狀態,即既不發送數據也不接收數據的時間,此處為1毫秒。
?Server:設置服務器超時時間,即允許服務器處于既不接收也不發送數據的非活動時間,此處為1毫秒。
3) Frontend前端配置主要完成兩個功能:一是配置監聽客戶端請求的IP地址和端口,在高可用環境下,此處的監聽IP地址通常為虛擬IP;二是將監聽到的客戶端請求轉發到指定的后端配置中進行負載均衡。
? ? ? ? frontend? WEB
? ? ? ? bind 192.168.0.10:80
? ? ? ? default_backend app
HAProxy中允許配置多個前端,前端名稱可以自定義,此處設置了名為Web的HAProxy前端,通過bind參數指定該前端監聽的IP為192.168.0.10,端口為80,而該前端對應的后端名稱是app,一旦Web前端監聽到連接,就會將該連接直接轉給名為app的后端處理。前端與后端是HAProxy配置中的關鍵部分,通常前端負責監聽請求連接,后端負責負載均衡。在OpenStack高可用集群配置中,由于每個OpenStack服務進行高可用配置,因此最佳做法就是將每個服務配置為一個前端和后端的組合,并將前端監聽的VIP通過Pacemaker或者Keepalived進行高可用設計。
? ? ? //數據庫服務前端
? ? ? ? frontend vip-db
? ? ? ? bind 192.168.142.201:3306
? ? ? ? timeout client 90m
? ? ? ? default_backend db-vms-Galera
? ? ? ? //qpid消息服務前端
? ? ? ? frontend vip-qpid
? ? ? ? bind 192.168.142.215:5672
? ? ? ? timeout client 120s
? ? ? ? default_backend qpid-vms
? ? ? ? //dashboard 服務前端
? ? ? ? frontend vip-horizon
? ? ? ? bind 192.168.142.211:80
? ? ? ? timeout client 180s
cookie SERVERID insert indirect nocache
? ? ? ? default_backend horizon-vms
4) Backend后端配置主要實現兩個主要功能:一是負載均衡調度算法的設置;二是設置最終響應請求的服務器池各個節點的IP地址和端口,并設置每個節點的健康檢查方式。一個典型的后端配置如下。
? ? ? ? backend app
? ? ? ? balance? ? ? roundrobin
? ? ? ? server? app1? 192.168.1.1:80 check
? ? ? ? server? app2? 192.168.1.2:80 check
? ? ? ? server? app3? 192.168.1.3:80 check inter 2s rise 4 fall 3
? ? ? ? server? app4 192.168.1.4:80 backup
HAProxy允許配置多個后端,且每個后端都有一個前端與其對應,后端實例的名稱可以用戶自定義,但是一定要與對應前端中設置的后端名稱一致。上述后端配置中,后端實例的名稱是app,采用Round-Robin負載均衡算法,server定義后端的真實服務器,服務器的名稱為app1、app2、app3和app4,這里的服務器名稱并非真實的后端服務器主機名,而只是便于識別的自定義服務器名稱,服務器的具體地址通過緊隨其后的IP地址和端口號來確定。在定義后端服務器的同時,通過check參數可指定HAProxy對服務器的健康檢查方式,上述配置中,后端服務器app3中inter 2s指定了對app3進行健康檢查的時間間隔是2s,rise 4表示HAProxy對app3發起4次健康檢查均正常則認為app3正常,fall 3表示連續3次健康檢查失敗則認為app3已經故障。
HAProxy后端配置中指定了負載均衡所采用的算法,HAProxy支持多種負載均衡算法,用戶可以根據后端服務器池中各個節點的實際資源配置進行不同的算法選取,HAProxy支持的負載均衡算法有以下幾種。
?Round-Robin(round robin):與Keepalived的Round-Robin類似,服務請求會被輪詢轉發到服務器池中的每一個服務器上,而不去評估服務器的當前負載和處理能力,服務器池中的每個節點都被輪詢轉發請求。
?Static Round-Robin(static-rr):與Round-Robin一樣輪詢轉發請求到每一個后端服務器,但是不允許對后端服務器進行動態加權設置,即服務器的權重是靜態固定的,而由于權重靜態固定,后端服務器池中的節點數目不受限。
?Least-Connection(leastconn)最少連接數算法:與Keepalived的最少連接數算法類似,后端服務器活動連接數越多,則接收到的服務請求就越少,反之,則接收到的服務請求越多。
?Source(source):將請求中的源IP地址進行HASH后除以全部正常運行的后端服務器權重來決定接收服務請求的服務器,在這種算法中,同一個客戶端(相同的源IP地址)發出的請求會被固定轉發給某一個固定的后端服務器。但是,如果服務器權重大小發生改變或者服務器數目出現變動,HASH/Wight值發生改變,則響應該客戶端請求的后端服務器會改變。
?URL(url):將請求URL字符串進行HASH并除以全部正常運行的后端服務器權重來決定接收服務請求的服務器,在這種算法中,指向同一目標站點的服務請求會被固定轉發到相同的后端服務器上。URL稱為基于目標地址的HASH負載均衡算法,主要用于Web Cache集群中,通過URL負載均衡算法,可以避免請求因為指向不同的Cache服務器而導致缺頁,而缺頁會導致刷新Cache最終降低系統響應速率。
?URL Parameter(url_param):通過查詢源HTTP請求報文中的某一字符串參數并將其進行HASH后除以全部服務器權重來決定接收服務請求的服務器。如果HTTP報文中沒有需要的參數,則默認Round-Robin算法。
?Header Name(hdr):通過查詢HTTP請求報文中的HEAD字段并將其進行HASH后除以全部服務器權重來決定接收服務請求的服務器。如果報文中沒有HEAD參數,則默認使用Round-Robin算法。
在高可用集群配置中,為了實現服務的高可用,通常每個后端配置中都需要提供兩個以上的后端服務器進行負載均衡。OpenStack高可用集群配置中,為實現每個OpenStack服務的高可用性,通常為每個服務配置三個控制節點,而這三個控制節點即HAProxy后端配置中的后端服務器,OpenStack高可用集群配置的HAProxy后端配置示例如下:
? ? ? ? //heat服務后端
? ? ? ? backend heat-srv-vms
? ? ? ? balance roundrobin
? ? ? ? server controller1-vm 192.168.142.110:8004 check inter 1s
? ? ? ? server controller2-vm 192.168.142.111:8004 check inter 1s
? ? ? ? server controller3-vm 192.168.142.112:8004 check inter 1s
? ? ? ? //ceilometer服務后端
? ? ? ? backend ceilometer-vms
? ? ? ? balance roundrobin
? ? ? ? server controller1-vm 192.168.142.110:8777 check inter 1s
? ? ? ? server controller2-vm 192.168.142.111:8777 check inter 1s
? ? ? ? server controller3-vm 192.168.142.112:8777 check inter 1s
? ? ? ? //MySQL數據庫服務后端
? ? ? ? backend db-vms-Galera
? ? ? ? option httpchk
? ? ? ? option tcpka
? ? ? ? stick-table type ip size 1000
? ? ? ? stick on dst
? ? ? ? timeout server? 90m
? ? ? ? server? controller1-vm? 192.168.142.110:3306? check? inter? 1s? port? 9200? backup? on-marked-down shutdown-sessions
? ? ? ? server? controller2-vm? 192.168.142.111:3306? check? inter? 1s? port? 9200? backup? on-marked-down shutdown-sessions
? ? ? ? server? controller3-vm? 192.168.142.112:3306? check? inter? 1s? port? 9200? backup? on-marked-down shutdown-sessions
HAProxy配置完成之后,在各個節點啟動HAProxy服務即可正常使用HAProxy強大的負載均衡功能。
? ? ? ? //啟動haproxy服務
? ? ? ? systemctl start haproxy.service
? ? ? ? //設置開機自啟動haproxy服務
? ? ? ? systemctl enable haproxy.service
筆記整理來自山金孝的《OpenStack高可用集群(上冊):原理與架構》4.2.1和4.2.2章節,如有侵權請通知刪除