【認識haproxy】
軟體作用:負載均衡,可做4層也可做7層。
優點:
1 配置簡單,軟體使用簡單
2 4、7層都可以做
3 有自動的監控檢查功能
4 是一個專業反向代理軟體
5 會話保持功能比較強大(ngixn的實作是通過ip hash,LVS 是通過-p)
6 幾乎不需要優化,支援數以萬計的并發連接配接。
常常用來對比LVS和NGINX對比
【常用環境】
1 郵件伺服器代理
2 取代F5 等裝置,或者作為其備份
3 代理web
【haporxy的簡單搭建和簡單使用執行個體--代理ssh】
目的:學習了解haproxy
【系統的環境】
[root@master haproxy]# ifconfig |grep -A1 eth0
eth0 Link encap:Ethernet HWaddr 00:0C:29:65:14:0F
inet addr:192.168.100.10 Bcast:192.168.100.255 Mask:255.255.255.0
[root@master haproxy]# uname -r; uname -m
2.6.32-358.el6.x86_64
x86_64
[root@master haproxy]# cat /etc/issue
entOS release 6.4 (Final)
【軟體準備】
[root@master haproxy]# ll -h /usr/local/src/haproxy-1.6.2.tar.gz
-rw-r--r-- 1 root root 1.5M Sep 4 18:52 /usr/local/src/haproxy-1.6.2.tar.gz
【安裝】
<code>cd</code> <code>/usr/local/src</code>
<code>tar</code> <code>xvf haproxy-1.6.2.</code><code>tar</code><code>.gz </code>
<code>cd</code> <code>haproxy-1.6.2</code>
<code>make</code> <code>TARGET=linux2628 ARCH=x86_64</code>
<code>make</code> <code>install</code> <code>PREFIX=</code><code>/usr/local/haproxy</code>
【安裝結果和一些常用目錄建立】
預設隻有三個目錄
[root@master haproxy]# tree -d /usr/local/haproxy/
/usr/local/haproxy/
├── doc
│ └── haproxy
├── sbin
└── share
└── man
建立一些常用目錄:
cd /usr/local/haproxy
mkdir -p etc var/run/ var/chroot logs #放置haproxy配置文的目錄,var/run 放置pid等檔案的目錄
建立haproxy使用者
[root@master etc]# useradd -s /sbin/nologin -M haproxy
[root@master etc]# id haproxy
uid=1002(haproxy) gid=1002(haproxy) groups=1002(haproxy)
【編寫haproxy配置檔案】
vim haproxy.cfg
#Global settings
global
log 127.0.0.1:514 local3 info ###[err warning info debug]
maxconn 20480
chroot /usr/local/haproxy/var/chroot
user haproxy #為haproxy 使用者的uid ,haproxy使用者需要自己手動建立
group haproxy
daemon #背景運作
quiet
nbproc 2
pidfile /usr/local/haproxy/var/run/haproxy.pid
##---------------------------------------------------------------------
## common defaults that all the 'listen' and 'backend' sections will
## use if not designated in their block
defaults
log global ####采用全局定義的日志
mode http ###預設的模式mode { tcp|http|health },tcp是4層,http是7層,health隻會傳回OK
option httplog
option httpclose
option forwardfor
option dontlognull ###不記錄健康檢查的日志資訊
option redispatch ###serverId對應的伺服器挂掉後,強制定向到其他健康的伺服器
retries 3 #3次連接配接失敗就認為服務不可用,也可以通過後面設定
balance roundrobin #采用輪訓算法
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen ssh_poll
bind 192.168.100.10:80
mode tcp
option dontlognull
option logasap
server host1 192.168.100.10:22 check inter 2000 rise 3 fall 3
server host2 192.168.100.13:22 check inter 2000 rise 3 fall 3
listen status
bind 192.168.100.10:8080
stats enable
stats uri /stats #管理位址
stats auth admin:123456 #管理使用者和密碼
[root@master etc]#
# 注意配置檔案的balance輪詢方法,常用 balance roundrobin 和 balance static-rr 兩者的差別是。一個是動态一個是靜态,靜态的在運作的時候不生效。切動态的對後端服務的連接配接數有限制,最多為4128個連接配接。是以一般代理tcp 資料庫的一般輪詢方法是用 balance static-rr。
測試啟動:
檢查配置檔案:
/usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/etc/haproxy.conf -c
-f 指定配置檔案
-c check配置檔案
背景啟動
/usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/etc/haproxy.conf -D
檢查是否啟動1:
[root@master haproxy]# ps -ef |grep haproxy
haproxy 2394 1 0 22:22 ? 00:00:00 /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/etc/haproxy.conf -D
haproxy 2395 1 0 22:22 ? 00:00:00 /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/etc/haproxy.conf -D
root 2626 1707 0 22:27 pts/0 00:00:00 grep --color=auto haproxy
檢查端口是否啟動:
[root@master haproxy]# netstat -tulnp |grep 80
tcp 0 0 192.168.100.10:8080 0.0.0.0:* LISTEN 2394/haproxy
tcp 0 0 192.168.100.10:80 0.0.0.0:* LISTEN 2394/haproxy
【測試80-代理ssh端口】
[root@master haproxy]# ssh -p80 192.168.100.10
[email protected]'s password:
Last login: Sun Sep 4 22:23:02 2016 from 192.168.100.10 #第一被代理輪循到了host1
[root@master ~]# logout
Connection to 192.168.100.10 closed.
[root@master haproxy]# ssh -p80 192.168.100.10
Last login: Sun Sep 4 22:23:05 2016 from 192.168.100.10 #第二被代理輪循到了host2
[root@slave ~]# Connection to 192.168.100.10 closed by remote host.
【檢視日志和配置日志的路徑】
1 日志被定義到了local3 級别為info。 這是要開啟/etc/init.d/rsyslogd 服務的(如何使用這個服務,百度)。
2 netstat -tulnp |grep 514 檢視是否監聽rsyslogd端口
預設日志寫入/var/log/messages
<a href="http://s3.51cto.com/wyfs02/M01/86/D2/wKioL1fMMg_CQVR9AACDid8q5Zc828.png-wh_500x0-wm_3-wmp_4-s_1474080960.png" target="_blank"></a>
如何修改日志的路徑?
1 修改rsyslogd的配置(514監聽端口一定要開啟)
[root@master haproxy]# tail -1 /etc/rsyslog.conf
local3.* /usr/local/haproxy/logs/haproxy.log
2 重新開機rsyslogd服務
/etc/init.d/rsyslog restart
【編寫haproxy的啟動腳本】
腳本根據以下選項參數:
-c check mode : only check config files and exit
-D goes daemon ; -C changes to <dir> before loading files.
-V enters verbose mode (disables quiet mode)
-p writes pids of all children to this file
-sf/-st [pid ]* finishes/terminates old pids.
腳本--簡單 使用。不使用系統自帶函數/etc/init.d/functions
<code>#!/bin/bash</code>
<code>#by andy at 20160905</code>
<code>BASE=</code><code>"/usr/local/haproxy"</code>
<code>PROG=</code><code>"$BASE/sbin/haproxy"</code>
<code>PIDFILE=</code><code>"$BASE/var/run/haproxy.pid"</code>
<code>CONFIG=</code><code>"$BASE/etc/haproxy.conf"</code>
<code>lockfile=</code><code>/var/lock/subsys/haproxy</code>
<code>case</code> <code>"$1"</code> <code>in</code>
<code> </code><code>start)</code>
<code> </code><code>$PROG -f $CONFIG -D</code>
<code> </code><code>retval=$?</code>
<code> </code><code>[ $retval -</code><code>eq</code> <code>0 ] && </code><code>echo</code> <code>"start ok"</code> <code>&& </code><code>touch</code> <code>$lockfile</code>
<code> </code><code>;;</code>
<code> </code><code>stop)</code>
<code> </code><code>kill</code> <code>$(</code><code>cat</code> <code>$PIDFILE)</code>
<code> </code><code>[ $retval -</code><code>eq</code> <code>0 ] && </code><code>echo</code> <code>"stop ok"</code> <code>&& </code><code>rm</code> <code>-f $lockfile</code>
<code> </code><code>status)</code>
<code> </code><code>if</code> <code>[ -f $lockfile ];</code><code>then</code>
<code> </code><code>echo</code> <code>"haproxy is running..."</code>
<code> </code><code>else</code>
<code> </code><code>echo</code> <code>"haproxy is not running..."</code>
<code> </code><code>fi</code>
<code> </code><code>restart)</code>
<code> </code><code>echo</code> <code>"stop ok"</code>
<code> </code><code>echo</code> <code>"start ok"</code>
<code> </code><code>reload)</code>
<code> </code><code>$PROG -f $CONFIG -D -sf $(</code><code>cat</code> <code>$PIDFILE)</code>
<code> </code><code>[ $retval -</code><code>eq</code> <code>0 ] && </code><code>echo</code> <code>"reload ok"</code>
<code> </code><code>check)</code>
<code> </code><code>$PROG -f $CONFIG -V -c</code>
<code> </code><code>*)</code>
<code> </code><code>echo</code> <code>"USAGE: $0 {start|stop|restart|status|reload|check}"</code>
<code> </code><code>exit</code> <code>1</code>
<code> </code><code>esac</code>
【ha的自帶status頁面】
即,綁定在8080端口,開啟stats,uri 為stats 賬号密碼為admim/123456
<a href="http://s1.51cto.com/wyfs02/M00/86/ED/wKiom1fO01nAS-SFAAGNWNfv2sA035.png-wh_500x0-wm_3-wmp_4-s_1460222705.png" target="_blank"></a>
【關于監控檢查】
關于檢查檢查參數
基于tcp端口的健康檢查
check port 80 inter 2000 rise 3 fall 3
1 port 檢查的是RS端口80
2 inter 檢查時間間隔是2s 預設2000
3 rise 恢複時候的一個參數,恢複前檢查2次都Ok,認為其複活,加入群組。 預設是 2次
4 fall 3次檢查失敗後就摘除。預設值是3
差別以下:
server host1 192.168.100.10:8089 check port 80 inter 5000 rise 3 fall 3
監控檢查端口192.168.100.10:80端口每隔5s一次3次失敗則摘除,如果恢複3次檢查Ok就就入叢集
server host1 192.168.100.10:8089 check
==等于
server host1 192.168.100.10:8089 check port 8089 inter 5000 rise 3 fall 3
監控檢查端口192.168.100.10:8089端口每隔3s一次3次失敗則摘除,如果恢複2次檢查Ok就就入叢集
基于http IP url的檢查方式 option httpchk <method> <uri> <version>
method :如果沒有設定the "OPTIONS" method is used
uri : 如果沒有設定 It defaults to " / "
version: is the optional HTTP version string. It defaults to "HTTP/1.0".but some servers might behave incorrectly in HTTP 1.0, so turning it to HTTP/1.1 may sometimes help.
如果是1.1的版本Host字段一定要加 after "\r\n" following the version string.
合适7層的檢查優先于port檢查
1)
HEAD方式- 這是一個進階一點的健康檢查
如隻檢查通路碼為200的則通過檢查 相當要curl -I http://ip:port/check.html 的傳回碼要為200
option httpchk HEAD /check.html
==
option httpchk HEAD /check.html HTTP/1.0
server host1 192.168.100.10:8089 check inter 5000 rise 3 fall 3
server host2 192.168.100.13:80 check inter 5000 fall 3
也可以比對host内容
option httpchk HEAD /check.html HTTP/1.0
2)
GET方式 知識一個method方法而已
option httpchk GET /check.html
【禁用一個RS】
server host1 192.168.100.10:8089 check inter 5000 rise 3 fall 3 disabled
此節點在haproxy啟動時候,将RS節點處于維護狀态,不停供服務。
【server 語句的常用功能參數】
1) 高可用 backup
功能參數介紹
1) 目的:高可用
backup
When "backup" is present on a server line, the server is only used in load
balancing when all other non-backup servers are unavailable.
其他非non-bakcup RS節點都挂了的時候,才啟用backup提供服務。 讓其他非backup節點,恢複後,backup又不被啟用。
如:
server host1 192.168.100.10:8089 check inter 2000 rise 3 fall 3
server host2 192.168.100.13:80 check inter 2000 rise 3 fall 3
server host3 192.168.100.20:80 check inter 2000 rise 3 fall 3 backup
注意:隻有host1 host2都被剔除後,host3才啟用
2) option allbackups 語句
option allbackups
server ...
server host2 192.168.100.13:80 check inter 2000 rise 3 fall 3 backup
server host3 192.168.100.20:80 check inter 2000 rise 3 fall 3 backup
解釋:
預設當所有非backup的節點都挂了的時候,隻有第一個backup非接管所有的流量。但是有時又一個backup是承受不住了。是以需要allbackups開啟,這樣是多個backup會同時接管流量。
By default, the first operational backup server gets all traffic when normalservers are all down. Sometimes, it may be preferred to use multiple backups at once, because one will not be enough. When "option allbackups" is enabled,the load balancing will be performed among all backup servers when all normal ones are unavailable.
【RS用戶端記錄真實用戶端IP問題】
1 讓haproxy支援和功能,作為forward
option forwardfor
Enable insertion of the X-Forwarded-For header to requests sent to servers
可以放置在ay be used in sections : defaults | frontend | listen | backend區塊中
2 RS端 apache 和nginx有響應的日志修改問題調整X-Forwarder-For
延伸,RS如何不記錄ha因為健康檢查通路的日志呢?
nginx中如下配置即可:
location = /check.html {
access_log off;
}
【ha的高可用】
1 可以使用keepalived
2 可以使用heartbeat
如keepalived的檢測腳本(一定要控制好master 和backup的 優先級)
[root@slave ~]# cat /root/check_haproxy.sh
<code>A=`</code><code>ps</code> <code>-C haproxy --no-header | </code><code>wc</code> <code>-l`</code>
<code>if</code> <code>[ $A -</code><code>eq</code> <code>0 ];</code><code>then</code>
<code> </code><code>/etc/init</code><code>.d</code><code>/haproxy</code> <code>start</code>
<code> </code><code>sleep</code> <code>3</code>
<code> </code><code>if</code> <code>[ `</code><code>ps</code> <code>-C haproxy --no-header | </code><code>wc</code> <code>-l` -</code><code>eq</code> <code>0 ];</code><code>then</code>
<code> </code><code>#killall keepalived</code>
<code> </code><code>exit</code> <code>1</code>
<code> </code><code>fi</code>
<code>fi</code>
有一個問題: 1 當使用HA高可用的時候,VIP一定隻會haproxy的一個主節點或者被節點,是以在啟動haproxy的時候,肯定會出現報錯。如下:
[root@slave etc]# /etc/init.d/haproxy start
[ALERT] 261/215509 (25575) : Starting proxy ssh_poll: cannot bind socket[192.168.100.14:80]
原因: 綁定IP或者端口失敗。 綁定IP失敗的原因是網卡現在沒有這個VIP位址。如果是端口那就可能是其他程式占用。
解決沒有IP也能綁定的啟動haproxy的方法:
修改核心參數
<code>echo</code> <code>'net.ipv4.ip_nonlocal_bind = 1'</code> <code>>></code><code>/etc/sysctl</code><code>.conf</code>
<code>sysctl -p</code>
【七層的應用】
基于host
基于請求的路徑
基于user-agent
【基于host】
frontend www
bind 192.168.100.10:80
acl www_domain hdr(host) -i www.test.com
acl bbs_domain hdr(host) -i bbs.test.com
redirect prefix http://bbs.baidu.com code 301 if bbs_domain
use_backend www if www_domain
default_backend blog
.......
注意:比對到bbs_domain這個acl名字的規則的,301重定向到bbs.baidu.com
比對到www_doamain這個acl的規則的,使用backend blog。
【基于路徑】
acl url_begin_static path_beg /static /images /img /css
acl url_end_static path_end .gif .png .jpg .css .js
【基于user-agent】
frontend ua_test
acl ua_i hdr_reg(User-Agent) -i iphone android #比對User-Agent類型
acl ua_w hdr_reg(User-Agent) -i window
redirect prefix http://www.apple.com code 301 if ua_i
redirect prefix http://www.microsoft.com/zh-cn code 301 if ua_w
default_backend www
注意:比對到user-agent中有iphone或者android的acl都重定向到蘋果的官網。
測試:
[root@slave haproxy]# curl -I -H "user-agent:iphone6" bbs.test.com
HTTP/1.1 301 Moved Permanently
Content-length: 0
Location: http://www.apple.com/
Connection: close
【通路出錯時候的,優雅頁面顯示】
<code> is the HTTP status code. Currently, HAProxy is capable of
generating codes 200, 400, 403, 405, 408, 429, 500, 502, 503, and
504.
errorfile 400 /etc/haproxy/errorfiles/400badreq.html
errorfile 403 /etc/haproxy/errorfiles/403forbid.html
errorfile 503 /etc/haproxy/errorfiles/503sorry.html
【use_backend 中if 語句的與 或 非實作】
acl an1 hdr_sub(host) -i www.test.com
acl an_anhouse.cn_443 hdr_beg(host) -i member gold hft hfb pay www bi tt oa ssl-static ssl-file
正常滿足一個比對條件的
use_backend an1 if an_anhouse.cn_443
與
use_backend an1 if an_anhouse.cn_443 an1
或
use_backend an1 if an_anhouse.cn_443 || an1
非
use_backend an1 if ! an_anhouse.cn_443
【 #強制跳轉https的域名】
redirect scheme https code 301 if { hdr_beg(host) hfb bi tt fin pay oa } !{ ssl_fc }
注: ssl_fc 是一個預設布爾值
本文轉自殘劍部落格51CTO部落格,原文連結http://blog.51cto.com/cuidehua/1846235如需轉載請自行聯系原作者
cuizhiliang