參考文檔:html
http://cbonte.github.io/haproxy-dconv/1.5/configuration.htmljava
軟件負載均衡通常經過兩種方式來實現:基於操做系統的軟負載實現和基於第三方應用的軟負載實現 。LVS 就是基於 Linux 操做系統實現的一種軟負載,HAProxy 就是開源的而且基於第三應用實現的軟負載。HAProxy 相比 LVS 的使用要簡單不少,功能方面也很豐富。當前,HAProxy 支持兩種主要的代理模式:"tcp"也即 4 層 (大多用於郵件服務器、 內部協議通訊服務器等) , 和 7 層 (HTTP) 。 在 4 層模式下, HAproxy僅在客戶端和服務器之間轉發雙向流量。7 層模式下,HAProxy 會分析協議,而且能經過容許、拒絕、交換 、增長、 修改或者刪除請求(request)或者回應(response)裏指定內容來控制協議,這種操做要基於特定規則。詳情能夠在 HAProxy 官方網站(http://haproxy.1wt.eu)能夠下載配置說明文檔(configuration.txt)和架構文件(architecture.txt)做爲參考。ios
注意:Haproxy採用的是事件驅動機制,所以要獲取更好的性能,應該在Linux2.6或打了epoll()補丁的Linux2.4上運行haproxy1.2.5以上的版本。haproxy1.1默認使用的polling系統爲select(),其處理的文件數達到數千以後性能便會急劇降低。1.2和1.3版本默認的是poll(),在某些操做系統上依舊有問題,可是聽說在Solaris上表現不俗。nginx
這裏使用CentOS7 ,直接使用base源中的1.5.14進行安裝git
yum -y install haproxy
性能特性:github
(1)單進程、事件驅動模型顯著下降了上下文切換的開銷;web
(2)事件檢查器(event checker)容許其在高併發鏈接中對任何鏈接的任何事件實現即時探測;正則表達式
(3)在任何可用的狀況下,單緩衝(single buffering)機制能以不復制任何數據的方式完成讀寫操做,這會節約大量的CPU時鐘週期以及內存帶寬;redis
(4)MRU(與LRU對應,最近最多使用...)內存分配器在固定大小的內存池中能夠實現即時內存分配,這可以顯著減小建立一個會話的時長;算法
(5)樹型存儲:側重於使用做者多年前開發的彈性二叉樹,實現了以O(log(N))的低開銷來保持計時器命令、保持運行隊列命令以及管理輪詢以及最少鏈接隊列;
(6)優化的HTTP首部分析:優化的首部分析功能避免了在HTTP首部分析過程當中重讀任何內存區域;
(7)精心地下降了昂貴的系統調用,大部分工做都在用戶空間完成,如時間讀取、緩衝聚合以及文件描述符的啓用和禁用;
評估一個負載均衡器的性能每每從如下角度進行衡量
會話率:每秒能建立多少個會話
會話併發能力:能同時維持多少個會話
數據處理速度:會話處理的速度
而haproxy子在這三方面都有不俗的表現...nginx也不錯.能夠說Nginx和haproxy各有優勢,一半一半。
haproxy的官網和nginx同樣,很是的詳細。
咱們來使用haproxy簡單的配置一個負載均衡,首先看官方的配置說明,很是簡單:
HAProxy's configuration process involves 3 major sources of parameters :
- the arguments from the command-line, which always take precedence(配置行優先)
- the "global" section, which sets process-wide parameters (global設置的是進程級別的通用配置)
- the proxies sections which can take form of "defaults", "listen", (代理配置塊能夠是defaults, listen, frontend, backend)
"frontend" and "backend".
The configuration file syntax consists in lines beginning with a keyword
referenced in this manual, optionally followed by one or several parameters
delimited by spaces. If spaces have to be entered in strings, then they must be
preceded by a backslash ('\') to be escaped. Backslashes also have to be
escaped by doubling them.(空格必須使用\轉義)
用spring-boot簡單配置了2個java web項目,一個端口8081,一個端口8082
在配置文件最後一行加入如下內容:
listen tomcat *:8080 balance roundrobin server srv1 192.168.1.103:8081 check server srv2 192.168.1.103:8082 check listen stats *:9091 stats enable stats uri /admin?stats stats realm HAProxy\ Statistics stats auth admin:admin
簡要解釋:
首先listen表示是一個代理,名字是tomcat,監聽在8080端口上
採用的負載均衡算法是輪詢roundrobin
有2個後端服務器,一個是8081,一個是8082,check表示都會自動作健康檢查
注意到還有一個listen stats 這個表示是開啓web監控頁面,監控在9091端口上,訪問url爲admin?stats
設置了訪問stats頁面的用戶名密碼都是admin
訪問http://192.168.1.211:9091/admin?stats便可看到效果,而且已經實現了負載均衡。
####################全局配置信息######################## #######參數是進程級的,一般和操做系統(OS)相關######### global maxconn 20480 #單個haproxy進程的默認最大鏈接數 log 127.0.0.1 local3 #[err warning info debug] chroot /var/haproxy #chroot運行的路徑 uid 99 #所屬運行的用戶uid gid 99 #所屬運行的用戶組 daemon #之後臺形式運行haproxy nbproc 1 #進程數量(能夠設置多個進程提升性能) pidfile /var/run/haproxy.pid #haproxy的pid存放路徑,啓動進程的用戶必須有權限訪問此文件 ulimit-n 65535 #ulimit的數量限制
能夠經過配置syslog來獲取haproxy的日誌信息,這裏配置的是local3,在syslog中再配置local3便可
還有:
maxpipes: haproxy使用pipe機制實現內核級別的tcp報文重組,maxpipes每進程可使用的最大pipe數量,默認是maxconn/4
noepoll/nokqueue/nopoll/mosepoll... : 禁用某種事件機制
nosplice: 禁用內核級tcp報文的重組功能
spread-checks <0...50> : 分散健康監測0%-50%
還有不少的參數能夠調整,詳見haproxy的官方文檔,可是這些參數Haproxy官方說明不建議用戶手動調整。
haproxy關於代理的配置用法很是的多,haproxy官方給了個矩陣,這裏描述一些經常使用的:
http://cbonte.github.io/haproxy-dconv/1.5/configuration.html#4-bind
bind [<address>]:<port_range> [, ...] [param*]
bind /<path> [, ...] [param*]
指明監聽的套接字,如下是一些example
listen http_proxy bind :80,:443 bind 10.0.0.1:10080,10.0.0.1:10443 bind /var/run/ssl-frontend.sock user root mode 600 accept-proxy listen http_https_proxy bind :80 bind :443 ssl crt /etc/haproxy/site.pem listen http_https_proxy_explicit bind ipv6@:80 bind ipv4@public_ssl:443 ssl crt /etc/haproxy/site.pem bind unix@ssl-frontend.sock user root mode 600 accept-proxy listen external_bind_app1 bind fd@${FD_APP1}
http://cbonte.github.io/haproxy-dconv/1.5/configuration.html#4-balance
roundrobin: 動態算法,動態的加權輪詢,支持慢啓動以及運行時調整權重,後端有4095的限制
static-rr: 靜態算法,靜態的加權輪詢,後端主機無限制
least-conn: 動態的最小鏈接,短鏈接(好比短於5s的鏈接)更適合roundrobin,由於沒有必要去計算鏈接數... 推薦使用在長時間的會話場景中,好比LDAP, MySQL等協議;
first: The first server with available connection slots receives the connection. 根據服務器在列表中的位置,自上而下進行調度;前面服務器鏈接數達到上限將調度至下一個服務器
source: 源地址hash的算法
這裏hash算法也支持map-based和consistent
http://cbonte.github.io/haproxy-dconv/1.5/configuration.html#hash-type
還能夠指定hash函數
uri: 對URI的左半部分或者整個uri作hash計算,將對同一個uri的請求發往同一個uri server,特別適合於緩存服務器
This algorithm hashes either the left part of the URI (before the question mark) or the whole URI (if the "whole" parameter is present) and divides the hash value by the total weight of the running servers.
url_param: 跟上面相似,可是隻計算uri中的params,適合登陸類的網站
The URL parameter specified in argument will be looked up in the query string of each HTTP GET request.
hdr(<name>): 經過<name>指定的http請求首部作hash,若是沒有,則作輪詢。
hdr(Host):基於請求的Host進行調度
hdr(Cookie)
rdp-cookie: 遠程桌面協議,略
http://cbonte.github.io/haproxy-dconv/1.5/configuration.html#4-server
server <name> <address>[:[port]] [param*]
server first 10.1.1.1:1080 cookie first check inter 1000 server second 10.1.1.2:1080 cookie second check inter 1000 server transp ipv4@ server backup ${SRV_BACKUP}:1080 backup server www1_dc1 ${LAN_DC1}.101:80 server www1_dc2 ${LAN_DC2}.101:80
支持的參數很是多:http://cbonte.github.io/haproxy-dconv/1.5/configuration.html#5.2
關於check:
關於check,若是是http mode,還支持使用option-httpcheck,很是簡單
http://cbonte.github.io/haproxy-dconv/1.5/configuration.html#4-option%20httpchk
option httpchk
option httpchk <uri>
option httpchk <method> <uri>
option httpchk <method> <uri> <version>例如:option httpchk GET /index.html #心跳檢測的文件
關於cookie:
Enable cookied-based persistence in a backend.
<name>: is the name of the cookie which will be monitored, modified or inserted in order to bring persistence.
這個cookie會以Set-Cookie的響應頭髮送給客戶端,以後這個客戶端發送的全部請求都會攜帶這個Cookie信息。所以須要注意不要和應用中其餘的Cookie名稱發生衝突。發送cookie的方式:
rewrite: This keyword indicated that the cookie will be provided by the server and that haproxy will have to modify its value to set the server's identifier in it.
This mode is handy(方便的) when the mangement of complex combinations of "Set-Cookie" and "Cache-control" headers is left to the application. The application can then decide whether or not it is appropriate to emit a persistence cookie. Since all responses should be monitored, this mode doesn't work in HTTP tuunel mode. Unless the application behaviour is very complex and/or broken, it is advised not to start with this mode for new deployments. This keyword is incompatible with "insert" and "prefix".insert: This keyword indicates that the persistence cookie will have to be inserted by haproxy in server response if the client did not already have a cookie that would have permitted it to access this server. When used without the "preserve" option, if the server emits a cookie with the same name, it will be remove before processing. For this reason, this mode can be used to upgrade existing configurations running in the "rewrite" mode . The cookie will be only be a session cookie and will not be stored on the client' disk. By default, unless the "indirect" option is added, the server will see the cookie emitted by the client. Due to caching effects, it is generally wise to add "nocache" or "postonly" keywords.
prefix
indirect: when this option is specified, no cookie will be emmited to a client which already have valid one for the server which processed the request. If the server sets such a cookie itself, it will be "removed", unless the "preserve" option is also set.
{tcp | http | health}
option forwardfor [ except <network> ] [ header <name> ] [ if-none ]
Enable insertion of the X-Forwarded-For header to requests sent to servers, 跟Nignx中設置源Ip同樣
# Public HTTP address also used by stunnel on the same machine frontend www mode http option forwardfor except 127.0.0.1 # stunnel already adds the header # Those servers want the IP Address in X-Client backend www mode http option forwardfor header X-Client
acl擁有很是多的內容:http://cbonte.github.io/haproxy-dconv/1.5/configuration.html#7
ACL names(名稱約束): ACL names must be formed from upper and lower case letters, digits, '-' (dash),'_' (underscore) , '.' (dot) and ':' (colon). ACL names are case-sensitive, which means that "my_acl" and "My_Acl" are two different ACLs.
只容許大小寫字母,數字,'-','_','.',':' 並且是大小寫敏感的
基本格式爲: acl <aclname> <criterion> [flags] [operator] <value> ...
criterion(標準):
The criterion generally is the name of a sample fetch method, or one of its ACL specific(特殊的) declinations(傾向). The default test method is implied by the output type of this sample fetch method. The ACL declinations can describe alternate matching methods of a same sample fetch method. The sample fetch methods are the only ones supporting a conversion.
Sample fetch methods return data which can be of the following types :
flags: 是一些特殊的ACL標誌位,其含義以下所示:
-i : ignore case during matching of all subsequent patterns.
-f : load patterns from a file.
-m : use a specific pattern matching method
-n : forbid the DNS resolutions
-M : load the file pointed by -f like a map file.
-u : force the unique id of the ACL
-- : force end of flags. Useful when a string looks like one of the flags.
最經常使用的是-i表示無視大小寫。
其中criterion用法很是的多,分爲Layer4,Layer5,Layer6,Layer7.
好比Layer7的 req.cook, req.hdr..
好比經常使用的path:This extracts the request's URL path, which starts at the first slash(斜線) and ends before the question mark(問號) (without the host part),其中path又有多種用法:
好比url: This extracts the request's URL as presented in the request,也有相似的用法
還有url_param等等
訪問控制:
block { if | unless } <condition>
http-request 操控http request
acl nagios src 192.168.129.3
acl local_net src 192.168.0.0/16
acl auth_ok http_auth(L1)
http-request allow if nagios
http-request allow if local_net auth_ok
http-request auth realm Gimme if local_net auth_ok
http-request deny
http-response 操縱http response
acl key_acl res.hdr(X-Acl-Key) -m found
acl myhost hdr(Host) -f myhost.lst
http-response add-acl(myhost.lst) %[res.hdr(X-Acl-Key)] if key_acl
http-response del-acl(myhost.lst) %[res.hdr(X-Acl-Key)] if key_acl
http://rickyhui.blog.51cto.com/10570875/1680676
####################全局配置信息######################## #######參數是進程級的,一般和操做系統(OS)相關######### global maxconn 20480 #默認最大鏈接數 log 127.0.0.1 local3 #[err warning info debug] chroot /var/haproxy #chroot運行的路徑 uid 99 #所屬運行的用戶uid gid 99 #所屬運行的用戶組 daemon #之後臺形式運行haproxy nbproc 1 #進程數量(能夠設置多個進程提升性能) pidfile /var/run/haproxy.pid #haproxy的pid存放路徑,啓動進程的用戶必須有權限訪問此文件 ulimit-n 65535 #ulimit的數量限制 #####################默認的全局設置###################### ##這些參數能夠被利用配置到frontend,backend,listen組件## defaults log global mode http #所處理的類別 (#7層 http;4層tcp ) maxconn 20480 #最大鏈接數 option httplog #日誌類別http日誌格式 option httpclose #每次請求完畢後主動關閉http通道,即顯示不支持客戶端的長鏈接 option dontlognull #不記錄健康檢查的日誌信息 option forwardfor #若是後端服務器須要得到客戶端真實ip須要配置的參數,能夠從Http Header中得到客戶端ip option redispatch #serverId對應的服務器掛掉後,強制定向到其餘健康的服務器 option abortonclose #當服務器負載很高的時候,自動結束掉當前隊列處理比較久的鏈接 stats refresh 30 #統計頁面刷新間隔 retries 3 #3次鏈接失敗就認爲服務不可用,也能夠經過後面設置 balance roundrobin #默認的負載均衡的方式,輪詢方式 #balance source #默認的負載均衡的方式,相似nginx的ip_hash #balance leastconn #默認的負載均衡的方式,最小鏈接 contimeout 5000 #鏈接超時 clitimeout 50000 #客戶端超時 srvtimeout 50000 #服務器超時 timeout check 2000 #心跳檢測超時 ####################監控頁面的設置####################### listen admin_status #Frontend和Backend的組合體,監控組的名稱,按需自定義名稱 bind 0.0.0.0:65532 #監聽端口 mode http #http的7層模式 log 127.0.0.1 local3 err #錯誤日誌記錄 stats refresh 5s #每隔5秒自動刷新監控頁面 stats uri /admin?stats #監控頁面的url stats realm itnihao\ itnihao #監控頁面的提示信息 stats auth admin:admin #監控頁面的用戶和密碼admin,能夠設置多個用戶名 stats auth admin1:admin1 #監控頁面的用戶和密碼admin1 stats hide-version #隱藏統計頁面上的HAproxy版本信息 stats admin if TRUE #手工啓用/禁用,後端服務器(haproxy-1.4.9之後版本) errorfile 403 /etc/haproxy/errorfiles/403.http errorfile 500 /etc/haproxy/errorfiles/500.http errorfile 502 /etc/haproxy/errorfiles/502.http errorfile 503 /etc/haproxy/errorfiles/503.http errorfile 504 /etc/haproxy/errorfiles/504.http #################HAProxy的日誌記錄內容設置################### capture request header Host len 40 capture request header Content-Length len 10 capture request header Referer len 200 capture response header Server len 40 capture response header Content-Length len 10 capture response header Cache-Control len 8 #######################網站監測listen配置##################### ###########此用法主要是監控haproxy後端服務器的監控狀態############ listen site_status bind 0.0.0.0:1081 #監聽端口 mode http #http的7層模式 log 127.0.0.1 local3 err #[err warning info debug] monitor-uri /site_status #網站健康檢測URL,用來檢測HAProxy管理的網站是否能夠用,正常返回200,不正常返回503 acl site_dead nbsrv(server_web) lt 2 #定義網站down時的策略當掛在負載均衡上的指定backend的中有效機器數小於1臺時返回true acl site_dead nbsrv(server_blog) lt 2 acl site_dead nbsrv(server_bbs) lt 2 monitor fail if site_dead #當知足策略的時候返回503,網上文檔說的是500,實際測試爲503 monitor-net 192.168.16.2/32 #來自192.168.16.2的日誌信息不會被記錄和轉發 monitor-net 192.168.16.3/32 ########frontend配置############ #####注意,frontend配置裏面能夠定義多個acl進行匹配操做######## frontend http_80_in bind 0.0.0.0:80 #監聽端口,即haproxy提供web服務的端口,和lvs的vip端口相似 mode http #http的7層模式 log global #應用全局的日誌配置 option httplog #啓用http的log option httpclose #每次請求完畢後主動關閉http通道,HA-Proxy不支持keep-alive模式 option forwardfor #若是後端服務器須要得到客戶端的真實IP須要配置次參數,將能夠從Http Header中得到客戶端IP ########acl策略配置############# acl itnihao_web hdr_reg(host) -i ^(www.itnihao.cn|ww1.itnihao.cn)$ #若是請求的域名知足正則表達式中的2個域名返回true -i是忽略大小寫 acl itnihao_blog hdr_dom(host) -i blog.itnihao.cn #若是請求的域名知足www.itnihao.cn返回true -i是忽略大小寫 #acl itnihao hdr(host) -i itnihao.cn #若是請求的域名知足itnihao.cn返回true -i是忽略大小寫 #acl file_req url_sub -i killall= #在請求url中包含killall=,則此控制策略返回true,不然爲false #acl dir_req url_dir -i allow #在請求url中存在allow做爲部分地址路徑,則此控制策略返回true,不然返回false #acl missing_cl hdr_cnt(Content-length) eq 0 #當請求的header中Content-length等於0時返回true ########acl策略匹配相應############# #block if missing_cl #當請求中header中Content-length等於0阻止請求返回403 #block if !file_req || dir_req #block表示阻止請求,返回403錯誤,當前表示若是不知足策略file_req,或者知足策略dir_req,則阻止請求 use_backend server_web if itnihao_web #當知足itnihao_web的策略時使用server_web的backend use_backend server_blog if itnihao_blog #當知足itnihao_blog的策略時使用server_blog的backend #redirect prefix http://blog.itniaho.cn code 301 if itnihao #當訪問itnihao.cn的時候,用http的301挑轉到http://192.168.16.3 default_backend server_bbs #以上都不知足的時候使用默認server_bbs的backend ##########backend的設置############## #下面我將設置三組服務器 server_web,server_blog,server_bbs ###########################backend server_web############################# backend server_web mode http #http的7層模式 balance roundrobin #負載均衡的方式,roundrobin平均方式 cookie SERVERID #容許插入serverid到cookie中,serverid後面能夠定義 option httpchk GET /index.html #心跳檢測的文件 server web1 192.168.16.2:80 cookie web1 check inter 1500 rise 3 fall 3 weight 1 #服務器定義,cookie 1表示serverid爲web1,check inter 1500是檢測心跳頻率rise 3是3次正確認爲服務器可用, #fall 3是3次失敗認爲服務器不可用,weight表明權重 server web2 192.168.16.3:80 cookie web2 check inter 1500 rise 3 fall 3 weight 2 #服務器定義,cookie 1表示serverid爲web2,check inter 1500是檢測心跳頻率rise 3是3次正確認爲服務器可用, #fall 3是3次失敗認爲服務器不可用,weight表明權重 ###################################backend server_blog############################################### backend server_blog mode http #http的7層模式 balance roundrobin #負載均衡的方式,roundrobin平均方式 cookie SERVERID #容許插入serverid到cookie中,serverid後面能夠定義 option httpchk GET /index.html #心跳檢測的文件 server blog1 192.168.16.2:80 cookie blog1 check inter 1500 rise 3 fall 3 weight 1 #服務器定義,cookie 1表示serverid爲web1,check inter 1500是檢測心跳頻率rise 3是3次正確認爲服務器可用,fall 3是3次失敗認爲服務器不可用,weight表明權重 server blog2 192.168.16.3:80 cookie blog2 check inter 1500 rise 3 fall 3 weight 2 #服務器定義,cookie 1表示serverid爲web2,check inter 1500是檢測心跳頻率rise 3是3次正確認爲服務器可用,fall 3是3次失敗認爲服務器不可用,weight表明權重 ###################################backend server_bbs############################################### backend server_bbs mode http #http的7層模式 balance roundrobin #負載均衡的方式,roundrobin平均方式 cookie SERVERID #容許插入serverid到cookie中,serverid後面能夠定義 option httpchk GET /index.html #心跳檢測的文件 server bbs1 192.168.16.2:80 cookie bbs1 check inter 1500 rise 3 fall 3 weight 1 #服務器定義,cookie 1表示serverid爲web1,check inter 1500是檢測心跳頻率rise 3是3次正確認爲服務器可用,fall 3是3次失敗認爲服務器不可用,weight表明權重 server bbs2 192.168.16.3:80 cookie bbs2 check inter 1500 rise 3 fall 3 weight 2 #服務器定義,cookie 1表示serverid爲web2,check inter 1500是檢測心跳頻率rise 3是3次正確認爲服務器可用,fall 3是3次失敗認爲服務器不可用,weight表明權重