參考:http://www.iyunv.com/thread-252539-1-1.htmlphp
負載均衡介紹css
四層和七層負載均衡的區別 四層
所謂的四層就是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.2html
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請求。 二、集羣中的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