Linux之HAProxy

互聯網架構基礎知識

一、網站常見架構

  • 負載層
  • 頁面緩存層
  • 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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,143評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,553評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,620評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,416評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,940評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,170評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,709評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,597評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,029評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,407評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,663評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,403評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,746評論 2 370

推薦閱讀更多精彩內容

  • HAProxy簡介HAProxy配置ACL配置TCP轉發SSL轉發 一、HAProxy簡介: (一)HAProxy...
    哈嘍別樣閱讀 1,557評論 0 0
  • Haproxy是既可以工作在7層也能工作在4層的反代工具.Haproxy的功能: 路由HTTP請求到后端服務器,基...
    uangianlap閱讀 1,565評論 0 1
  • 目錄: HAProxy是什么 HAProxy的核心能力和關鍵特性 HAProxy的安裝和運行 使用HAProxy搭...
    kelgon閱讀 79,951評論 9 159
  • 參考文檔: 1.haproxy:http://www.haproxy.org/ 本文涉及haproxy的安裝,并做...
    Netonline閱讀 2,436評論 1 51
  • 一.HAProxy介紹 HAProxy: 是法國人Willy Tarreau開發的一個開源軟件,是 一款應對客戶端...
    楠人幫閱讀 1,126評論 0 2