Haproxy介紹
- Haproxy 是一款提供高可用性、負載均衡以及基于TCP(第四層)和HTTP(第七層)應用的代理軟件,支持虛擬主機,它是免費、快速并且可靠的一種解決方案。 HAProxy特別適用于那些負載特大的web站點,這些站點通常又需要會話保持或七層處理。HAProxy運行在時下的硬件上,完全可以支持數以萬計的 并發連接。并且它的運行模式使得它可以很簡單安全的整合進您當前的架構中, 同時可以保護你的web服務器不被暴露到網絡上。
- Haproxy 實現了一種事件驅動、單一進程模型,此模型支持非常大的并發連接數。多進程或多線程模型受內存限制 、系統調度器限制以及無處不在的鎖限制,很少能處理數千并發連接。事件驅動模型因為在有更好的資源和時間管理的用戶端(User-Space) 實現所有這些任務,所以沒有這些問題。此模型的弊端是,在多核系統上,這些程序通常擴展性較差。這就是為什么他們必須進行優化以 使每個CPU時間片(Cycle)做更多的工作。
- Haproxy 支持連接拒絕 : 因為維護一個連接的打開的開銷是很低的,有時我們很需要限制攻擊蠕蟲(attack bots),也就是說限制它們的連接打開從而限制它們的危害。 這個已經為一個陷于小型DDoS攻擊的網站開發了而且已經拯救
- 了很多站點,這個優點也是其它負載均衡器沒有的。
- Haproxy 支持全透明代理(已具備硬件防火墻的典型特點): 可以用客戶端IP地址或者任何其他地址來連接后端服務器. 這個特性僅在Linux?2.4/2.6內核打了cttproxy補丁后才可以使用. 這個特性也使得為某特殊服務器處理部分流量同時又不修改服務器的地址成為可能。
性能:HAProxy借助于OS上幾種常見的技術來實現性能的最大化。
- 1,單進程、事件驅動模型顯著降低了上下文切換的開銷及內存占用。
- 2,事件檢查器(event checker)允許其在高并發連接中對任何連接的任何事件實現即時探測。
- 3,在任何可用的情況下,單緩沖(single buffering)機制能以不復制任何數據的方式完成讀寫操作,這會節約大量的CPU時鐘周期及內存帶寬;
- 4,借助于Linux 2.6 (>= 2.6.27.19)上的splice()系統調用,HAProxy可以實現零復制轉發(Zero-copy forwarding),在Linux 3.5及以上的OS中還可以實現零復制啟動(zero-starting);
- 5,內存分配器在固定大小的內存池中可實現即時內存分配,這能夠顯著減少創建一個會話的時長;
- 6,樹型存儲:側重于使用作者多年前開發的彈性二叉樹,實現了以O(log(N))的低開銷來保持計時器命令、保持運行隊列命令及管理輪詢及最少連接隊列;
- 7,優化的HTTP首部分析:優化的首部分析功能避免了在HTTP首部分析過程中重讀任何內存區域;
- 8,精心地降低了昂貴的系統調用,大部分工作都在用戶空間完成,如時間讀取、緩沖聚合及文件描述符的啟用和禁用等;
- 所有的這些細微之處的優化實現了在中等規模負載之上依然有著相當低的CPU負載,甚至于在非常高的負載場景中,5%的用戶空間占用率和95%的系統空間占用率也是非常普遍的現象,這意味著HAProxy進程消耗比系統空間消耗低20倍以上。因此,對OS進行性能調優是非常重要的。即使用戶空間的占用率提高一倍,其CPU占用率也僅為10%,這也解釋了為何7層處理對性能影響有限這一現象。由此,在高端系統上HAProxy的7層性能可輕易超過硬件負載均衡設備。
- 在生產環境中,在7層處理上使用HAProxy作為昂貴的高端硬件負載均衡設備故障故障時的緊急解決方案也時長可見。硬件負載均衡設備在“報文”級別處理請求,這在支持跨報文請求(request across multiple packets)有著較高的難度,并且它們不緩沖任何數據,因此有著較長的響應時間。對應地,軟件負載均衡設備使用TCP緩沖,可建立極長的請求,且有著較大的響應時間。
- HAProxy目前主要有三個版本: 1.3 , 1.4 ,1.5,CentOS6.6 自帶的RPM包為 1.5 的。
1.1 搭建Haproy
[root@haproxy ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) [root@haproxy ~]# systemctl stop firewalld [root@haproxy ~]# getenforce Disabled [root@haproxy ~]# yum install -y haproxy [root@haproxy ~]# haproxy -v HA-Proxy version 1.5.18 2016/05/10 Copyright 2000-2016 Willy Tarreau <willy@haproxy.org>
?
?1.2? 修改/etc/haproxy/haproxy.cfg
global # 全局參數的設置 log 127.0.0.1 local0 info # log語法:log <address_1>[max_level_1] # 全局的日志配置,使用log關鍵字,指定使用127.0.0.1上的syslog服務中的local0日志設備,記錄日志等級為info的日志 user haproxy group haproxy # 設置運行haproxy的用戶和組,也可使用uid,gid關鍵字替代之 daemon # 以守護進程的方式運行 nbproc 16 # 設置haproxy啟動時的進程數,根據官方文檔的解釋,我將其理解為:該值的設置應該和服務器的CPU核心數一致,即常見的2顆8核心CPU的服務器,即共有16核心,則可以將其值設置為:<=16 ,創建多個進程數,可以減少每個進程的任務隊列,但是過多的進程數也可能會導致進程的崩潰。這里我設置為16 maxconn 4096 # 定義每個haproxy進程的最大連接數 ,由于每個連接包括一個客戶端和一個服務器端,所以單個進程的TCP會話最大數目將是該值的兩倍。 #ulimit -n 65536 # 設置最大打開的文件描述符數,在1.4的官方文檔中提示,該值會自動計算,所以不建議進行設置 pidfile /var/run/haproxy.pid # 定義haproxy的pid defaults # 默認部分的定義 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替代。該參數向后兼容 listen status # 定義一個名為status的部分 bind 0.0.0.0:1080 # 定義監聽的套接字 mode http # 定義為HTTP模式 log global # 繼承global中log的定義 stats refresh 30s # stats是haproxy的一個統計頁面的套接字,該參數設置統計頁面的刷新間隔為30s stats uri /admin?stats # 設置統計頁面的uri為/admin?stats stats realm Private lands # 設置統計頁面認證時的提示內容 stats auth admin:password # 設置統計頁面認證的用戶和密碼,如果要設置多個,另起一行寫入即可 stats hide-version # 隱藏統計頁面上的haproxy版本信息 frontend http_80_in # 定義一個名為http_80_in的前端部分 bind 0.0.0.0:80 # http_80_in定義前端部分監聽的套接字 mode http # 定義為HTTP模式 log global # 繼承global中log的定義 option forwardfor # 啟用X-Forwarded-For,在requests頭部插入客戶端IP發送給后端的server,使后端server獲取到客戶端的真實IP 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 backend php_server #定義一個名為php_server的后端部分 mode http # 設置為http模式 balance source # 設置haproxy的調度算法為源地址hash cookie SERVERID # 允許向cookie插入SERVERID,每臺服務器的SERVERID可在下面使用cookie關鍵字定義 option httpchk GET /test/index.php # 開啟對后端服務器的健康檢測,通過GET /test/index.php來判斷后端服務器的健康情況 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 static_server mode http option httpchk GET /test/index.html server static_server_1 10.12.25.83:80 cookie 3 check inter 2000 rise 3 fall 3
?