互聯網架構基礎知識
一、網站常見架構
-
負載層
-
頁面緩存層
-
web層
-
數據層
二、運維法則
-
緩存為王
-
盡量在前端(緩存層)響應完成
-
應用和服務解耦
三、網站灰度發布的步驟
-
先下線需要下線的服務器(markdown)
-
停止服務(需要等待keepalive的時長后)
-
關閉監控(以免監控大量的報警)
-
替換程序(全量、增量)
- 一般情況下將多個版本軟鏈至指定的目錄,必要是可以回滾操作
-
啟動服務
-
warmingup(預熱)
- 對頁面進行訪問請求,進行緩存數據環節,以免大流量打跨服務器,冷數據的服務上線會導致雪崩(可能需要依賴一此程序進行訪問預熱)
-
測試
- 進行測試操作,以免有未發現的bug
-
加監控
-
上線
-
review
- 檢查復審,查看日志
四、web常見術語
-
UV : User view
-
PV : Page view
衡量一個網站的穩定性和承載能力,一般比較好的網站每個UV平均15個PV
-
活動連接數
連接狀態為Established,一般情況下,使用日PV/18(小時),可以計算一個粗略的活動連接數,在短鏈的情況下,活動連接數與QPS比較接近
-
QPS(并發)
連接狀態為:time_wait close_wait,是NEW的請求
-
并發峰值
測量一個網站的重要指標,架構設計承載需要是最高并發峰值的5到10倍
代理的基礎知識
代理的作用
-
1、web緩存
以提供加速
-
2、反向代理
以提高安全性和流量分發
-
3、內容路由
根據流量及內容類型等將請求轉發至特定服務器
-
4、轉碼器
后端到代理服務器沒有壓縮,代理到客戶端進行壓縮
代理的重要性能指標
-
會話率
每秒建立新的連接速率
-
會話并發能力
-
數據率
數據傳輸率
LB實現方式
-
TCP層
- LVS
- haproxy
- nginx
-
應用層
- haproxy
- nginx
- ats
- apache
KV數據的常用算法
-
取模法
對K進行hash計算,有幾臺cache服務器就取模多少數值,可以將每次的請求分散至不同的服務器
* 缺點
添加和刪除服務器,都會帶來全部緩存失效
-
一致性hash算法
事先虛擬一個環,環上從零開始計數,到232個數值結束,其使用32位二進制表示,把每個服務器按照特定的方式計算(如IP地址進行hash計算),其hash的結果一定會在環上的0到232之間,服務器計算的結果就分散在此環之上。緩存數據時,對key進行hash計算,按順時針找到離的最近的一個節點存放數據。如果其中一臺cache server檔機,只會影響此服務器上緩存的數據,不會讓緩存全部失效
* 缺點:
hash環的偏斜(多個節點計算后,節點都在環上較近位置且在環的一側位置),可以使用虛擬服務器方法解決(將一個節點虛擬成多個節點,再分散到環上)
Linux之HAProxy
一、HAProxy簡介
HAProxy提供高可用性、負載均衡以及基于TCP和HTTP應用的代理 ,支持虛擬機,它是免費、快速并且可靠的一種解決方案。HAProxy特別適用于高負載且需要持久連接或7層處理機制的web站點,這些站點通常又要會話保持或七層處理,HAProxy運行在時下的硬件上,完全可以支持數以萬計的并發連接,并且它的運行模式使得它可以很簡單安全的融合進你當前的架構中,同時可以保護你的web服務器不被暴露到網絡上。
HAProxy實現了一種事件驅動、單一進行模型,此模型支持非常大的并發連接數,多進行或多線程模型受內存限制、系統調度器限制以及無處不在的鎖限制,很少處理數千并發連接。事件驅動模型因為在有更好的資源和時間管理的用戶端(user-space)實現所有這些任務,所以沒有這些問題。 此模型的弊端是,在多核系統上,這些程序通常擴展性較差,這就是為什么它們必須進行優化以使每次個CPU時間片(Cycle)做更多的工作。
二、HAProxy主要版本:
1.4版本
其衍生于1.2版本,并提供額外的新特性,其中大多數是期待已久的
- 1、客戶端側的長連接(Client-side keep-alive)
- 2、TCP加速(TCP speedups)
- 3、響應池(response buffering)
- 4、RDP協議(remote desktop protocol)
- 5、基于源的粘性(Source-based stickiness)
- 6、更好的數據統計接口(a much better stats interfaces)
- 7、更詳細的健康狀態檢測機制(more verbose health checks)
- 8、基于流量的健康評估機制(traffic-based health)
- 9、支持http認證
- 10、服務器管理命令行接口(server management from the CLI)
- 11、基于ACL的持久性(ACL-based persistence)
- 12、日志分析器
1.3版本
其衍生于1.2版本,并提供了額外的新特性
- 1、內容交換(Content switching):基于任何請求標準挑選服務器池
- 2、ACL:編寫內容交換規則
- 3、負載均衡算法(load-balancing algorithms):更多的算法支持
- 4、內容檢測(Content ipspection):阻止非授權協議
- 5、透明代理(transparent proxy):在Linux系統上允許使用客戶端IP地址連入服務器
- 6、內核TCP拼接(kernel TCP splicing):無copy方式在客戶端和服務端之間的轉發數據以實現G級別的數據速率
- 7、分層設計(layered design):分別實現套接字、TCP、HTTP處理以提供更好的健壯性,更好的處理機制及便捷的演進能力
- 8、快速、公平調度器(fast and fair scheduler):為某些任務指定優先級可實現更好的Qos
- 9、會話速率限制(session rate limiting):適用于托管環境
三、支持的平臺及OS
- x86、x86_64、Alpha、SPARC、MIPS及PARISC平臺上的Linux 2.4
- x86、x86_64、ARM (ixp425)及PPC64平臺上的Linux2.6
- UltraSPARC 2和3上的Sloaris 8/9
- Opteron和UltraSPARC平臺上的Solaris 10
- x86平臺上的FreeBSD 4.1-8
- 386, amd64, macppc, alpha, sparc64和VAX平臺上的OpenBSD 3.1-current
若要獲得最高性能,需要在Linux2.6或打了epoll補丁的Linux2.4上運行haproxy 1.2.5以上的版本,haproxy1.1l默認使用了polling系統為select(),其處理的文件數達數千個時性能便會急劇下降,1.2和1.3版本默認為poll(),在有些操作系統上可能會有性能方面的問題,但在Solaris上表現相當不錯,HAProxy1.3在Linux2.6及打了epoll補丁的Linux 2.4上默認使用了epoll,在FreeBSD上使用Kqueue,這兩種機制在任何負載上都能提供恒定的性能表現,在較新版本的Linux2.6(>=2.6.27.19)上,HAProxy還能夠使用splice()系統調用在接口間無復制地轉發任何數據,這甚至可達到10Gbps性能
HAProxy常規版本選擇建議
- Linux 2.6.32及之后版本上運行HAProxy1.4
- 打了epoll補丁的Linux 2.4上運行HAProxy1.4
- FreeBSD上運行HAProxy1.4
- Solaris 10上運行Haproxy 1.4
四、HAProxy實現高性能的方法
-
1、單進程、事件驅動模型
顯著降低了上下文切換的開銷及內存占用
-
2、O(1)事件檢查器(event checker)
允許其在高并發連接中對任何連接的任何事件實現即時探測
-
3、單緩沖(single buffering)機制
以不復制任何數據的方式完成讀寫操作,這會節約大量的CPU時鐘周期及內存帶寬
-
4、splice()系統調用機制
在2.6(>=2.6.27.19)Haproxy可以實現零復制轉發(zero-copy forwarding),在Linux3.5及以上的OS中還可以實現零復制啟動(zero-starting)
-
5、優秀的內存分配器
內存分配器在固定大小的內存池中實現即時內存分配,能夠顯著減少創建一個會話的時長
-
6、樹形存儲
側重于使用作者多年前開發的彈性二叉樹算法,實現了以O(log(N))的低開銷來保持啟動計時器命令、保持運行隊列命令及管理輪詢及最少連接隊列
-
7、優化的HTTP首部分析機制
優化的首部分析功能避免了HTTP首部分析過程中重讀任何區域
-
8、精心地降低了昂貴的系統調用
大部分工作在用戶空間完成,如時間讀取、緩沖聚合及文件描述符的啟用和禁用等
所有的這些細微之處的優化實現了在中等規模負載之上依然有著相當低的CPU負載,甚至于在非常高的負載場景中,5%的用戶空間占用率和95%的系統空間占用率也是非常普遍的現象,這意味著HAProxy進程消耗比系統空間消耗低20倍以上。因此,對OS進行性能調優是非常重要的。即使用戶空間的占用率提高一倍,其CPU占用率也僅為10%,這也解釋了為何7層處理對性能影響有限這一現象。由此,在高端系統上HAProxy的7層性能可輕易超過硬件負載均衡設備。
在生產環境中,在7層處理上使用HAProxy作為昂貴的高端硬件負載均衡設備故障故障時的緊急解決方案也時長可見。硬件負載均衡設備在“報文”級別處理請求,這在支持跨報文請求(request across multiple packets)有著較高的難度,并且它們不緩沖任何數據,因此有著較長的響應時間。對應地,軟件負載均衡設備使用TCP緩沖,可建立極長的請求,且有著較大的響應時間。
配置HAProxy
安裝haproxy
- yum install haproxy
配置程序及配置文件
/etc/haproxy/haproxy.cfg
/usr/sbin/haproxy
/etc/haproxy/haproxy.cfg
配置文件格式
-
global配置段
用于設定全局配置參數
-
proxy相關配置段
如defaults,listen,frontend和backend
時間格式
一此包含了值的參數表示時間,如超時時長,這些值一般以毫秒為單位,但也可以使用其它的時間單位后綴
-
us
: 微秒(microseconds),即1/1000000秒 -
ms
: 毫秒(milliseconds),即1/1000秒 -
s
: 秒(seconds) -
m
: 分鐘(minutes) -
h
: 小時(hours) -
d
: 天(days)
示例:
global
daemon
maxconn 25600
defaults
mode http
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
frontend http-in
bind *:80
default_backend servers
backend servers
server server1 127.0.0.1:8080 maxconn 32
配置了一個監聽在所有接口的80端口上HTTP proxy服務,它轉發所有的請求至后端監聽在127.0.0.1:8000上的"server"
全局配置
global配置中的參數為進程級別的參數,且通常與運行的OS相關
-
進程管理及安全相關的參數
-
chroot <jail dir>
- 修改haproxy的工作目錄至指定的目錄并在放棄權限之前執行chroot()操作,可以提升haproxy的安全級別,不過需要注意的是要確保指定的目錄為空目錄且任何用戶均不能有寫權限
-
daemon
- 讓Haproxy以守護進程的方式工作于后臺
-
gid <number>
- 以指定的GID運行haproxy
-
group <group name>
- 同GID,不過指定的是組名
-
log <address <facility> [max level [min level]]
- 定義全局的syslog服務器,最多可定義兩個
-
log-send-hostname [string]
- 在syslog信息的首部添加當前主機名,默認是使用當前主機名
-
nbporc <number>
- 指定啟動的haproxy進程個數,默認只啟動一個,一般只在單進程僅能打開少數文件描述符的場景才使用多進程模式
-
pidfile <file>
- pid文件
-
uid
- 以指定的UID身份運行進程
-
unlimit -n
- 設定每進程能夠打開的最大文件描述符數據,默認情況下其會自動進行計算,不推薦修改此項
-
user
- 同UID,但使用用戶名
-
stats socket /var/lib/haproxy/status
- 訪問stats時,使用socket調用的文件
-
node
- 定義當前節點的名稱,用于HA場景中多haproxy進程共享同一個IP地址時使用
-
description
- 當前實例的描述信息
-
-
性能調整相關的參數
-
maxconn <number>
- 設定每個haproxy進程所接受的最大并發連接數,等同于ulimit -n
-
maxpipes <number>
- haproxy使用Pipe完成基于內核的TCP報文重組,用于設定每進行所允許使用的最大Pipe個數,每個pipe使用兩個文件描述符
-
noepoll
- 在linux系統上禁用epoll機制
-
nokqueue
- 在BSD系統上禁用kqueue機制
-
nopoll
- 禁用poll機制
-
nosepoll
- 在linux禁用啟發式epoll機制
-
nosplice
- 禁止在Linux套按字上使用內核tcp重組,這會導致更多的recv/send系統調用,不過在2.6.25-28系統的內核上,tcp重組功能有bug
-
spread-checks <0..50,in percent>
- 在haproxy后端有著眾多服務器的場景中,在精確的時間間隔后統一對眾服務器進行健康狀況檢查可能會帶來意外問題;此選項用于將其檢查的時間間隔長度上增加或減小一定的隨機時長
-
tune.bufsize <number>
- 設定buffer的大小,同樣的內存條件下,較小的值可以讓haproxy有能力接受更多的并發連接,較大的值可以讓某些應用程序使用較大的cookie信息;默認為16384,其可以在編譯時修改,不過強烈建議使用默認值
-
tune.chksize <number>
- 檢查緩沖的大小,專用檢測用戶的請求首部信息,建議默認值
-
tune.maxaccept <number>
- 一次性一次交由多少個請求給進程
-
tune.maxpollevents <number>
- 設定一次系統調用可以處理的事件最大數,默認值取決于OS;其值小于200時可節約帶寬,但會略微增大網絡延遲,而大于200時會降低延遲,但會稍稍增加網絡帶寬的占用量;
-
tune.maxrewrite <number>
- 設定首部重寫或追加而預留的緩沖空間,建議使用1024左右的大小,在需要使用更大的空間時,haproxy全自動增加其值
debug
: 調度模式quiet
: 靜默模式
-
代理
代理相關的配置可以有如下配置段
-
defaults <name>
- 用于為所有其它配置段提供默認參數,這配置默認配置參數可由下一個defaults所重新設定
-
frontend <name>
- 用于定義一系列監聽的套拼字,這些套按字可接受客戶端請求并與之建立連接
-
backend <name>
- 用于定義一系列“后端”服務器,代理將會將對應客戶端的請求轉發至這些服務器
-
listen <name>
- 通過關聯“前端”和“后端”定義了一個完整的代理 ,通常只對TCP流量有效
所有代理的名稱只能使用大寫字母、小寫字母、數字、-(中線)、_(下劃線)、.(點號)和:(冒號)。此外,ACL名稱會區分字母大小寫。
配置文件中的關鍵字參考
1、balance
- 用法
balance <algorithm> [arguments]
balance url_param <param> [check_post [<max_wait>]]
- 功能
- 定義負載算法,可用于defaults,listen,backend段
支持的算法類型:
- 動態:權重可動態調整,服務器自己調整
- 靜態:調整權重不會實時生效,只有重啟才會生效
調度算法
-
roundrobin
基于權重進行輪叫,在服務器的處理時間保持均勻分布時,這是最平衡、最公平的算法。此算法是動態的,這表示其權重可以在運行時進行調整,不過,在設計上,每個后端服務器僅能最多接受4128個連接
-
static-rr
基于權重進行輪叫,與roundrobin類似,但是為靜態方法,在運行時調整其服務器權重不會生效;不過,其在后端服務器連接數上沒有限制
-
leastconn
新的連接請求被派發至具有最少連接數目的后端服務器;在有著較長時間會話的場景中推薦使用此算法,如LDAP、SQL等,其并不太適用于較短會話的應用層協議,如HTTP;此算法是動態的,可以在運行時調整其權重
-
source
將請求的源地址進行hash運算,并由后端服務器的權重總數相除后派發至某匹配的服務器;這可以使得同一個客戶端IP的請求始終被派發至某特定的服務器;不過,當服務器權重總數發生變化時,如某服務器宕機或添加了新的服務器,許多客戶端的請求可能會被派發至與此前請求不同的服務器;常用于負載均衡無cookie功能的基于TCP的協議;其默認為靜態,不過也可以使用hash-type修改此特性
-
uri
對URI的左半部分(“問題”標記之前的部分)或整個URI進行hash運算,并由服務器的總權重相除后派發至某匹配的服務器;這可以使得對同一個URI的請求總是被派發至某特定的服務器,除非服務器的權重總數發生了變化;此算法常用于代理緩存或反病毒代理以提高緩存的命中率;需要注意的是,此算法僅應用于HTTP后端服務器場景;其默認為靜態算法,不過也可以使用hash-type修改此特性
-
uri-param
通過<argument>為URL指定的參數在每個HTTP GET請求中將會被檢索;如果找到了指定的參數且其通過等于號“=”被賦予了一個值,那么此值將被執行hash運算并被服務器的總權重相除后派發至某匹配的服務器;此算法可以通過追蹤請求中的用戶標識進而確保同一個用戶ID的請求將被送往同一個特定的服務器,除非服務器的總權重發生了變化;如果某請求中沒有出現指定的參數或其沒有有效值,則使用輪叫算法對相應請求進行調度;此算法默認為靜態的,不過其也可以使用hash-type修改此特性
-
hdr(name)
對于每個HTTP請求,通過<name>指定的HTTP首部將會被檢索;如果相應的首部沒有出現或其沒有有效值,則使用輪叫算法對相應請求進行調度;其有一個可選選項“use_domain_only”,可在指定檢索類似Host類的首部時僅計算域名部分(比如通過www.magedu.com來說,僅計算magedu字符串的hash值)以降低hash算法的運算量;此算法默認為靜態的,不過其也可以使用hash-type修改此特性
rdp-cookie
rdp-cookie(name)
示例1:
backend app
balance hdr(User-Agent)
server srv1 172.16.36.70:80 check
server srv2 172.16.36.71:80 check
server srv3 172.16.36.60:80 check
server srv4 172.16.36.61:80 check
示例2:
backend app
balance uri
hash-type consistent
server srv1 172.16.36.70:80 check
2、bind
-
用法
bind [<address>]:<port-range> [,...]
bind [<address>]:<port_range> [, ...] interface <interface>
-
功能
- 此指令僅能用于frontend和listen區段,用于定義一個或幾個監聽的套接字
frontend main
bind *:80
bind *:8080
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .gif .png .css .js
3、mode
-
用法
mode {tcp|http|health}
-
功能
- 設定實例的運行模式或協議。當實現內容交換時,前端和后端必須工作于同一種模式(一般說來都是HTTP模式),否則將無法啟動實例
tcp:實例運行于純TCP模式,在客戶端和服務器端之間將建立一個全雙工的連接,且不會對7層報文做任何類型的檢查;此為默認模式,通常用于SSL、SSH、SMTP等應用;
http:實例運行于HTTP模式,客戶端請求在轉發至后端服務器之前將被深度分析,所有不與RFC格式兼容的請求都會被拒絕;
health:實例工作于health模式,其對入站請求僅響應“OK”信息并關閉連接,且不會記錄任何日志信息;此模式將用于響應外部組件的健康狀態檢查請求;目前業講,此模式已經廢棄,因為tcp或http模式中的monitor關鍵字可完成類似功能
4、hash-type
- 用法
hash-type <method>
- 功能
- 定義用于將hash碼映射至后端服務器的方法;其不能用于frontend區段;可用方法有map-based和consistent,在大多數場景下推薦使用默認的map-based方法
map-based:hash表是一個包含了所有在線服務器的靜態數組。其hash值將會非常平滑,會將權重考慮在列,但其為靜態方法,對在線服務器的權重進行調整將不會生效,這意味著其不支持慢速啟動。此外,挑選服務器是根據其在數組中的位置進行的,因此,當一臺服務器宕機或添加了一臺新的服務器時,大多數連接將會被重新派發至一個與此前不同的服務器上,對于緩存服務器的工作場景來說,此方法不甚適用。
consistent:hash表是一個由各服務器填充而成的樹狀結構;基于hash鍵在hash樹中查找相應的服務器時,最近的服務器將被選中。此方法是動態的,支持在運行時修改服務器權重,因此兼容慢速啟動的特性。添加一個新的服務器時,僅會對一小部分請求產生影響,因此,尤其適用于后端服務器為cache的場景。不過,此算法不甚平滑,派發至各服務器的請求未必能達到理想的均衡效果,因此,可能需要不時的調整服務器的權重以獲得更好的均衡性。
backend app
balance uri
hash-type consistent
server srv1 172.16.36.70:80 check
server srv2 172.16.36.71:80 check
server srv3 172.16.36.60:80 check
server srv4 172.16.36.61:80 check
-
5、log
- 用法
log global
log <address> <facility> [<level>][<minlevel>]
- 功能
- 為每個實例啟用事件和流量日志,因此可用于所有區段。每個實例最多可以指定兩個log參數,不過,如果使用了“log global”且"global"段已經定了兩個log參數時,多余了log參數將被忽略
- 用法
-
6、maxconn
- 用法
maxconn <conns>
- 功能
- 設定一個前端的最大并發連接數,因此,其不能用于backend區段。對于大型站點來說,可以盡可能提高此值以便讓haproxy管理連接隊列,從而避免無法應答用戶請求。當然,此最大值不能超出“global”段中的定義。此外,需要留心的是,haproxy會為每個連接維持兩個緩沖,每個緩沖的大小為8KB,再加上其它的數據,每個連接將大約占用17KB的RAM空間。這意味著經過適當優化后,有著1GB的可用RAM空間時將能維護40000-50000并發連接。如果為<conns>指定了一個過大值,極端場景下,其最終占據的空間可能會超出當前主機的可用內存,這可能會帶來意想不到的結果;因此,將其設定了一個可接受值方為明智決定。其默認為2000
- 用法
-
7、default_backend
- 用法
maxconn <conns>
- 功能
- 在沒有匹配的"use_backend"規則時為實例指定使用的默認后端,因此,其不可應用于backend區段。在"frontend"和"backend"之間進行內容交換時,通常使用"use-backend"定義其匹配規則;而沒有被規則匹配到的請求將由此參數指定的后端接收。
- 用法
frontend main *:80
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -j .jpg .gif .png .css .js
use_backend static if url_static
default_backend app
-
8、server
-
用法:
server <name> <address>[:port][param*]
-
功能:
- 為后端聲明一個server,因此不能用于defaults和frontend區段
-
服務器或默認服務器參數
- backup : 設定為備用服務器,即sorry server
- check : 健康狀態檢測
- inter <delay> : 設定健康狀態檢測時的時間,默認為2000,單位為ms
- fall <number> : 從up-->down(soft state-->hard state),默認為3次
- rise <number> : 從down-->up的次數
- cookie <value> : 為server設定個cookie值,會話級別的cookie,基于cookie的原綁定方式,會在響應報文中的cookie頭后添加相應的cookie值
- maxconn :此服務器接受的并發連接最大數值
- maxqueue : 請求隊列的最大長度
- observer <mode> : 通過流量判斷后端服務器的狀態,默認為禁用,其支持4層和7層
- weight <number> : 默認為1,最大為256,0表示不被調用
- redir <prefix> : 啟用重定向功能,所有發往此服務器的GET和HEAD請求,均以302響應,在prefix最后不能加/,且不能使用相對地址
server srv1 172.16.100.6:80 redir http://imageserver.zhenping.me check
-
-
9、opttion check
-
用法:
option httpchk
option httpchk <uri>
option httpchk <method> <uri>
-
option httpchk <mothod> <uri> <version>
:不能用于frontend段
-
功能
- 健康狀態檢測方法定義
-
backend https_relay
mode tcp
option check OPTIONS * HTTP/1.1\r\nHost:\ www.zhenping.me
server apache1 172.16.36.70 check prot 80
對server172.16.36.70使用option check定義的方法進行檢測,但可以使用80端口進行健康狀態檢測
-
10、capture request header
- 用法:
capture request header <name> len <length>
- 功能:
- 捕獲并記錄指定的請求首部最近 一次出現時的第一個值,僅能用于“frontend”和“listen”區段。捕獲的首部值使用花括號{}括起來后添加進日志中。如果需要捕獲多個首部值,它們將以指定的次序出現在日志文件中,并以豎線“|”作為分隔符。不存在的首部記錄為空字符串,最常需要捕獲的首部包括在虛擬主機環境中使用的“Host”、上傳請求首部中的“Content-length”、快速區別真實用戶和網絡機器人的“User-agent”,以及代理環境中記錄真實請求來源的“X-Forward-For”。可以捕獲的請求首部的個數沒有限制,但每個捕獲最多只能記錄64個字符。為了保證同一個frontend中日志格式的統一性,首部捕獲僅能在frontend中定義。
- 用法:
-
11、capture response header
- 用法
capture response header <name> len <length>
- 功能
- 捕獲并記錄響應首部,其格式和要點同請求首部
- 用法
-
11、stats enable
- 用法
stats enable
- 功能
- 啟用基于程序編譯時默認設置的統計報告,不能用于frontend段,
listen statistics #定義listen區段名稱 bind *:9090 #定義監聽端口 stats enable #啟用stats stats hide-version #隱藏版本 stats refresh 10s #刷新時間 stats uri /haproxyadmin?stats #stats的URI地址 stats realm "HAProxy\ statistics" #stats的登陸提示信息 stats auth zhenping:123321 # 定義用戶名和密碼 stats admin if TRUE #如果用戶驗證成功,就給予admin權限
- 用法
-
12、option httplog
- 用法
option httplog [clf]
- 功能
- 啟用記錄HTTP請求,會話狀態和計時器的功能,默認情況下,日志輸入格式非常簡陋,因為其僅包括源地址、目標地址和實例名稱,而“option httplog”參數將會使得日志格式變得豐富許多,其通常包括但不限于HTTP請求、連接計時器、會話狀態、連接數、捕獲的首部及cookie、“frontend”、“backend”及服務器名稱,當然也包括源地址和端口號等
- 用法
-
13 option logasap
-
14 no option logasap
- 功能:
啟用或禁用提前將http請求記入日志,不能用于frontend段
listen http_proxy 0.0.0.0:80 mode http option httplog option logasap log 172.16.100.9 local2
- 功能:
-
15、option forwardfor
- 用法:
option forwardfor [except <network>][header <name>][if-none]
- 功能
允許在發往服務器的請求首部中插入“X-Forwarded-For”首部,些參數定義后,需要在后端服務器的記錄日志格式修改為記錄X-Forwarded-For的信息,方可記錄下客戶端IP地址
if-none: 僅在此首部不存在時才將其添加至請求報文中。
frontend www mode http option forwardfor except 127.0.0.1/8
- 用法:
-
16、errorfile
- 用法:
errorfile <code> <file>
- 功能
- 在用戶請求不存的頁面時,返回一個頁面文件給客戶端而非由haproxy生成的錯誤代碼;可用于所有段中
- <code> : 指定對HTTP的哪些狀態碼返回指定的頁面;這里可用的狀態碼有200、400、403、408、500、502、503和504
- <file>:指定用于響應的頁面文件
errorfile 400 /etc/haproxy/errorpages/400badreq.http errorfile 403 /etc/haproxy/errorpages/403forbid.http errorfile 503 /etc/haproxy/errorpages/503sorry.http
- 用法:
-
17、errorloc和errorloc302
- 用法:
errorloc <code> <url>
errorloc302 <code> <url>
- 功能
- 請求錯誤時,返回一個HTTP重定向至某URL的信息;可用于所有配置段中。
- <code>:指定對HTTP的哪些狀態碼返回指定的頁面;這里可用的狀態碼有200、400、403、408、500、502、503和504;
- <url>:Location首部中指定的頁面位置的具體路徑,可以是在當前服務器上的頁面的相對路徑,也可以使用絕對路徑;需要注意的是,如果URI自身錯誤時產生某特定狀態碼信息的話,有可能會導致循環定向
- 用法:
需要留意的是,這兩個關鍵字都會返回302狀態碼,這將使得客戶端使用同樣的HTTP方法獲取指定的URL,對于非GET方法的場景(如POST)來說會產生問題,因為返回客戶的URL是不允許使用GET以外的其它方法的。如果的確有這種問題,可以使用errorloc303來返回303狀態碼給客戶端
-
18、errorloc303
- 用法:
errorloc303 <code> <url>
- 功能
- 請求錯誤時,返回一個HTTP重定向至某URL的信息給客戶端,可用于所有配置段中
- <code>:指定對HTTP的哪些狀態碼返回指定的頁面;這里可用的狀態碼有400、403、408、500、502、503和504;
- <url>:Location首部中指定的頁面位置的具體路徑,可以是在當前服務器上的頁面的相對路徑,也可以使用絕對路徑;需要注意的是,如果URI自身錯誤時產生某特定狀態碼信息的話,有可能會導致循環定向
- 用法:
backend webserver
server 172.16.100.6 172.16.100.6:80 check maxconn 3000 cookie serv01
server 172.16.100.7 172.16.100.7:80 check maxconn 3000 cookie serv02
errorfile 403 /etc/haproxy/errorpages/sorry.htm
errorfile 503 /etc/haproxy/errorpages/sorry.htm
-
19、option http-server-close
-
20、no option http-server-close
- 功能:由客戶端到服務端的連接設定,當HAProxy的保持連接開啟的時候,需要把這項開起來,服務器主動斷開連接,其是向報文中添加connection:close的頭信息,客戶端收到后,將發出斷開連接請求
-
21、option http-pretend-keepalive
- 功能:當啟用http-server-close或option forceclose代理服務器添加一個connect:close(就是短連接模式)的頭部信息,轉發至后端server,當后端的server收到報文后,無法識別或拒絕響應。所以需要代理 服務器就需要假裝是保持連接模式,而不發送connection:close的信息頭部,在使用了option forceclose,http-server-close的選項時,就應該啟用http-pretend-keepalive選項
-
22 option httpclose
-
23 no option httpcolse
- 功能:啟用或禁用被動http連接功能,是否允許服務端斷開連接,跟http-server-close一樣
-
24、option redispatch
-
25、no option redispatch
- 是否允許做重新調度,如果做了保持功能的情況下,被訪問的主機壞了,是不是允許把請求調到其它主機
-
26、redirect
- 功能:做重定向
acl clear dst_port 80 acl secure dst_port 80 acl login_page url_beg /login acl logout url_beg /logout acl uid_given url_reg /login?userid=[^&]+ acl cookie_set hdr_sub(cookie) SEEN=1 redirect prefix https://zhenping.me set-cookie SEEN=1 if !cookie_set redirect prefix https://zhenping.me if login_page !secure redirect location http://www.zhenping.me if !login_page secure redirect location / clear-cookie USERID= if logout
-
27、reqadd
- 功能:向請求報文添加首部
acl is-ssl dst_port 81 reqadd X-Proto:\ SSL if is-ssl 如果是通過81訪問的請求,就向請求首部添加X-Proto: SSL的首部信息
-
28、rspadd
- 向響應報文添加首部
rspadd Via:\ node1.zhenping.me
-
29、timeout http-keep-alive
- 用法:
timeout http-keep-alive 10s
- 功能:
- 開啟haproxy的保持連接功能
- 用法:
-
30、option dontlognull
- 功能:不記錄自己的健康狀態檢查的日志
配置案例
http服務器配置示例
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 30000
listen stats
mode http
bind 0.0.0.0:1080
stats enable
stats hide-version
stats uri /haproxyadmin?stats
stats realm Haproxy\ Statistics
stats auth admin:admin
stats admin if TRUE
frontend http-in
bind *:80
mode http
log global
option httpclose
option logasap
option dontlognull
capture request header Host len 20
capture request header Referer len 60
default_backend servers
frontend healthcheck
bind :1099
mode http
option httpclose
option forwardfor
default_backend servers
backend servers
balance roundrobin
server websrv1 192.168.10.11:80 check maxconn 2000
server websrv2 192.168.10.12:80 check maxconn 2000
負載均衡MySQL服務的配置示例
#---------------------------------------------------------------------
# Global settings
#---------------------------------------------------------------------
global
# to have these messages end up in /var/log/haproxy.log you will
# need to:
#
# 1) configure syslog to accept network log events. This is done
# by adding the '-r' option to the SYSLOGD_OPTIONS in
# /etc/sysconfig/syslog
#
# 2) configure local2 events to go to the /var/log/haproxy.log
# file. A line like the following can be added to
# /etc/sysconfig/syslog
#
# local2.* /var/log/haproxy.log
#
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
defaults
mode tcp
log global
option httplog
option dontlognull
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 600
listen stats
mode http
bind 0.0.0.0:1080
stats enable
stats hide-version
stats uri /haproxyadmin?stats
stats realm Haproxy\ Statistics
stats auth admin:admin
stats admin if TRUE
frontend mysql
bind *:3306
mode tcp
log global
default_backend mysqlservers
backend mysqlservers
balance leastconn
server dbsrv1 192.168.10.11:3306 check port 3306 intval 2 rise 1 fall 2 maxconn 300
server dbsrv2 192.168.10.12:3306 check port 3306 intval 2 rise 1 fall 2 maxconn 300
ACL
Haproxy的ACL用于實現基于請求報文的首部、響應報文的內容或其它的環境狀態信息做出轉發決策,這大大增加了其配置彈性,其配置法則通常分為兩步,首先先定義ACL,即定義一個測試條件,而后在條件得到滿足時執行特定的動作,如阻止請求或轉發至某特定的后端
-
定義ACL的語法格式
-
acl <aclname> <criterion> [flags] [operator] <value> ....
-
<aclname>
: ACL名稱,區分字符大小寫,且其只能包含大小寫字母、數字、-(連接線)、_(下劃線)、.(點號)和:(冒號);haproxy中,acl可以重名,這可以把多個測試條件定義為一個共同的acl -
<criterion>
: 測試標準,即對什么信息發起測試;測試方式可以由[flags]指定的標志進行調整;而有些測試標準也可以需要為其在<value>之前指定一個操作符[operator] -
[flags]
: 目前haproxy的acl支持的標志位有3個-
-i
: 不區分<value>中模式字符的大小寫 -
-f
: 從指定的文件中加載模式 -
--
: 標志符的強制結束符,在模式中的字符串像標記符時使用
-
-
<value>
: acl測試條件支持的值有以下四類- 整數或整數范圍:如1024:65535表示從1024至65535;僅支持使用正整數(如果出現類似小數的標識,其為通常為版本測試),且支持使用的操作符有5個,分別為eq、ge、gt、le和lt;
- 字符串:支持使用“-i”以忽略字符大小寫,支持使用“\”進行轉義;如果在模式首部出現了-i,可以在其之前使用“--”標志位;
- 正則表達式:其機制類同字符串匹配;
- IP地址及網絡地址
-
-
同一個acl中可以指定多個測試條件,這些測試條件需要由邏輯操作符指定其關系。條件間的組合測試關系有三種:“與”(默認即為與操作)、“或”(使用“||”操作符)以及“非”(使用“!”操作符)
-
常用的測試標準(criteria)
-
be_sess_rate <integer>
用于測試指定的backend上會話創建的速率(即每秒創建的會話數)是否滿足指定的條件;常用于在指定backend上的會話速率過高時將用戶請求轉發至另外的backend,或用于阻止攻擊行為。例如:
backend dynamic mode http acl being_scanned be_sess_rate gt 50 redirect location /error_pages/denied.html if being_scanned
-
fe_sess_rate <integer>
用于測試指定的frontend(或當前frontend)上的會話創建速率是否滿足指定的條件;常用于為frontend指定一個合理的會話創建速率的上限以防止服務被濫用。例如下面的例子限定入站郵件速率不能大于50封/秒,所有在此指定范圍之外的請求都將被延時50毫秒
frontend mail bind :25 mode tcp maxconn 500 acl too_fast fe_sess_rate ge 50 tcp-request inspect-delay 500ms tcp-request content accept if ! too_fast tcp-request content accept if WAIT_END
-
hdr(header) <string>
用于測試請求報文中的所有首部或指定首部是否滿足指定的條件;指定首部時,其名稱不區分大小寫,且在括號“()”中不能有任何多余的空白字符。測試服務器端的響應報文時可以使用shdr()。例如下面的例子用于測試首部Connection的值是否為close
hdr(Connection) -i close
-
method <string>
測試HTTP請求報文中使用的方法
-
path_beg <string>
用于測試請求的URL是否以<string>指定的模式開頭。下面的例子用于測試URL是否以/static、/images、/javascript或/stylesheets頭
acl url_static path_beg -i /static /images /javascript /stylesheets
-
path_end <string>
用于測試請求的URL是否以<string>指定的模式結尾。例如,下面的例子用戶測試URL是否以jpg、gif、png、css或js結尾
acl url_static path_end -i .jpg .gif .png .css .js
-
hdr_beg <string>
用于測試請求報文的指定首部的開頭部分是否符合<string>指定的模式。例如,下面的例子用記測試請求是否為提供靜態內容的主機img、video、download或ftp
acl host_static hdr_beg(host) -i img. video. download. ftp.
-
hdr_end <string>
用于測試請求報文的指定首部的結尾部分是否符合<string>指定的模式
url_beg
url_end
path_reg
url_reg
-
總結
balance的算法:
- roundrobin
- static-rr
- leastconn
- source
- uri
- url_param
- hdr(HEADER)
acl creterion的方法
- path
- path_beg
- path_end
- src
- src_port
- dst
- dst_port
- url_beg
- url_end
- url_reg
- path_reg
- hdr(Header)
動靜分離示例:
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
# turn on stats unix socket
stats socket /var/lib/haproxy/stats
defaults
mode http
log global
option httplog
option dontlognull
option http-server-close
option forwardfor except 127.0.0.0/8
option redispatch
retries 3
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 30000
listen stats
mode http
bind 0.0.0.0:1080
stats enable
stats hide-version
stats uri /haproxyadmin?stats
stats realm Haproxy\ Statistics
stats auth admin:admin
stats admin if TRUE
frontend http-in
bind *:80
mode http
log global
option httpclose
option logasap
option dontlognull
capture request header Host len 20
capture request header Referer len 60
acl url_static path_beg -i /static /images /javascript /stylesheets
acl url_static path_end -i .jpg .jpeg .gif .png .css .js
use_backend static_servers if url_static
default_backend dynamic_servers
backend static_servers
balance roundrobin
server imgsrv1 172.16.200.7:80 check maxconn 6000
server imgsrv2 172.16.200.8:80 check maxconn 6000
backend dynamic_servers
cookie srv insert nocache
balance roundrobin
server websrv1 172.16.200.7:80 check maxconn 1000 cookie websrv1
server websrv2 172.16.200.8:80 check maxconn 1000 cookie websrv2
server websrv3 172.16.200.9:80 check maxconn 1000 cookie websrv3