HAProxy是一個開源的,高性能的,高可用的,可以支持TCP和HTTP的負載均衡代理服務軟件。
* 支持雙機熱備
* 良好的服務器節點健康檢查
* 故障節點服務器自動剔除
* 節點服務器恢復后自動加入負載集群的功能
* 能夠補充Nginx的一些缺點比如Session的保持,Cookie的引導等工作
* HAProxy是支持虛擬主機的,通過frontend指令來實現
* HAProxy可以對Mysql讀進行負載均衡,對后端的MySQL節點進行檢測和負載均衡,不過在后端的MySQL slaves數量超過10臺時性能不如LVS,所以我向大家推薦LVS+Keepalived。
* 能對請求的url和header中的信息做匹配
* HAProxy的負載均衡算法現在也越來越多了,具體有如下8種:
①roundrobin,表示簡單的輪詢,這個不多說,這個是負載均衡基本都具備的;
②static-rr,表示根據權重,建議關注;
③leastconn,表示最少連接者先處理,建議關注;
④source,表示根據請求源IP,這個跟Nginx的IP_hash機制類似,我們用其作為解決session問題的一種方法
⑤ri,表示根據請求的URI;
⑥rl_param,表示根據請求的URl參數'balance url_param' requires an URL parameter name;
⑦hdr(name),表示根據HTTP請求頭來鎖定每一次HTTP請求;
⑧rdp-cookie(name),表示根據據cookie(name)來鎖定并哈希每一次TCP請求。
## HAProxy簡介
HAProxy特別適用于高負載,訪問量大,但又需要回話保持的七層應用的代理業務.HAProxy幾乎不需要任何優化,就可以支持數以萬計的并發鏈接.Haproxy的代理模式,使得所有的應用服務器不會被暴露到公網上。
從1.3版本開始,Haproxy引入了frontend和backend的概念,frontend(acl規則匹配)可以讓運維管理人員根局任意的HTTP請求頭做規則匹配,然后把請求定向到相關的backend。
HAproxy支持兩種主要的代理模式:
* 基于4層的tcp應用代理(例如:郵件服務,內部協議通信服務器,mysql,https服務等)
* 基于7層的http代理。在4層tcp代理模式下,HAproxy盡在客戶端和服務器之間進行流量轉發。但是在7層http代理模式下,HAProxy會分析應用層協議,并且能通過允許,拒絕,交換,增加,修改或者刪除請求(request)或者響應(response)里指定內容控制協議.
## 拓撲結構圖
### 四層代理

### 七層代理

## 安裝
> 本安裝腳本基于操作系統Ubuntu14.04 Server
安裝的shell腳本保存于https://github.com/hanxt/haproxy_setup/setup.sh, 如下:
```
#!/bin/bash
ROOTPATH=`pwd`
export LANG=en
#wget http://www.haproxy.org/download/1.6/src/haproxy-1.6.7.tar.gz;
tar zxvf ./haproxy-1.6.7.tar.gz
cd $ROOTPATH/haproxy-1.6.7
make TARGET=linux2628 ARCH=x86_64
sudo make PREFIX=/usr/local/haproxy-1.6.7 install
sudo ln -s /usr/local/haproxy-1.6.7 /usr/local/haproxy;
cd /usr/local/haproxy;
sudo mkdir -p bin conf logs var/run var/chroot
sudo useradd haproxy -s /sbin/nologin;
sudo chown -R haproxy:haproxy /usr/local/haproxy/var/run/;
sudo cp ./haproxy.cfg /usr/local/haproxy/conf;
```
> 查看README,可以獲得關于更多的編譯安裝的幫助信息.
配置haproxy的日志環境,不同的操作系統配置方法不一致。
```
# vim /etc/syslog.conf
添加:
local0.* /usr/local/logs/haproxy.log
local3.* /usr/local/logs/haproxy_err.log
#vim /etc/sysconfig/syslog
修改:
SYSLOGD_OPTIONS="-r -m 0"
service syslog restart
注: -r enables logging from remote machines
```
#### 內核參數修改
> 注意:/etc/sysctl.conf為ubuntu系統內核參數修改文件,Centos待確認!
net.ipv4.ip_forward = 1 #基于NAT模式的負載均衡器都需要打開系統轉發的功能
```
#使內核參數修改生效
sysctl -p
```
其他的常用參數優化:

