一、haproxy的介紹
HAProxy提供高可用性、負載均衡以及基於TCP和HTTP應用的代理,支持虛擬主機,尤其適用於高負載且需要持久連接或7層處理機制的web站點。。Haproxy支持兩種主要代理模式:第一個是4層tcp代理(例如:可用於郵件服務內部協議通信服務器、Mysql服務等)。第二個是7層代理(如HTTP代理)。在4層tcp代理模式下,Haproxy僅在客戶端和服務器之間雙向轉發流量。但是在7層模式下Haproxy會分析應用層協議,並且能通過運行、拒絕、交換、增加、修改或者刪除請求(request)或者回應(reponse)裏指定內容來控制協議。
二、haproxy的配置
haproxy的配置文件/etc/haproxy/haproxy.cfg,分爲5個部分
1、global:參數是進程級的,通常是和操作系統相關。這些參數一般只設置一次,如果配置無誤,就不需要再次進行修改
2、defaults:配置默認參數,這些參數可以被用到frontend,backend,Listen組件
3、frontend:用於定義一系列監聽的套接字,這些套接字可接受客戶端請求並與之建立連接
4、backend:用於定義一系列“後端”服務器,代理將會將對應客戶端的請求轉發至這些服務器
5、Listen:通過關聯“前端”和“後端”定義了一個完整的代理,通常只對TCP流量有用
下面爲默認配置文件:
global log 127.0.0.1 local2 #全局syslog服務器,最多可以定義兩個 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 #最大連接數 user haproxy group haproxy daemon stats socket /var/lib/haproxy/stats defaults mode http #代理模式 (tcp|http),混合模式無需設置mode log global #定義全局日誌 option httplog #啓用記錄HTTP請求、會話狀態和計時器的功能。混合模式還需要tcplog option dontlognull #不記錄健康檢查的日誌信息 option http-server-close #每次請求完畢後主動關閉http通道 option forwardfor except 127.0.0.0/8 #如果後端服務器需要獲得客戶端真實ip需要配置的參數,可以從Http Header中獲得客戶端ip option redispatch #serverId對應的服務器掛掉後,強制定向到其他健康的服務器 retries 3 #失敗連接次數3 timeout http-request 10s #http請求超時 timeout queue 1m #隊列超時 timeout connect 10s #連接超時時間 timeout client 1m #客戶端連接超時 timeout server 1m #服務器連接超時 timeout http-keep-alive 10s #持久連接連接超時 timeout check 10s #心跳檢測超時 maxconn 3000 #最大連接數 frontend main *:5000 acl url_static path_beg -i /static /p_w_picpaths /javascript /stylesheets acl url_static path_end -i .jpg .gif .png .css .js use_backend static if url_static #acl default_backend app #使用的後端服務器組 backend static # balance roundrobin #負載均衡算法 server static 127.0.0.1:4331 check backend app balance roundrobin server app1 127.0.0.1:5001 check server app2 127.0.0.1:5002 check server app3 127.0.0.1:5003 check server app4 127.0.0.1:5004 check
關於默認配置文件的補充:
1、log
將log記錄在/var/log/haproxy.log
編輯 vim /etc/rsyslog.conf,增加log2* /var/log/haproxy.log,重啓日誌 service rsyslog restart
/etc/sysconfig/rsyslog
SYSLOGD_OPTIONS="-r -m 0 -c 2" #-c 2 使用兼容模式,默認是 -c 5 #-r 開啓遠程日誌 #-m 0 標記時間戳。單位是分鐘,爲0時,表示禁用該功能
/etc/rsyslog.conf
$ModLoad imudp $UDPServerRun 514
2、balance
定義負載均衡算法,可以用defaults,backed及listen中,算法常用的有以下幾種
1)、roundrobin:基於權重進行輪詢,可以在運行時進行權重調整。但是,設計上每個後端服務器僅能最多支持4128個連接
2)、static-rr:靜態的基於權重輪詢,運行時調整權重無效,但是沒有對連接數的限制
3)、leastconn:請求被髮往後端最少連接數目的服務器,可以動態調整權重,在保持較長回話的場景中推薦使用此算法
4)、source:類似於niginx的ip_hash ,默認爲靜態
5)、uri:對uri ?號之前的部分或者整個uri進行hash算後除模派發至相應服務器,適用於代理緩存及反病毒代理
URL Syntax: <scheme>://<host>:<port>/<path>;<params>?<query>#<frag>
http://www.wlw.com/test/go;type=s
6)、url_param:通過<argument>爲URL指定的參數在每個HTTP GET請求中將會被檢索;如果找到了指定的參數且其通過等於號“=”被賦予了一個值,那麼此值將被執行hash運算並被服務器的總權重相除後派發至某匹配的服務器;此算法可以通過追蹤請求中的用戶標識進而確保同一個用戶ID的請求將被送往同一個特定的服務器,除非服務器的總權重發生了變化;如果某請求中沒有出現指定的參數或其沒有有效值,則使用輪叫算法對相應請求進行調度;此算法默認爲靜態的
7)、hdr(<name>):對於每個HTTP請求,通過<name>指定的HTTP首部將會被檢索;如果相應的首部沒有出現或其沒有有效值,則使用輪叫算法對相應請求進行調度;其有一個可選選項“use_domain_only”,可在指定檢索類似Host類的首部時僅計算域名部分以降低hash算法的運算量;此算法默認爲靜態的
3、hash_type
map_based:默認 不適用於後端爲緩存服務器
consistent:一致性hash 適用於後端爲緩存服務器
4、bind
用於frontend和listen中,格式爲bind [<address>]:<port_range> [, ...]
5、default_backend
沒有匹配use_backend的情況下默認使用的後端
6、server
server <name> <address>[:port] [param*]
[param*]參數
1)backup,負載均衡的備用服務器
2)check,進行健康檢測,還可以根據另外的參數進行定製 inter <delay> 時間間隔 rise <count>從離線到正常的檢測次數 fall<count>從正常到離線的檢測次數
後端check的方法
option httpchk:請求首頁,對方響應200即爲成功
option httpchk <uri>:指定的uri,對方響應200即爲成功
option httpchk <method> <uri>:指定方法和uri
option httpchk <method> <uri> <version>:不能用於frontend段
3)cookie <value>:爲指定server設定cookie值,此處指定的值將在請求入站時被檢查,第一次爲此值挑選的server將在後續的請求中被選中,其目的在於實現持久連接的功能;基於cookie會話的源綁定。
backend static balance roundrobin cookie webser insert nocache server serv1 192.168.0.102:80 check port 80 weight 2 cookie serv1 server serv2 192.168.0.103:80 check port 80 weight 1 cookie serv2
4) weight <weight>:權重,默認爲1,最大值爲256,0表示不參與負載均衡;
5)redir <prefix>:啓用重定向功能,將發往此服務器的GET和HEAD請求均以302狀態碼響應;需要注意的是,在prefix後面不能使用/,且不能使用相對地址,以免造成循環
server serv1 192.168.0.102:80 check port 80 redir http://192.168.0.104
6)server 綁定端口後前端bind多個端口都可以在server的端口打開,否則默認使用與前端相同的端口打開
7、stat
listen stats bind *:3306 #讓stats統計報告監聽在1515端口上 stats enable #開啓stats功能 stats hide-version #隱藏版本信息 stats uri /hpadmin?stats #設置uri stats realm HAporxy\ admin #開啓認證時登錄框顯示的信息 stats auth admin:admin #認證的賬號密碼 stats admin if TRUE #如果上面條件認證通過,開啓管理接口 stats scope . #僅能爲127.0.0.1本地訪問
stats scope { <name> | "." }
<name>:可以是一個“listen”、“frontend”或“backend”區段的名稱,而“.”則表示stats scope語句所定義的當前區段
8、errorfile
errorfile:在用戶請求不存在的頁面時,返回一個頁面文件給客戶端,這裏可用的狀態碼有200、400、403、408、500、502、503和504;
errorfile 400 /etc/haproxy/errorpages/400badreq.http
errorfile 403 /etc/haproxy/errorpages/403forbid.http
errorfile 503 /etc/haproxy/errorpages/503sorry.http
9、option forwardfor:允許在發往服務器的請求首部中插入“X-Forwarded-For”首部。
LogFormat "%{X-Forwarded-For}i %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
10、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中可以指定多個測試條件,這些測試條件需要由邏輯操作符指定其關係。條件間的組合測試關係有三種:“與”(默認即爲與操作)、“或”(使用“||”操作符)以及“非”(使用“!”操作符)。
1)常用的測試標準(criteria)
be_sess_rate(backend) <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(frontend) <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 50ms
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、/p_w_picpaths、/javascript或/stylesheets頭。
acl url_static path_beg -i /static /p_w_picpaths /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>指定的模式
用法一: 將源IP爲172.16.253.254的用戶禁止、將403的錯誤重定向到其他服務器; frontend webservers bind *:80 default_backend webservs acl badguy src 172.16.253.254 block if badguy errorloc 403 http://www.baidu.com 用法二: 當用戶訪問地址爲172.16.2.1時,將訪問頁面重定向http://www.baidu.com frontend webservers bind *:80 default_backend webservs acl dstipaddr hdr(Host) 172.16.2.1 redirect location http://www.baidu.com if dstipaddr 用法三: acl中path的使用 frontend webservers bind *:80 default_backend webservs acl badguy src 172.16.253.254 acl denyfile path /1.html http-request deny if badguy denyfile 用法四: 讀寫分離: acl read method GET acl read method HEAD acl write method PUT acl write method POST use_backend imgservers if read use_backend uploadservers if write 用法五: 動靜分離 acl static path_end .html use_backend staticservs if static default_backend appservs
三、keepalived+haproxy動靜分離部署discuz
192.168.1.200配置:
haproxy配置
global log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon 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 3000 frontend main bind 192.168.1.250:80 acl url_static path_beg -i /static /p_w_picpaths /javascript /stylesheets acl url_static path_end -i .jpg .gif .png .css .js use_backend static if url_static default_backend web backend static balance roundrobin server static 192.168.1.202:80 check port 80 backend web balance roundrobin server web 192.168.1.203:80 check port 80
keepalived配置:
! Configuration File for keepalived global_defs { notification_email { root@localhost } notification_email_from root smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id LVS_10 } vrrp_script haproxy { script "/etc/keepalived/haproxy.sh" interval 1 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.1.250/24 dev eth0 label eth0:1 } track_script { haproxy } }
/etc/keepalived/haproxy.sh
#!/bin/bash counter=$(ps -C haproxy --no-heading|wc -l) if [ "${counter}" = "0" ]; then /usr/sbin/haproxy -f /etc/haproxy/haproxy.cfg sleep 2 counter=$(ps -C haproxy --no-heading|wc -l) if [ "${counter}" = "0" ]; then /etc/init.d/keepalived stop fi fi
192.168.1.201配置類似修改優先級和state
192.168.1.204配置
mysql授權:
mysql> grant all on discuz.* to disuser@'%' identified by 'smile'; mysql> flush privileges;
nfs配置:
vim /etc/exports
/data/discuz *(rw) //discuz訪問權限爲文件權限和客戶及讀寫權限
chmod -R 777 /data/discuz
192.168.1.203配置:
yum install php php-mysql -y
mkdir /var/www/hrml/discuz
mount -t nfs 192.168.1.204:/data/discuz /var/www/html/discuz
192.168.1.204配置:
mount -t nfs 192.168.1.204:/data/discuz /var/www/html/discuz