Haproxy 安裝及配置

Haproxy介紹

HAProxy是一個特別適用於高可用性環境的TCP/HTTP開源的反向代理和負載均衡軟件。實現了一種事件驅動,單一進程模型,支持很是大的併發鏈接,是由於事件驅動模型有更好的資源和時間管理的用戶端(user-space)實現這些業務javascript

  • 在7層負載均衡方面的功能很強大(支持cookie track, header rewrite等等)
  • 支持雙機熱備
  • 支持虛擬主機
  • 支持健康檢查
  • 同時還提供直觀的監控頁面,能夠清晰實時的監控服務集羣的運行情況。
  • 同時支持Linux 2.6內核中System Epoll,經過簡化系統調用,大幅的提升了網絡I/O性能。

 

特徵php

  • 根據靜態分配的cookie 分配HTTP請求
  • 分配負載到各個服務器,同時保證服務器經過使用HTTP Cookie實現鏈接保持;
  • 當主服務器宕機時切換到備份服務器;容許特殊端口的服務監控;
  • 作維護時經過熱配置能夠保證業務的連續性,更加人性化;
  • 添加/修改/刪除HTTP Request和Response 頭;
  • 經過特定表達式Block HTTP請求;
  • 根據應用的cookie作鏈接保持;
  • 帶有用戶驗證的詳細的HTML監控報告.css

 

負載均衡算法html

  • roundrobin,表示簡單的輪詢,服務器根據權重輪流使用,這個是負載均衡基本都具有的;
  • static-rr,表示根據權重,根據權重輪流使用,對服務器的數量沒有限制;
  • leastconn,表示最少鏈接者先處理,建議用於長回話服務;
  • source, 表示根據請求源IP,這個跟NginxIP_hash機制相似,咱們用其做爲解決session問題的一種方法,建議關注;
  • uri,    表示根據請求的URI;uri hash算法
  • url_param,表示根據請求的URl參數’balance url_param’ requires an URL parameter name;
  • hdr(name), 表示根據HTTP請求頭來鎖定每一次HTTP請求;
  • rdp-cookie(name), 表示根據據cookie(name)來鎖定並哈希每一次TCP請求。

 

Haproxy部署

  • yum安裝

yum install haproxy keepalived -y

#配置文件:
/etc/haproxy/haproxy.cfg
/etc/keepalived/keepalived.conf

 

  • 源碼安裝

#安裝依賴包
yum install -y net-tools vim lrzsz tree screen lsof tcpdump nc mtr nmap gcc glib gcc-c++ make
#下載並安裝 wget http:
//www.haproxy.org/download/1.6/src/haproxy-1.6.3.tar.gz tar zxf haproxy-1.6.3.tar.gz cd haproxy-1.6.3 make TARGET=linux2628 ARCH=x86_64 PREFIX=/usr/local/haproxy make install PREFIX=/usr/local/haproxy cp /usr/local/sbin/haproxy /usr/sbin/ haproxy -v

 

Haproxy啓動腳本前端

cd /usr/local/src/haproxy-1.6.3  

cp examples/haproxy.init /etc/init.d/haproxy

chmod 755 /etc/init.d/haproxy

 

配置文件java

useradd -r haproxy

mkdir /etc/haproxy   /var/lib/haproxy    /var/run/haproxy


#配置文件
cat
/etc/haproxy/haproxy.cfg 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
*:5000 acl url_static path_beg -i /static /images /javascript /stylesheets acl url_static path_end -i .jpg .gif .png .css .js use_backend static if url_static 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

 

Haproxy日誌設置mysql

vim /etc/rsyslog.conf
#rsyslog 默認狀況下,須要在514端口監聽UDP,因此能夠把/etc/rsyslog.conf以下的註釋去掉
# Provides UDP syslog reception 
$ModLoad imudp 
$UDPServerRun 514
local3.*         /var/log/haproxy.log

#重啓rsyslog
systemctl restart rsyslog

 

配置案例linux

###########全局配置#########
global
  log 127.0.0.1 local0         #[日誌輸出配置,全部日誌都記錄在本機,經過local0輸出]
  log 127.0.0.1 local3 notice     #定義haproxy 日誌級別[error warringinfo debug]
  daemon                 c#之後臺形式運行harpoxy
  nbproc 1                 #設置進程數量,應該與服務器的cpu核心數一致
  maxconn 4096             #默認最大鏈接數,需考慮ulimit-n限制
  #user haproxy             #運行haproxy的用戶
  #group haproxy             #運行haproxy的用戶所在的組
  #pidfile /var/run/haproxy.pid     #haproxy 進程PID文件
  #ulimit-n 819200             #ulimit 的數量限制
  #chroot /usr/share/haproxy       #chroot運行路徑
  #debug                 #haproxy 調試級別,建議只在開啓單進程的時候調試
  #quiet