## haproxy.conf配置文件說明
HAProxy配置文件總體分為五個部分:
* global:全局配置參數段,主要用來控制HAProxy啟動前的進程及系統相關設置.
* defaults:配置一些默認參數,如果frontend,backend,listen等端未設置就使用defaults的配置.
* listen:frontend和backend的組合體
* frontend:用來匹配接收客戶所請求的域名,url等,并針對不同的匹配,做不同的請求處理.
* backend:定義后端服務集群,以及后端服務器的權重,隊列,連接數等選項。
### 一個http負載均衡代理的配置模板
```
global # 全局參數的設置
log 127.0.0.1 local0 info
# log語法:log [max_level_1]
# 全局的日志配置,使用log關鍵字,指定使用127.0.0.1上的syslog服務中的local0日志設備,
記錄日志等級為info的日志
user haproxy
group haproxy
# 設置運行haproxy的用戶和組,也可使用uid,gid關鍵字替代之
daemon
# 以守護進程的方式運行
nbproc 16
# 設置haproxy啟動時的進程數,根據官方文檔的解釋,我將其理解為:該值的設置應該和服務
#器的CPU核心數一致,即常見的2顆8核心CPU的服務器,即共有16核心,則可以將其值設置為:
#<=16 ,創建多個進程數,可以減少每個進程的任務隊列,但是過多的進程數也可能會導致進程
#的崩潰。這里我設置為16
maxconn 4096
# 定義每個haproxy進程的最大連接數 ,由于每個連接包括一個客戶端和一個服務器端,所以單
#個進程的TCP會話最大數目將是該值的兩倍。
#ulimit -n 65536
# 設置最大打開的文件描述符數,在1.4的官方文檔中提示,該值會自動計算,所以不建議進行
#設置
pidfile /var/run/haproxy.pid
# 定義haproxy的pid
defaults # 默認部分的定義
mode http
# mode語法:mode {http|tcp|health} 。http是七層模式,tcp是四層模式,health是健康檢測
#,返回OK
log 127.0.0.1 local3 err
# 使用127.0.0.1上的syslog服務的local3設備記錄錯誤信息
retries 3
# 定義連接后端服務器的失敗重連次數,連接失敗次數超過此值后將會將對應后端服務器標記為
#不可用
option httplog
# 啟用日志記錄HTTP請求,默認haproxy日志記錄是不記錄HTTP請求的,只記錄“時間[Jan 5 13
#:23:46] 日志服務器[127.0.0.1] 實例名已經pid[haproxy[25218]] 信息[Proxy http_80_in s
#topped.]”,日志格式很簡單。
option redispatch
# 當使用了cookie時,haproxy將會將其請求的后端服務器的serverID插入到cookie中,以保證
#會話的SESSION持久性;而此時,如果后端的服務器宕掉了,但是客戶端的cookie是不會刷新的
#,如果設置此參數,將會將客戶的請求強制定向到另外一個后端server上,以保證服務的正常
option abortonclose
# 當服務器負載很高的時候,自動結束掉當前隊列處理比較久的鏈接
option dontlognull
# 啟用該項,日志中將不會記錄空連接。所謂空連接就是在上游的負載均衡器或者監控系統為了
#探測該服務是否存活可用時,需要定期的連接或者獲取某一固定的組件或頁面,或者探測掃描
#端口是否在監聽或開放等動作被稱為空連接;官方文檔中標注,如果該服務上游沒有其他的負
#載均衡器的話,建議不要使用該參數,因為互聯網上的惡意掃描或其他動作就不會被記錄下來
option httpclose
# 這個參數我是這樣理解的:使用該參數,每處理完一個request時,haproxy都會去檢查http頭
#中的Connection的值,如果該值不是close,haproxy將會將其***,如果該值為空將會添加為:
#Connection: close。使每個客戶端和服務器端在完成一次傳輸后都會主動關閉TCP連接。與該
#參數類似的另外一個參數是“option forceclose”,該參數的作用是強制關閉對外的服務通道
#,因為有的服務器端收到Connection: close時,也不會自動關閉TCP連接,如果客戶端也不關
#閉,連接就會一直處于打開,直到超時。
contimeout 5000
# 設置成功連接到一臺服務器的最長等待時間,默認單位是毫秒,新版本的haproxy使用timeout
#connect替代,該參數向后兼容
clitimeout 3000
# 設置連接客戶端發送數據時的成功連接最長等待時間,默認單位是毫秒,新版本haproxy使用
#timeout client替代。該參數向后兼容
srvtimeout 3000
# 設置服務器端回應客戶度數據發送的最長等待時間,默認單位是毫秒,新版本haproxy使用
#timeout server替代。該參數向后兼容
listen status
# 定義一個名為status的部分,可以在listen指令指定的區域中定義匹配規則和后端服務器ip,
#相當于需要在其中配置frontend,backend的功能。一般做tcp轉發比較合適,不用太多的規則
#匹配。
bind 0.0.0.0:1080
# 定義監聽的套接字
mode http
# 定義為HTTP模式
log global
# 繼承global中log的定義
stats refresh 30s
# stats是haproxy的一個統計頁面的套接字,該參數設置統計頁面的刷新間隔為30s
stats uri /admin?stats
# 設置統計頁面的uri為/admin?stats
stats realm Private lands
# 設置統計頁面認證時的提示內容
stats auth admin:password
# 設置統計頁面認證的用戶和密碼,如果要設置多個,另起一行寫入即可
stats hide-version
# 隱藏統計頁面上的haproxy版本信息
frontend http_80_in # 定義一個名為http_80_in的前端部分,haproxy會監聽bind的端口
bind 0.0.0.0:80
# http_80_in定義前端部分監聽的套接字
mode http
# 定義為HTTP模式
log global
# 繼承global中log的定義
option forwardfor
# 啟用X-Forwarded-For,在requests頭部插入客戶端IP發送給后端的server,使后端server獲
#取到客戶端的真實IP
acl static_down nbsrv(static_server) lt 1
# 定義一個名叫static_down的acl,當backend static_sever中存活機器數小于1時會被匹配到
acl php_web url_reg /*.php$
#acl php_web path_end .php
# 定義一個名叫php_web的acl,當請求的url末尾是以.php結尾的,將會被匹配到,上面兩種寫
#法任選其一
acl static_web url_reg /*.(css|jpg|png|jpeg|js|gif)$
#acl static_web path_end .gif .png .jpg .css .js .jpeg
# 定義一個名叫static_web的acl,當請求的url末尾是以.css、.jpg、.png、.jpeg、.js、.gif
#結尾的,將會被匹配到,上面兩種寫法任選其一
use_backend php_server if static_down
# 如果滿足策略static_down時,就將請求交予backend php_server
use_backend php_server if php_web
# 如果滿足策略php_web時,就將請求交予backend php_server
use_backend static_server if static_web
# 如果滿足策略static_web時,就將請求交予backend static_server
backend php_server #定義一個名為php_server的后端部分,frontend定義的請求會到到這里處理
mode http
# 設置為http模式
balance source
# 設置haproxy的調度算法為源地址hash
cookie SERVERID
# 允許向cookie插入SERVERID,每臺服務器的SERVERID可在下面使用cookie關鍵字定義
option httpchk GET /test/index.php
# 開啟對后端服務器的健康檢測,通過GET /test/index.php來判斷后端服務器的健康情況
server php_server_1 10.12.25.68:80 cookie 1 check inter 2000 rise 3 fall 3 weight 2
server php_server_2 10.12.25.72:80 cookie 2 check inter 2000 rise 3 fall 3 weight 1
server php_server_bak 10.12.25.79:80 cookie 3 check inter 1500 rise 3 fall 3 backup
# server語法:server [:port] [param*]
# 使用server關鍵字來設置后端服務器;為后端服務器所設置的內部名稱[php_server_1],該名
#稱將會呈現在日志或警報中、后端服務器的IP地址,支持端口映射[10.12.25.68:80]、指定該
#服務器的SERVERID為1[cookie 1]、接受健康監測[check]、監測的間隔時長,單位毫秒[inter
#2000]、監測正常多少次后被認為后端服務器是可用的[rise 3]、監測失敗多少次后被認為后端
#服務器是不可用的[fall 3]、分發的權重[weight 2]、最為備份用的后端服務器,當正常的服
#務器全部都宕機后,才會啟用備份服務器[backup]
backend static_server
mode http
option httpchk GET /test/index.html
server static_server_1 10.12.25.83:80 cookie 3 check inter 2000 rise 3 fall 3
```
### tcp負載均衡的代理配置例子


