參考:http://www.iyunv.com/thread-252539-1-1.html
負載均衡介紹
四層和七層負載均衡的區別 四層
所謂的四層就是ISO參考模型中的第四層。四層負載均衡也稱為四層交換機,它主要是 通過分析IP層及TCP/UDP層的流量實現的基於IP加端口的負載均衡。常見的基於四層的負載均衡器有LVS、F5等。 以常見的TCP應用為例,負載均衡器在接收到第一個來自客戶端的SYN請求時,會通過設定的負載均衡算法選擇一個最佳的后端服務器,同時將報文中目標IP地址修改為后端服務器IP,然后直接轉發給該后端服務器,這樣一個負載均衡請求就完成了。
從這個過程來看,一個TCP連接是客戶端和服務器直接建立的,而負載均衡器只不過完成了一個類似路由器的轉發動作。在某些負載均衡策略中,為保證后端服務器返回的報文可以正確傳遞給負載均衡器,在轉發報文的同時可能還會對報文原來的源地址進行修改。
七層 同理,七層負載均衡器也稱為七層交換機,位於 OSI 的最高層,即應用層,此時負載均衡器支持多種應用協議,常見的有 HTTP、FTP、SMTP 等。七層負載均衡器可以根據報文內容,再配合負載均衡算法來選擇后端服務器,因此也稱為“內容交換器”。
比如,對於 Web 服務器的負載均衡,七層負載均衡器不但可以根據“IP+端口”的方式進行負載分流,還可以根據網站的 URL、訪問域名、瀏覽器類別、語言等決定負載均衡的策略。
例如,有兩台 Web 服務器分別對應中英文兩個網站,兩個域名分別是 A、B,要實現訪問 A 域名時進入中文網站,訪問 B 域名時進入英文網站,這在四層負載均衡器中幾乎是無法實現的,而七層負 載均衡可以根據客戶端訪問域名的不同選擇對應的網頁進行負載均衡處理。
常見的七層負載均衡器有 HAproxy、Nginx 等。 HAProxy支持兩種主要的代理模式: TCP 即4層 (大多用於郵件服務器、內部協議通信服務器等)。在4層模式 下,HAProxy僅在客戶端和服務器之間轉發雙向流量。 HTTP 即7層模式,HAProxy會分析協議,並且能通過允許、拒絕、交換、增加、修改或者***請求 (request)或者回應(response)里指定內容來控制協議,
這種操作要基於特定規則。(新的1.3之后的版本引入了frontend,backend指令;frontend根據任意HTTP請求頭內容做規則匹配,然后把請求定向到相關的backend.) 這里仍以常見的TCP應用為例,由於負載均衡器要獲取到報文的內容,因此只能先代替后端服務器和客戶端建立連接,接着,才能收到客戶端發送過來的報文內容,然后再根據該報文中特定字段加上負載均衡器中設置的負載均衡算法來決定最終選擇的內部服務器。
縱觀 整個過程,七層負載均衡器在這種情況下類似於一個代理服務器。整個過程如下圖所示。
對比四層負載均衡和七層負載均衡運行的整個過程,可以看出,
七層負載均衡模式下,負載均衡器與客戶端及后端的服務器會分別建立一次TCP連接
四層負載均衡模式下, 僅建立一次TCP連接。
由此可知,七層負載均衡對負載均衡設備的要求更高,而七層負載均 衡的處理能力也必然低於四層模式的負載均衡。 HAProxy與LVS的異同 下面就這兩種負載均衡軟件的異同做一個簡單總結: 1)兩者都是軟件負載均衡產品,但是LVS是基於Linux操作系統內核實現的一種軟負載均衡,而HAProxy是基於第三應用實現的軟負載均衡。 2)LVS是基於四層的IP負載均衡技術,而HAProxy是基於四層和七層技術、可提供TCP和HTTP應用的負載均衡綜合解決方案。 3)LVS工作在ISO模型的第四層,因此其狀態監測功能單一,而HAProxy在狀態監測方面功能強大,可支持端口、URL、腳本等多種狀態檢測方式。 4)HAProxy雖然功能強大,但是整體處理性能低於四層模式的LVS負載均衡,而LVS擁有接近硬件設備的網絡吞吐和連接負載能力。 綜上所述,HAProxy和LVS各有優缺點,沒有好壞之分,要選擇哪個作為負載均衡器,要以實際的應用環境來決定。
HAProxy主要在於它有以下優點,總結如下: 1、HAProxy是支持虛擬主機的,通過frontend指令來實現 2、能夠補充Nginx的一些缺點比如Session的保持,Cookie的引導等工作 3、支持url檢測后端的服務器出問題的檢測會有很好的幫助。 4、它跟LVS一樣,本身僅僅就只是一款負載均衡軟件;單純從效率上來講HAProxy更會比Nginx有更出色的負載均衡速度,在並發處理上也是優於Nginx的。 5、HAProxy可以對Mysql讀進行負載均衡,對后端的MySQL節點進行檢測和負載均衡,不過在后端的MySQL slaves數量超過10台時性能不如LVS,所以向大家推薦LVS+Keepalived。 6、能對請求的url和header中的信息做匹配,有比lvs有更好的7層實現
安裝HAProxy
可以在HAProxy的官網http://www.haproxy.org/下載HAProxy的源碼包,這里以操作系統Centos6.6 X64版本為例,下載的HAProxy是haproxy-1.6.9.tar.gz,安裝過程如 下:
#tar -zxvf haproxy-1.6.9.tar.gz
#cd haproxy-1.6.9
#make TARGET=linux26 PREFIX=/usr/local/haproxy #此處TARGET=linux26是填寫系統內核版本 uname -r ,如版本是2.6.32-504.el6.x86_64, 直接填寫26即可。
#make install PREFIX=/usr/local/haproxy
#ls /usr/local/haproxy/
doc sbin share
創建配置文件目錄及log目錄(pid文件)
#mkdir /usr/local/haproxy/conf
#mkdir /usr/local/haproxy/log
#cp examples/option-http_proxy.cfg /usr/local/haproxy/conf/haproxy.cfg
#haproxy安裝完成后,默認安裝目錄中沒有配置文件,這里是將源碼包里面的示例配置文件拷貝到配置文件目錄
這樣,HAProxy就安裝完成了。
haproxy配置詳解 http://cbonte.github.io/haproxy-dconv/1.6/configuration.html#4.2
HAProxy配置中分五大部分:
global: 全局配置參數,進程級的,用來控制Haproxy啟動前的一些進程及系統設置
defaults: 配置一些默認的參數,可以被frontend,backend,listen段繼承使用
frontend: 用來匹配接收客戶所請求的域名,uri等,並針對不同的匹配,做不同的請求處理
backend: 定義后端服務器集群,以及對后端服務器的一些權重、隊列、連接數等選項的設置,我將其理解為Nginx中的upstream塊
listen: frontend和backend的組合體
global maxconn 4096
# 定義每個haproxy進程的最大連接數 ,由於每個連接包括一個客戶端和一個服務器端,所以單個進程的TCP會話最大數目將是該值的兩倍
chroot /usr/local/haproxy
#修改haproxy的工作目錄至指定目錄並在放棄權限前執行chroot()操作,可以提升haproxy安全級別,
#
user nobody
group nobody
#設置運行haproxy的用戶和組,也可使用uid,gid關鍵字替代之,可以創建haproxy用戶
daemon
#以守護進程的方式運行
nbproc 1
# 設置haproxy啟動時的進程數,根據官方文檔的解釋,我將其理解為:該值的設置應該和服務器的CPU核心數一致,即常見的2顆8核心CPU的服務器,即共有16核心,
#則可以將其值設置為:<=16 ,創建多個進程數,可以減少每個進程的任務隊列,但是過多的進程數也可能會導致進程的崩潰。這里我設置為16
pidfile /usr/local/haproxy/logs/haproxy.pid
# 定義haproxy的pid
log 127.0.0.1 local0 info
# log語法:log [max_level_1]
# 全局的日志配置,使用log關鍵字,指定使用127.0.0.1上的syslog服務中的local0日志設備,記錄日志等級為info的日志
#ulimit -n 65536
# 設置最大打開的文件描述符數,在1.4的官方文檔中提示,該值會自動計算,所以不建議進行設置
時間格式,默認為毫秒
us 微秒1/1000000秒
ms 毫秒1/1000秒
s 秒
m 分鍾
h 小時
d 天
defaults (類似common)
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 stopped.]”,日志格式很簡單。
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替代。該參數向后兼容
option forwardfor except 127.0.0.0/8
frontend front_www_server bind *:80
#http_80_in定義前端部分監聽的套接字 vip,可以bind ip:80 mode http
#定義為HTTP模式 option httplog
# 啟用日志記錄HTTP請求,默認haproxy日志記錄是不記錄HTTP請求的,只記錄“時間[Jan 5 13:23:46] 日志服務器[127.0.0.1] 實例名已經pid[haproxy[25218]] 信息[Proxy http_80_in stopped.]”,日志格式很簡單。可加到default模塊 option forwardfor
# 啟用X-Forwarded-For,在requests頭部插入客戶端IP發送給后端的server,使后端server獲取到客戶端的真實IP option httpclose
#這個參數我是這樣理解的:使用該參數,每處理完一個request時,haproxy都會去檢查http頭中的Connection的值,如果該值不是close,haproxy將會將其***,如果該值為空將會添加為:Connection: close。
#使每個客戶端和服務器端在完成一次傳輸后都會主動關閉TCP連接。與該參數類似的另外一個參數是“option forceclose”,該參數的作用是強制關閉對外的服務通道,因為有的服務器端收到Connection: close時,
#也不會自動關閉TCP連接,如果客戶端也不關閉,連接就會一直處於打開,直到超時。 log global
#繼承global中log的定義 option dontlognull
# 啟用該項,日志中將不會記錄空連接。所謂空連接就是在上游的負載均衡器或者監控系統為了探測該服務是否存活可用時,需要定期的連接或者獲取某一固定的組件或頁面,或者探測掃描端口是否在監聽或開放等動作被稱為空連接;
#官方文檔中標注,如果該服務上游沒有其他的負載均衡器的話,建議不要使用該參數,因為互聯網上的惡意掃描或其他動作就不會被記錄下來
default_backend www_server
#acl host_wwwhdr_dom(host) -i www.zb.com #acl host_imghdr_dom(host) -i img.zb.com #use_backendhtmpool if host_www #use_backendimgpool if host_img ==========可選配參數 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 ==========
frontend front_www_server
bind *:80
mode http
option httplog
option forwardfor
option httpclose
log global
option dontlognull
default_backend www_server
backend back_www_server mode http
#設置為http模式 option redispatch
# 當使用了cookie時,haproxy將會將其請求的后端服務器的serverID插入到cookie中,以保證會話的SESSION持久性;而此時,如果后端的服務器宕掉了,但是客戶端的cookie是不會刷新的,如果設置此參數,將會將客戶的請求強制定向到另外一個后端server上,以保證服務的正常,可定義到default模塊 option abortonclose
# 當服務器負載很高的時候,自動結束掉當前隊列處理比較久的鏈接 balance static-rr
# 設置haproxy的調度算法為源地址static-rr cookie SERVERID
#允許向cookie插入SERVERID,每台服務器的SERVERID可在下面用cookie關鍵字定義 option httpchk GET /index.html
# 開啟對后端服務器的健康檢測,通過GET /test/index.php來判斷后端服務器的健康情況option httpchk HEAD / HTTP/1.0也可以,但是日志好像有點多啊
server node81 192.168.0.81:80 [cookie server1] weight 6 check inter 2000 rise 2 fall 3 server node82 192.168.0.82:80 [cookie server2] weight 3 check inter 2000 rise 2 fall 3
=================================================== 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 imgpool mode http option redispatch option abortonclose balance static-rr cookie SERVERID option httpchk GET /index.jsp server host236 192.168.81.236:8080 cookie server1 weight 6 check inter 2000 rise 2 fall 3
listen admin_stats # 定義一個名為status的部分,可以在listen指令指定的區域中定義匹配規則和后端服務器ip,相當於需要在其中配置frontend,backend的功能。一般做tcp轉發比較合適,不用太多的規則匹配 bind 0.0.0.0:9188 # 定義監聽的套接字 mode http # 定義為HTTP模式 log 127.0.0.1 local0 err #定義log stats refresh 30s # stats是haproxy的一個統計頁面的套接字,該參數設置統計頁面的刷新間隔為30s stats uri /haproxy-status # 設置統計頁面的uri為/haproxy-status stats realm welcome login\ Haproxy # 設置統計頁面認證時的提示內容stats realm Private lands stats auth admin:admin~!@ # 設置統計頁面認證的用戶和密碼,如果要設置多個,另起一行寫入即可stats auth admin:password stats hide-version # 隱藏統計頁面上的haproxy版本信息 stats admin if TRUE
http://ip:9188/haproxy-status
===================日志配置 # vi /etc/rsyslog.conf 取消注釋,增加一條 # Provides UDP syslog reception $ModLoad imudp $UDPServerRun 514 local0.* /usr/local/haproxy/logs/haproxy.log (對后端的訪問日志也在) # vi /etc/sysconfig/rsyslog SYSLOGD_OPTIONS="-r -m 0 -c 2" ===================日志配置
啟動與測試haproxy的負載均衡功能 1、啟動與管理haproxy 啟動服務: # /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.cfg 重啟服務: # /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.cfg -st `cat /usr/local/haproxy/log/haproxy.pid` 停止服務: # killall haproxy
HAProxy負載均衡器算法 1、HAProxy支持的負載均衡算法 roundrobin,表示簡單的輪詢,基於權重負載均衡基礎算法(支持慢速啟動,運行時調整)
server node81 192.168.0.81:80 check weight 3
server node82 192.168.0.82:80 check weight 1 static-rr,表示根據權重 leastconn,表示最少連接者先處理(不適用web) source,表示根據請求源IP(會話保持,此方法動靜還要取決於hash-type,map-based靜態,consistent動態) uri,表示根據請求的URI;(用於緩存服務器) url_param,表示根據請求的URl參數來進行調度 hdr(name),表示根據HTTP請求頭來鎖定每一次HTTP請求; rdp-cookie(name),表示根據據cookie(name)來鎖定並哈希每一次TCP請求。 2、集群中的session處理 session保持 session復制 session共享
通過HAProxy的ACL規則實現智能負載均衡 由於HAProxy可以工作在七層模型下,因此,要實現HAProxy的強大功能,一定要使用強大靈活的ACL規則,通過ACL規則可以實現基於HAProxy的智能負載均衡系統。 HAProxy 通過ACL規則完成兩種主要的功能,分別是: 1)通過設置的ACL規則檢查客戶端請求是否合法。如果符合ACL規則要求,那么就將放行,反正,如果不符合規則,則直接中斷請求. 2)符合ACL規則要求的請求將被提交到后端的backend服務器集群,進而實現基於ACL規則的負載均衡。 HAProxy中的ACL規則經常使用在frontend段中,使用方法如下: acl 自定義的acl名稱 acl方法 -i [匹配的路徑或文件] 其中: acl:是一個關鍵字,表示定義ACL規則的開始。后面需要跟上自定義的ACL名稱。 acl方法:這個字段用來定義實現ACL的方法,HAProxy定義了很多ACL方法,經常使用的方法有hdr_reg(host)、hdr_dom(host)、hdr_beg(host)、url_sub、url_dir、 path_beg、path_end等。 -i:表示忽略大小寫,后面需要跟上匹配的路徑或文件或正則表達式。 與ACL規則一起使用的HAProxy參數還有use_backend,use_backend后面需要跟上一個backend實例名,表示在滿足ACL規則后去請求哪個backend實例,與 use_backend對應的還有default_backend參數,它表示在沒有滿足ACL條件的時候默認使用哪個后端backend。 下面列舉幾個常見的ACL規則例子: acl www_policy hdr_reg(host) -i ^(www.z.cn|z.cn) acl bbs_policy hdr_dom(host) -i bbs.z.cn acl url_policy url_sub -i buy_sid= use_backend server_www if www_policy use_backend server_app if url_policy use_backend server_bbs if bbs_policy default_backend server_cache
使用socat工具在線管理haproxy Unix Socket command sroot@test86 ~]# yum install -y socat [root@test86 conf]# vi haproxy.cfg global stats socket /var/run/haproxy.sock mode 600 level admin stats timeout 2m 重啟服務: # /usr/local/haproxy/sbin/haproxy -f /usr/local/haproxy/conf/haproxy.cfg -st `cat /usr/local/haproxy/logs/haproxy.pid` To access the socket, an external utility such as "socat" is required. Socat is a swiss-army knife to connect anything to anything. We use it to connect terminals to the socket, or a couple of stdin/stdout pipes to it for scripts. The two main syntaxes we'll use are the following : # socat /var/run/haproxy.sock stdio # socat /var/run/haproxy.sock readline [root@test86 conf]# echo "help" | socat /var/run/haproxy.sock stdio clear counters : clear max statistics counters (add 'all' for all counters) clear table : remove an entry from a table help : this message prompt : toggle interactive mode with prompt quit : disconnect show backend : list backends in the current running config show info : report information about the running process show pools : report information about the memory pools usage show stat : report counters for each proxy and server show stat resolvers [id]: dumps counters from all resolvers section and associated name servers show errors : report last request and response errors for each proxy show sess [id] : report the list of current sessions or dump this session show table [id]: report table usage stats or dump this table's contents show servers state [id]: dump volatile server information (for backend <id>) get weight : report a server's current weight set weight : change a server's weight set server : change a server's state, weight or address set table [id] : update or create a table entry's data set timeout : change a timeout setting set maxconn : change a maxconn setting set rate-limit : change a rate limiting value disable : put a server or frontend in maintenance mode enable : re-enable a server or frontend which is in maintenance mode [root@test86 conf]# echo "disable server htmpool/237server " | socat /var/run/haproxy.sock stdio [root@test86 conf]# echo "enable server htmpool/237server " | socat /var/run/haproxy.sock stdio shutdown : kill a session or a frontend (eg:to release listening ports) show acl [id] : report available acls or dump an acl's contents get acl : reports the patterns matching a sample for an ACL add acl : add acl entry del acl : delete acl entry clear acl <id> : clear the content of this acl show map [id] : report available maps or dump a map's contents get map : reports the keys and values matching a sample for a map set map : modify map entry add map : add map entry del map : delete map entry clear map <id> : clear the content of this map set ssl <stmt> : set statement for ssl