########默認配置############
defaults
  log global
  mode http               #默認的模式mode { tcp|http|health },tcp是4層,http是7層,health只會返回OK
  option httplog             #日誌類別,採用httplog
  option dontlognull           #不記錄健康檢查日誌信息
  retries 2               #兩次鏈接失敗就認爲是服務器不可用,也能夠經過後面設置
  #option forwardfor           #若是後端服務器須要得到客戶端真實ip須要配置的參數,能夠從Http Header中得到客戶端ip
  option httpclose           #每次請求完畢後主動關閉http通道,chaproxy不支持keep-alive,只能模擬這種模式的實現
  #option redispatch         #當serverId對應的服務器掛掉後,強制定向到其餘健康的服務器,之後將不支持
  option abortonclose       #當服務器負載很高的時候,自動結束掉當前隊列處理比較久的連接
  maxconn 4096           #默認的最大鏈接數
  timeout connect 5000ms     #鏈接超時
  timeout client 30000ms     #客戶端超時
  timeout server 30000ms       #服務器超時
  #timeout check 2000         #心跳檢測超時
  #timeout http-keep-alive10s     #默認持久鏈接超時時間
  #timeout http-request 10s       #默認http請求超時時間
  #timeout queue 1m         #默認隊列超時時間
  balance roundrobin           #設置默認負載均衡方式,輪詢方式
  #balance source           #設置默認負載均衡方式,相似於nginx的ip_hash
  #balnace leastconn         #設置默認負載均衡方式,最小鏈接數

########統計頁面配置########
listen stats
  bind 0.0.0.0:1080         #設置Frontend和Backend的組合體,監控組的名稱,按須要自定義名稱
  mode http             #http的7層模式
  option httplog           #採用http日誌格式
  #log 127.0.0.1 local0 err     #錯誤日誌記錄
  maxconn 10             #默認的最大鏈接數
  stats refresh 30s         #統計頁面自動刷新時間
  stats uri /stats         #統計頁面url
  stats realm XingCloud\ Haproxy   #統計頁面密碼框上提示文本
  stats auth admin:admin       #設置監控頁面的用戶和密碼:admin,能夠設置多個用戶名
  stats auth Frank:Frank       #設置監控頁面的用戶和密碼:Frank
  stats hide-version         #隱藏統計頁面上HAProxy的版本信息
  stats admin if TRUE       #設置手工啓動/禁用,後端服務器(haproxy-1.4.9之後版本)

########設置haproxy 錯誤頁面#####
#errorfile 403 /home/haproxy/haproxy/errorfiles/403.http
#errorfile 500 /home/haproxy/haproxy/errorfiles/500.http
#errorfile 502 /home/haproxy/haproxy/errorfiles/502.http
#errorfile 503 /home/haproxy/haproxy/errorfiles/503.http
#errorfile 504 /home/haproxy/haproxy/errorfiles/504.http

########frontend前端配置##用來匹配接收客戶端所請求的域名############
frontend main
  bind *:80               #這裏建議使用bind *:80的方式,要否則作集羣高可用的時候有問題,vip切換到其餘機器就不能訪問了。
  acl web hdr(host) -i www.abc.com   #acl後面是規則名稱,-i爲忽略大小寫,後面跟的是要訪問的域名,若是訪問www.abc.com這個域名,就觸發web規則,。
  acl img hdr(host) -i img.abc.com   #若是訪問img.abc.com這個域名,就觸發img規則。
  use_backend webserver if web   #若是上面定義的web規則被觸發,即訪問www.abc.com,就將請求分發到webserver這個做用域
  use_backend imgserver if img   #若是上面定義的img規則被觸發,即訪問img.abc.com,就將請求分發到imgserver這個做用域。
  default_backend dynamic       #不知足則響應backend的默認頁面

