HAProxy簡介:
HAProxy提供高可用性、負載均衡以及基於TCP和HTTP應用的代理,支持虛擬主機,它是一款開源的、快速並且可靠的反向代理的解決方案。HAProxy特別適用於那些負載特大的web站點,而這些站點通常又需要保持會話或七層處理(最常用的如動靜分離)。HAProxy運行在當前的硬件上,完全可以支持數以萬計的併發連接,並且它的運行模式使得它可以很簡單安全的整合進現有的架構中,同時可以保護後端的web服務器不被暴露在網絡上。
HAProxy使用的是事件驅動、單一進程模型,此模型支持非常大的併發連接數。多進程或多線程模型受內存限制、系統調度器限制以及鎖限制,很少能處理數千併發連接。事件驅動模型因爲在有更好的資源和時間管理的用戶端實現這些任務,所以沒有這些問題。
HAProxy特性:
HAProxy是開源、極速且可靠的用於爲TCP和基於HTTP應用程序提供高可用、負載均衡和代理服務的解決方案。
HAProxy目前有兩個主要版本:
1.4-提供較好的彈性,衍生於1.2版本,提供了額外的新特性:
支持客戶端一側的長連接(client-side keep-alive)
支持TCP加速(TCP speedups)
支持響應池(response buffering)
支持RDP協議
支持基於源的粘性(source-based stickiness)
支持更好的統計數據接口(a much better stats interfaces)
支持更詳細的健康狀態檢測機制(more verbose health checks)
支持基於流量的健康評估機制(traffic-based health)
支持基於HTTP認證
支持服務器管理命令行接口(server management from the CLI)
支持基於ACL的持久性(ACL-based persistence)
支持日誌分析器
1.3-內容交換和超強負載:衍生於1.2版本,並提供額外的新特性:
內容交換(content switching):基於任何請求標準挑選服務器池;
ACL:編寫內容交換規則;
負載均衡算法(load-balancing algorithms):更多的算法支持;
內容探測(content inspection):組織非授權協議;
透明代理(transparent proxy):在Linux系統上允許使用客戶端IP直接連入服務器;
內核TCP拼接(kernel TCP splicing):無copy方式在客戶端和服務器端之間轉發數據以實現數G級別的數據速率;
分層設計(layered design):分別實現套接字、TCP、HTTP處理以提供更好的健壯性、更快的處理機制以及更便捷的演進能力;
快速、公平調度器(fast and fair scheduler):爲某些任務指定優先級可實現更好的Qos;
會話速率限制(session rate limiting):適用於託管環境;
HAProxy的性能:
HAProxy有很好的性能是因爲它藉助於OS上幾種常見的技術來實現性能上的最大化:
1、單進程、事件驅動模型顯著降低了上下文切換的開銷以及內存佔用。
2、O(1)事件檢查器(event checker)允許其在高併發連接中對任何連接的任何事件實現即時探測。
3、在任何可用的情況下,單緩衝(single buffering)機制能以不復制任何數據的方式完成讀寫操作,這會節約大量的CPU時鐘週期及內存帶寬。
4、藉助於splice()系統調用,可以實現零複製轉發。
5、內存分配器在固定大小的內存池中可實現即時內存分配,能夠顯著減少創建一個會話的時長。
6、樹形存儲:使用彈性二叉樹,實現以O(log(N))的低開銷來保持計時器命令、保持運行隊列命令及管理輪詢及最少連接隊列。
7、優化的HTTP首部分析:優化的首部分析功能避免了在HTTP首部分析過程中重讀任何內存區域。
模擬實驗:
使用HAProxy實現將用戶請求按請求資源類型的不同調度至不同的服務器進行響應,通常資源的類型被分爲靜態資源和動態資源,實驗中實現的效果即動靜分離。
實驗環境:
三臺虛擬機:
node1:eth0:172.16.103.1(模擬爲外網IP),eth1:192.168.1.1(內網IP,與後端RealServer通信使用)
node2:eth0:192.168.1.2 (提供動態頁面內容)
node3:eth0:192.168.1.3 (提供靜態頁面內容)
實驗簡易拓撲:
實驗過程:
前端HAProxy代理服務器上安裝haproxy程序包
# yum -y install haproxy
爲了能在後端服務器均出現故障時,能提供提示性信息,在haproxy所在主機啓動httpd服務,並提供主頁文件,內容編輯爲:
# vim /etc/httpd/conf/httpd.conf
Listen 8080 #修改一個默認的監聽地址,與後端的RealServer不一致,因爲haproxy地址監聽的通常設置爲80,設置這個監聽地址的目的就是爲了避免在本機不同進程使用同一端口,而產生衝突。
# vim /var/www/html/index.html
<h1>Site under Maintaince</h1>
RS1主機提供動態頁面的訪問,安裝有httpd和php程序包並提供主頁文件
# yum -y install httpd php # vim /var/www/html/index.php <h1>php Page</h1> <?php phpinfo(); ?> # vim /var/www/html/index.html #爲了之後測試可以在node2這臺提供動態頁面訪問服務的主機上創建一個靜態頁面文件,與node3上的文件名稱相同,但內容不同,在訪問相同名稱的文件時,可以測試是否能始終將靜態內容調度到靜態內容服務器node3上。 # vim /var/www/html/index.html <h1>node2.cluster.com</h1>
RS2上僅提供靜態頁面內容,只安裝httpd程序
# yum -y install httpd # vim /var/www/html/index.html <h1>node3.cluster.com</h1>
配置前端的haproxy,使得用戶請求時,動態頁面內容調度至RS1,請求靜態內容時會調度到RS2,在配置文件中的添加如下內容:
frontend main #定義前端的haproxy工作特性 maxconn 6000 #支持的併發連接數 bind :80 #監聽的端口 acl url_static path_beg -i /p_w_picpaths /stylesheets /videos /css /javascript #定義訪問控制列表 acl url_static path_end -i .jpg .html .css .js .png .gif #定義訪問控制列表,以便在條件匹配時調用 use_backend static if url_static #調用之前定義的訪問控制列表,之前定義的訪問控制列表指定的內容是開頭以圖片,樣式表,視頻,css文件及java腳本開頭的和以.jpg.html等文件結尾的文件時會使用後端以static定義的服務器組。 default_backend webservers #定義默認的訪問調度服務器,用戶請求的資源部是acl定義的資源類型時,由默認的webserver響應 backend static balance roundrobin #使用的調度算法 server static1 192.168.1.3 check port 80 #提供靜態頁面內容的服務器定義在static組中 server b1 127.0.0.1:8080 backup check port 8080 backend webservers balance roundrobin server s1 192.168.1.2 check port 80 # 提供動態頁面內容的服務器定義在默認的服務器組中 server b1 127.0.0.1:8080 backup check port 8080 #定義了一個backup server,當後端的各RealServer都出現故障時,會使用haproxy所在的主機提供的web服務來響應,顯示服務器在維護中的信息。
啓動haproxy服務:
# service haproxy start
實現動靜分離時定義的效果:當訪問默認主頁時,使用默認的backend定義的webserver服務器響應,這個服務器上提供的是php頁面文件,也是動態頁面的內容:
多次刷新測試後訪問的還是同一個頁面的內容,如果訪問的是靜態文件的內容,比如index.html,即使在node2上有相同名稱的頁面文件,也不會調度到node2上,而是隻顯示node3上的文件:
實現了動態頁面和靜態頁面分離的效果。