1、Haproxy概述;
2、Haproxy原理實現;
3、Nginx、LVS、Haproxy對比;
4、Haproxy配置文件講解;
5、案例:Haproxy+Nginx+Tomcat搭建高可用集羣;css
概述:Haproxy是一個開源的高性能的反向代理或者說是負載均衡服務軟件之一,由C語言編寫而成,支持會話保持、七層處理、健康檢查、故障修復後自動加載、動靜分離。HAProxy運行在當前的硬件上,徹底能夠支持數以萬計的併發鏈接;
Haproxy軟件引入了frontend,backend的功能,frontend(acl規則匹配)能夠運維管理人員根據任意HTTP請求頭作規則匹配,而後把請求定向到相關的backend(server pools等待前端把請求轉過來的服務器組)。html
代理模式:
1.四層tcp代理:例如:可用於郵件服務內部協議通訊服務器、Mysql服務等;
2.七層應用代理:例如:HTTP代理或https代理。在4層tcp代理模式下,Haproxy僅在客戶端和服務器之間雙向轉發流量。可是在7層模式下Haproxy會分析應用層協議,而且能經過運行、拒絕、交換、增長、修改或者刪除請求(request)或者回應(reponse)裏指定內容來控制協議。
四層代理:
ISO參考模型中的第四層傳輸層。四層負載均衡也稱爲四層交換機,它主要是經過分析IP層及TCP/UDP層的流量實現的基於IP加端口的負載均衡。常見的基於四層的負載均衡器有LVS、F5等。以常見的TCP應用爲例,負載均衡器在接收到第一個來自客戶端的SYN請求時,會經過設定的負載均衡算法選擇一個最佳的後端服務器,同時將報文中目標IP地址修改成後端服務器IP,而後直接轉發給該後端服務器,這樣一個負載均衡請求就完成了。從這個過程來看,一個TCP鏈接是客戶端和服務器直接創建的,而負載均衡器只不過完成了一個相似路由器的轉發動做。在某些負載均衡策略中,爲保證後端服務器返回的報文能夠正確傳遞給負載均衡器,在轉發報文的同時可能還會對報文原來的源地址進行修改。整個過程下圖所示。
七層代理:
ISO參考模型中的最高層第七層應用層。七層負載均衡也稱爲七層交換機,此時負載均衡器支持多種應用協議,常見的有HTTP、FTP、SMTP等。七層負載均衡器能夠根據報文內容,再配合負載均衡算法來選擇後端服務器,所以也稱爲「內容交換器」。好比,對於Web服務器的負載均衡,七層負載均衡器不但能夠根據「IP+端口」的方式進行負載分流,還能夠根據網站的URL、訪問域名、瀏覽器類別、語言等決定負載均衡的策略。例如,有兩臺Web服務器分別對應中英文兩個網站,兩個域名分別是A、B,要實現訪問A域名時進入中文網站,訪問B域名時進入英文網站,這在四層負載均衡器中幾乎是沒法實現的,而七層負載均衡能夠根據客戶端訪問域名的不一樣選擇對應的網頁進行負載均衡處理。常見的七層負載均衡器有HAproxy、Nginx等。
這裏仍以常見的TCP應用爲例,因爲負載均衡器要獲取到報文的內容,所以只能先代替後端服務器和客戶端創建鏈接,接着,才能收到客戶端發送過來的報文內容,而後再根據該報文中特定字段加上負載均衡器中設置的負載均衡算法來決定最終選擇的內部服務器。縱觀整個過程,七層負載均衡器在這種狀況下相似於一個代理服務器。整個過程以下圖所示。
調度算法:
balance roundrobin:表示簡單的輪詢,負載均衡基礎算法
balance static-rr:表示根據權重
balance leastconn:表示最少鏈接者先處理
balance source:表示根據請求源IP
balance uri:表示根據請求的URI;
balance url_param:表示根據請求的URl參數來進行調度
balance hdr(name):表示根據HTTP請求頭來鎖定每一次HTTP請求;
balance rdp-cookie(name):表示根據據cookie(name)來鎖定並哈希每一次TCP請求。前端
總結:
大型網站架構:對性能有嚴格要求的時候可使用lvs或者硬件F5,就單純從負載均衡的角度來講,lvs也許會成爲主流,更適合如今大型的互聯網公司;
中型網站架構:對於頁面分離請求由明確規定,而且性能有嚴格要求時,可使用haproxy;
中小型網站架構:好比日 PV 小於1000萬,須要進行高併發的網站或者對網絡不太嚴格的時候,可使用nginx;java
global:全局配置區域參數是進程級的,一般是和操做系統相關。這些參數通常只設置一次,若是配置無誤,就不須要再次進行修改;
linux
defaults:配置默認參數,這些參數能夠被用到frontend,backend,Listen組件;
nginx
frontend:處理請求的虛擬節點,Frontend能夠將匹配到本地區域的請求交給下邊的backend;
backend:後端服務集羣的配置,是真實服務器,一個Backend對應一個或者多個實體服務器;web
配置文件樣例:正則表達式
案例拓撲:
算法
案例步驟:
搭建並配置nginx節點,準備網頁,啓動服務,測試節點(兩臺nginx配置相同,在此列出一臺的配置);
搭建並配置tomcat節點,準備網頁,啓動服務,測試節點(兩臺tomcat配置相同,在此列出一臺的配置);
安裝Haproxy程序軟件;
配置Haproxy服務;
啓動Haproxy服務;
客戶端訪問測試驗證集羣;
將Haproxy的日誌文件分離(便於查看);
配置Haproxy服務的日誌管理界面;
客戶端訪問測試Haproxy的日誌管理界面;sql
搭建並配置nginx節點,準備網頁,啓動服務,測試節點(兩臺nginx配置相同,在此列出一臺的配置); [root@ng1 ~]# yum -y install pcre-devel zlib-devel [root@ng1 ~]# useradd -M -s /sbin/nologin nginx [root@ng1 ~]# tar zxvf nginx-1.12.2.tar.gz -C /usr/src/ [root@ng1 ~]# cd /usr/src/nginx-1.12.2/ [root@ng1 nginx-1.12.2]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module [root@ng1 nginx-1.12.2]# make && make install [root@ng1 nginx-1.12.2]# cd [root@ng1 ~]# ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/ [root@ng1 ~]# vi /usr/lib/systemd/system/nginx.service [Unit] Description=nginxapi After=network.target [Service] Type=forking PIDFile=/usr/local/nginx/logs/nginx.pid ExecStart=/usr/local/nginx/sbin/nginx ExecReload=kill -s HUP $(cat /usr/local/nginx/logs/nginx.pid) ExecStop=kill -s QUIT $(cat /usr/local/nginx/logs/nginx.pid) PrivateTmp=Flase [Install] WantedBy=multi-user.target [root@ng1 ~]# echo "192.168.100.102" >>/usr/local/nginx/html/index.html [root@ng1 ~]# systemctl start nginx [root@ng1 ~]# systemctl enable nginx [root@ng1 ~]# netstat -utpln |grep nginx tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 3538/nginx: master 搭建並配置tomcat節點,準備網頁,啓動服務,測試節點(兩臺tomcat配置相同,在此列出一臺的配置); [root@tm1 ~]# ls apache-tomcat-9.0.10.tar.gz jdk-8u171-linux-x64.tar.gz [root@tm1~]# rpm -qa |grep java [root@tm1 ~]# tar zxvf jdk-8u171-linux-x64.tar.gz [root@tm1 ~]# mv jdk1.8.0_171/ /usr/local/java [root@tm1 ~]# ls /usr/local/java bin db javafx-src.zip lib man release THIRDPARTYLICENSEREADME-JAVAFX.txt COPYRIGHT include jre LICENSE README.html src.zip THIRDPARTYLICENSEREADME.txt [root@tm1 ~]# cat <<END >>/etc/profile export JAVA_HOME=/usr/local/java export PATH=$PATH:/usr/local/java/bin END [root@tm1~]# source /etc/profile [root@tm1 ~]# java -version java version "1.8.0_171" Java(TM) SE Runtime Environment (build 1.8.0_171-b11) Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode) [root@tm1 ~]# tar zxvf apache-tomcat-9.0.10.tar.gz [root@tm1 ~]# mv apache-tomcat-9.0.10 /usr/local/tomcat [root@tm1 ~]# ls /usr/local/tomcat bin conf lib LICENSE logs NOTICE RELEASE-NOTES RUNNING.txt temp webapps work [root@tm1 ~]# vi /usr/local/tomcat/conf/server.xml 150 <Context docBase="/web/webapp" path="" reloadable="false"></Context> :wq [root@tm1 ~]# mkdir -p /web/webapp [root@tm1 ~]# vi /web/webapp/index.jsp <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <html> <head> <title>JSP TEST PAGE1 </title> </head> <body> <% out.println("Welcome to test site;http://192.168.100.104");%> </body> </html> [root@tm1 ~]# /usr/local/tomcat/bin/startup.sh ##啓動apache-tomcat [root@tm1 ~]# netstat -utpln |grep 8080 tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 14758/java 安裝Haproxy程序軟件; [root@ha ~]# yum -y install pcre-devel bzip2-devel ##安裝依賴軟件包 [root@ha ~]# tar zxvf haproxy-1.4.24.tar.gz -C /usr/src/ [root@ha ~]# cd /usr/src/haproxy-1.4.24/ [root@ha haproxy-1.4.24]# uname -r 3.10.0-693.5.2.el7.x86_64 [root@ha haproxy-1.4.24# make TARGET=linux310 ##make編譯,指定系統內核版本爲3.10 [root@ha haproxy-1.4.24]# make install [root@ha haproxy-1.4.24]# cd 配置Haproxy服務; [root@ha ~]# mkdir /etc/haproxy ##建立配置文件目錄 [root@ha ~]# cp /usr/src/haproxy-1.4.24/examples/haproxy.cfg /etc/haproxy/ [root@ha ~]# vi /etc/haproxy/haproxy.cfg ##修改主配置文件以下 global log 127.0.0.1 local0 info ##定義日誌級別; log 127.0.0.1 local1 notice maxconn 4096 ##設定每一個haproxy進程所接受的最大併發鏈接數 uid 99 ##指定運行服務的用戶和組 gid 99 daemon ##指定運行模式爲daemon,以守護進程的方式工做在後臺 defaults log global ##採起global中的日誌配置 mode http ##默認的模式mode { tcp|http|health },tcp是4層,http是7層,health只會返回OK option httplog ##採用http日誌格式記錄日誌 option dontlognull ##不記錄健康檢查的日誌記錄 option httpclose ##關閉保持鏈接 retries 3 ##檢查節點最多失敗次數 maxconn 2000 ##最大鏈接數,定義不得大於global中的值 contimeout 5000 ##鏈接超時時間,毫秒,在此期間,如若客戶端與服務端沒法成功創建鏈接,則斷掉 clitimeout 50000 ##設置鏈接客戶端發送數據時的成功鏈接最長等待時間,單位爲毫秒,如若在這期間沒法請求成功,則斷掉 srvtimeout 50000 ##設置服務器端迴應客戶端數據發送的最長等待時間,若是在這期間還沒法發送成功,則斷掉 ##################無分離頁面需求的配置############## #listen webcluster 0.0.0.0:80 ##指定haproxy服務監聽地址和端口 # option httpchk GET /index.html ##指定http請求方法和默認文件 # balance roundrobin ##指定輪詢調度算法 # server inst1 192.168.100.155:80 check inter 2000 fall 3 ##定義web節點,檢測心跳頻率,單位爲毫秒,定義檢查節點最多失敗次數 # server inst2 192.168.100.156:80 check inter 2000 fall 3 ##################有分離頁面需求的配置############## frontend http ##定義名稱爲http bind *:80 ##指定監聽地址和端口 acl linuxfan1 hdr_end(host) -i 192.168.100.101 ##指定類型爲訪問路徑的域名,-i不區分大小寫 acl linuxfan2 hdr_end(host) -i www.linuxfan.cn acl linuxfan3 path_end -i .jsp .do .css .js ##指定請求文件格式爲.jsp #acl linuxfan3 hdr_reg -i \.(css|png|jpg|jpeg|gif|ico|swf|xml|txt|pdf|do|jsp|js)$ ##調用正則表達式 acl linuxfan4 path_end -i .html .css .png .jpg .jpeg .xml ##指定請求文件格式爲.html acl linuxfan5 path_beg -i /WebRoot ##指定訪問URL中的路徑,如http://www.linuxfan.cn/WebRoot/index.jsp use_backend dongtai if linuxfan1 linuxfan3 use_backend dongtai if linuxfan2 linuxfan3 use_backend dongtai if linuxfan1 linuxfan5 linuxfan3 use_backend dongtai if linuxfan2 linuxfan5 linuxfan3 default_backend jingtai ##默認的請求使用backend dongtai backend jingtai ##定義backend :jingtai mode http ##定義模式 balance roundrobin ##定義調度算法爲輪詢 server jingtai01 192.168.100.102:80 check inter 2000 fall 3 ##定義節點 server jingtai02 192.168.100.103:80 check inter 2000 fall 3 backend dongtai mode http balance roundrobin server dongtai01 192.168.100.104:8080 check inter 2000 fall 3 server dongtai02 192.168.100.105:8080 check inter 2000 fall 3 啓動Haproxy服務; [root@ha ~]# cp /usr/src/haproxy-1.4.24/examples/haproxy.init /etc/init.d/haproxy [root@ha ~]# chmod +x /etc/init.d/haproxy [root@ha ~]# ln -s /usr/local/sbin/haproxy /usr/sbin/ [root@ha ~]# /etc/init.d/haproxy start [root@ha ~]# netstat -utpln |grep haproxy tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1264/haproxy udp 0 0 0.0.0.0:52177 0.0.0.0:* 1264/haproxy
客戶端訪問測試驗證集羣;
將Haproxy的日誌文件分離(便於查看); [root@ha ~]# vi /etc/rsyslog.conf 15 $ModLoad imudp 16 $UDPServerRun 514 ##打開此配置項的註釋,使rsyslog服務能夠接受udp協議514端口的系統日誌消息 74 local0.* /var/log/haproxy/ha-info.log 75 local1.* /var/log/haproxy/ha-notice.log ##在haproxy主配置文件中所指定的日誌設備和日誌級別將其輸出到不一樣的文件中,以方便查看; :wq [root@ha ~]# vi /etc/sysconfig/rsyslog SYSLOGD_OPTIONS="-r -m 0 -c 2" ##-r 接收udp 514號端口的系統日誌消息;-m 0 爲日誌消息添加時間等的標記 ;-c 2表示使用兼容模式 :wq [root@ha ~]# systemctl restart rsyslog [root@ha ~]# /etc/init.d/haproxy restart [root@ha ~]# tail -f /var/log/haproxy/ha-info.log Jul 27 18:14:44 localhost haproxy[1375]: 192.168.100.1:52965 [27/Jul/2018:18:14:44.167] http dongtai/dongtai01 0/0/0/2/3 200 349 - - ---- 0/0/0/0/0 0/0 "GET /index.jsp HTTP/1.1" 配置Haproxy服務的日誌管理界面; [root@ha ~]# vi /etc/haproxy/haproxy.cfg ###在後邊添加 listen status 0.0.0.0:8080 ##監控8080端口 stats enable ##開啓stats的模塊 stats uri /stats ##指定訪問的url stats auth admin:123456 ##指定登錄監控頁面的用戶名密碼 stats realm (Haproxy\ statistic) ##定義頁面的提示信息 [root@ha ~]# /etc/init.d/haproxy restart
客戶端訪問測試Haproxy的日誌管理界面;