########backend後端配置######定義後端服務器集羣,以及後端服務器的一些權重隊列鏈接數等選項的設置########
backend webserver             #webserver做用域,在frontend下指定設置,爲自定義的名稱,frontend會引用
  mode http
  balance roundrobin             #balance roundrobin 負載輪詢,balance source 保存session值,支持static-rr,leastconn,first,uri等參數
  option httpchk /index.html HTTP/1.0    #健康檢查, 檢測文件,若是分發到後臺index.html訪問不到就再也不分發給它
  server web1 10.16.0.9:8085  cookie 1 weight 5 check inter 2000 rise 2 fall 3
  server web2 10.16.0.10:8085 cookie 2 weight 3 check inter 2000 rise 2 fall 3
  #cookie 1表示serverid爲1,check inter 1500 是檢測心跳頻率 
  #rise 2是2次正確認爲服務器可用,fall 3是3次失敗認爲服務器不可用,weight表明權重

backend imgserver
  mode http
  option httpchk /index.php
  balance roundrobin 
  server img01 192.168.137.101:80 check inter 2000 fall 3
  server img02 192.168.137.102:80 check inter 2000 fall 3

backend dynamic 
  balance roundrobin 
  server test1 192.168.1.23:80 check maxconn 2000 
  server test2 192.168.1.24:80 check maxconn 2000


listen tcptest 
  bind 0.0.0.0:5222 
  mode tcp 
  option tcplog  #採用tcp日誌格式 
  balance source 
  #log 127.0.0.1 local0 debug 
  server s1 192.168.100.204:7222 weight 1 
  server s2 192.168.100.208:7222 weight 1

 

Haproxy健康檢查android

#經過監聽端口進行健康檢查

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 #經過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 
 相關配置
option httpchk <method><uri><version>

  #經過request獲取的頭部信息進行匹配進行健康檢測,經過對後端服務訪問的頭部信息進行匹配檢測。nginx

  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

 

根據URL後綴進行負載均衡