輪詢測試:

## 實現haproxy啟動/關閉/重啟SHELL腳本
```
#!/bin/bash
#set -x
# chkconfig 2345 on
# description: HAProxy is a TCP/HTTP reverse proxy which is particularly suited for high availability environments.
if [ `whoami` = "root" ];then
echo "root用戶!"
else
echo "請使用root用戶執行該命令,或者使用sudo!"
exit 1;
fi
config="/usr/local/haproxy/conf/haproxy.cfg"
exec="/usr/local/haproxy/sbin/haproxy"
PID="/usr/local/haproxy/var/run/haproxy.pid"
if [ -f $config ];then
echo ""
else
echo "/usr/local/haproxy/conf/haproxy.cfg配置文件不存在,請檢查"
exit 1;
fi
RETVAL=0
start() {
$exec -c -q -f $config
if [ $? -ne 0 ]; then
echo "Errors found in configuration file."
return 1
fi
echo -n "Starting HAproxy: "
$exec -D -f $config -p $PID
RETVAL=$?
echo
[ $RETVAL -eq 0 ]
return $RETVAL
}
stop() {
echo -n "Shutting down HAproxy: "
kill `cat $PID`
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f $PID
return $RETVAL
}
restart() {
$exec -c -q -f $config
if [ $? -ne 0 ]; then
echo "Errors found in configuration file, check it with 'haproxy check'."
return 1
fi
stop
start
}
rhstatus() {
status haproxy
}
check(){
$exec -c -f $config
}
# See how we were called.
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
status)
rhstatus
;;
check)
check
;;
*)
echo $"Usage: haproxy {start|stop|restart|status|check}"
RETVAL=1
esac
exit $RETVAL
```
chmod +x /etc/init.d/haproxy
可通過以下命令實現haproxy的啟動\關閉\重啟等操作
service haproxy start/stop/restart
service haproxy status 查看運行狀態
出自:http://lxsym.blog.51cto.com/1364623/852363
## 虛擬主機核心配置
如下配置中忽略了global,defaults等配置,案例如下:
```
frontend lvs2-lvs3
bind *:8080
acl is_lvs2 hdr_end(host) -i lvs2.test.net:8080
#使用hdr_end指令取request header中的host,如果host后綴部分匹配lvs2.test.net:8080,則匹配請求,
#然后把請求打到對應use_backend指定的后端server上
acl is_lvs3 hdr_beg(host) -i lvs3.test.net:8080
#用于測試request header中的host前綴部分是否匹配到lvs3.test.net:8080
use_backend lvs2 if is_lvs2
#如果規則if指定的acl匹配,則打到use_backend指定的后端server上
use_backend lvs3 if is_lvs3
backend lvs2
#定義后端server
balance roundrobin
#采用輪詢的負載均衡方法,網后端server轉發請求
server free172 10.253.3.14:80 weight 10
server free173 10.253.3.15:80 weight 10
backend lvs3
balance roundrobin
server free174 10.253.3.16:80 weight 10
server free173 10.253.3.15:80 weight 10
```
## 健康監測
1、通過監聽端口進行健康檢測
這種檢測方式,haproxy只會去檢查后端server的端口,并不能保證服務的真正可用。
```
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
balance roundrobin
option httpchk
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
```
2、通過URI獲取進行健康檢測
這種檢測方式,是用過去GET后端server的的web頁面,基本上可以代表后端服務的可用性。
```
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
balance roundrobin
option httpchk GET /index.html
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
```
3、通過request獲取的頭部信息進行匹配進行健康檢測
這種檢測方式,則是基于高級,精細的一些監測需求。通過對后端服務訪問的頭部信息進行匹配檢測。
```
listen http_proxy 0.0.0.0:80
mode http
cookie SERVERID
balance roundrobin
option httpchk HEAD /index.jsp HTTP/1.1\r\nHost:\ www.xxx.com
server web1 192.168.1.1:80 cookie server01 check
server web2 192.168.1.2:80 cookie server02 check inter 500 rise 1 fall 2
```
## haproxy實現持久連接
1 調度算法source
haroxy 將用戶IP經過hash計算后 指定到固定的真實服務器上(類似于nginx 的IP hash 指令)
配置指令 balance source
2 cookie 識別
haproxy 將WEB服務端發送給客戶端的cookie中插入(或添加加前綴)haproxy定義的后端的服務器COOKIE ID。
配置指令例舉 cookie SESSION_COOKIE insert indirect nocache
3 session 識別
haproxy 將后端服務器產生的session和后端服務器標識存在haproxy中的一張表里。客戶端請求時先查詢這張表。然后根據session分配后端server。
配置指令:appsession <cookie> len <length> timeout <holdtime>
詳細參考:http://bbs.linuxtone.org/thread-9526-1-1.html
## 參考
http://leejia.blog.51cto.com/4356849/1421882
* 高可用
http://wgkgood.blog.51cto.com/1192594/961544
* 開啟haproxy監控頁面 和頁面詳細參數介紹
http://blog.csdn.net/dylan_csdn/article/details/51261421
- 版權
- 博客主題
- 如何不去做運行3.5G-docker鏡像的工程師
- 預備主題
- FastDFS快速入門
- mysql定時創建月表
- SpringMVC-Restful
- Docker生態系統
- The Docker Ecosystem: An Introduction to Common Components
- docker監控指標
- 基于etcd服務發現的overlay跨多宿主機容器網絡
- etcd:從應用場景到實現原理的全方位解讀
- docker存儲驅動詳解
- 使用docker/engine-api操作docker
- 提升Docker安全性
- docker安全之用戶資源隔離
- marathon
- 開始
- 安裝mararhon
- 高可用模式
- 使用marathon
- 應用的部署
- 架構組件
- Dubbo與Zookeeper、SpringMVC整合和使用(負載均衡、容錯)
- Openstack架構解析
- haproxy
- Ubuntu系統安裝截圖
- mesos官方文檔
- 關于譯者
- mesos基礎
- Mesos架構
- 視頻與ppt
- 讓mesos跑起來
- 快速入門
- 配置
- Containerizer
- Docker Containerizer
- 監控
- 博客文章集
- 煮餃子與mesos之間妙不可言的關系
- linux運維
- 基礎篇
- 進階篇
- mysql
- Ubuntu14.04安裝mysql5.6
- MySQL 5.6 replicate原理與實踐
- mysql性能
- redis
- redis安裝及基礎知識
- redis數據結構
- redis命令
- redis數據持久化
- Redis主從復制
- redis集群
- 其他