# 定義一個名叫php_web的acl,當請求的url末尾是以.php結尾的,將會被匹配到,下面兩種寫法任選其一
acl php_web url_reg /*.php$
#acl php_web path_end .php 

# 定義一個名叫static_web的acl,當請求的url末尾是以.css、.jpg、.png、.jpeg、.js、.gif結尾的,將會被匹配到,下面兩種寫法任選其一
acl static_web url_reg /*.(css|jpg|png|jpeg|js|gif)$
#acl static_web path_end .gif .png .jpg .css .js .jpeg


# 若是知足策略php_web時,就將請求交予backend php_server
use_backend php_server if php_web

# 若是知足策略static_web時,就將請求交予backend static_server
use_backend static_server if static_web

 

根據url進行負載均衡

acl invitec url_reg /invitec_pk.do
use_backend b_yxpopo_com_pk if invitec

 

根據User-Agent實現域名跳轉

需求以下:

1:域名www.example.com PC端訪問正常顯示
2:手機端:Android iPhone 訪問首頁跳轉到wap.example.com,
3:static big_* small_* 這幾類文件開頭的進行跳轉進行跳轉效果以下所示:
   訪問:http://club.jesse.com/static/20130916/27635260.htm
  跳轉到:http://3g.club.jesse.com/static/20130916/27635260.htm
4:手機端訪問:除規則3之外的不跳轉:如http://club.xywy.com/top.htm訪問URL 不變。


acl static_d path_beg /static /small /big  #匹配XX開始的
acl index_page path_reg ^/$  #匹配首頁
acl ua hdr_reg(User-Agent) -i iphone android #匹配User-Agent類型
acl club hdr_reg(host) -i   club.jesse.com #匹配訪問的域名
redirect prefix http://3g.club.jesse.com if ua static_d club #匹配相關的ACL策略就進行跳轉
redirect prefix http://3g.club.jesse.com if index_page ua club
use_backend club_pool if club

 

1.6之後版本加入了 resolvers

 

ACL

########ACL策略定義#########################
一、#若是請求的域名知足正則表達式返回true -i是忽略大小寫
acl denali_policy hdr_reg(host) -i ^(www.inbank.com|image.inbank.com)$

二、#若是請求域名知足www.inbank.com 返回 true -i是忽略大小寫
acl tm_policy hdr_dom(host) -i www.inbank.com

三、#在請求url中包含sip_apiname=,則此控制策略返回true,不然爲false
acl invalid_req url_sub -i sip_apiname=#定義一個名爲invalid_req的策略

四、#在請求url中存在timetask做爲部分地址路徑,則此控制策略返回true,不然返回false
acl timetask_req url_dir -i timetask

五、#當請求的header中Content-length等於0時返回 true
acl missing_cl hdr_cnt(Content-length) eq 0

#########acl策略匹配相應###################
一、#當請求中header中Content-length等於0 阻止請求返回403
block if missing_cl

二、#block表示阻止請求,返回403錯誤,當前表示若是不知足策略invalid_req,或者知足策略timetask_req,則阻止請求。
block if !invalid_req || timetask_req

三、#當知足denali_policy的策略時使用denali_server的backend
use_backend denali_server if denali_policy

四、#當知足tm_policy的策略時使用tm_server的backend
use_backend tm_server if tm_policy

五、#reqisetbe關鍵字定義,根據定義的關鍵字選擇backend
reqisetbe ^Host:\ img dynamic
reqisetbe ^[^\ ]*\ /(img|css)/ dynamic
reqisetbe ^[^\ ]*\ /admin/stats stats

六、#以上都不知足的時候使用默認mms_server的backend
default_backend mms

 

啓動Haproxy並驗證

/usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/haproxy.cfg     #啓動

#查看狀態
http://ip:1080/stats    #配置文件listen已定義

 

優化

查看Tcp鏈接數和佔用內存

[root@bogon ~]# ss -s && free -g
Total: 337 (kernel 359)
TCP:   294 (estab 9, closed 258, orphaned 0, synrecv 0, timewait 257/0), ports 0

Transport Total     IP        IPv6
*      359       -         -        
RAW      0         0         0        
UDP      12        6         6        
TCP      36        18        18       
INET      48        24        24       
FRAG      0         0         0        

              total        used        free      shared  buff/cache   available
Mem:             15           4           0           0          10          10
Swap:             0           0           0

由上圖可知tcp鏈接數爲36 內存使用4G

 

Haproxy TCP端口耗盡解決方案

實際使用過程當中的問題:

  • TCP端口耗盡
  • 網卡帶寬跑滿

 

優化一:使用盡量多的端口

Linux系統默認提供了65K個端口,每當Haproxy創建了一個到MySQL的鏈接,就會消耗一個端口;當Haproxy斷開和MySQL的鏈接時,該端口並不會當即釋放,而是會處於TIME_WAIT狀態(2*MSL),超時後纔會釋放此端口供新的鏈接使用。
tcp_fin_timeout爲15秒,也就是說若是環境中的haproxy能夠承載的最大併發鏈接數爲64K/(15*2)=2.1K,可實際上達不到這個上限,緣由以下:

net.ipv4.ip_local_port_range = 15000 65000

linux會保留一段端口,實際能參與分配的端口數只有50K,爲了得到儘量多的可分配端口,作以下調整:

# sysctl net.ipv4.ip_local_port_range="1025 65000"
# sysctl net.ipv4.ip_local_port_range="1025 65000"

#記得修改/etc/sysctl.conf中對應的內容

 

優化二:複用處於TIME_WAIT的端口

 

調整兩個參數:

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1 

第一個參數很安全,能夠不用過多關注。須要注意的是第二個參數,某些狀況下會致使數據包被丟棄
例如:client經過NAT鏈接haproxy,而且haproxy端打開了tcp_tw_recycle,同時saw_tstamp也沒有關閉,當第一個鏈接創建並關閉後,此端口(句柄)處於TIME_WAIT狀態,在2*MSL時間內又一個client(相同IP,若是打開了xfrm還要相同PORT)發一個syn包,此時linux內核就會認爲這個數據包異常,從而丟掉這個包,併發送rst包.
不過一般狀況下,client都是經過內網直接鏈接haproxy,因此能夠認爲tcp_tw_recycle是安全的,只是須要記住此坑。

 

優化三:縮短TIME_WAIT時間

Linux系統默認MSL爲60秒,也就是正常狀況下,120秒後處於TIME_WAIT的端口(句柄)纔會釋放,能夠將MSL的時間縮小,縮短端口的釋放週期。

# cat /proc/sys/net/ipv4/tcp_fin_timeout
60
# echo 15 > /proc/sys/net/ipv4/tcp_fin_timeout
#這是一個折中的數值,過小也會致使其它問題

 

優化四:使用多IP

如優化一中所說,咱們已經儘量多的使用了系統提供的端口範圍。但最多依然不超過65K。
Haproxy提供了內建的端口管理方法,能夠充分利用以擴大咱們的端口範圍。

server mysql0     10.0.3.1:3306 check source 10.0.3.100:1025-65000
server mysql1     10.0.3.1:3306 check source 10.0.3.101:1025-65000

若是使用兩個ip,咱們可用的端口數就接近130K。擴展多個IP,就能夠不斷增長端口數。

相關文章
相關標籤/搜索