1、簡(jiǎn)述四層和七層負(fù)載均衡的特點(diǎn)及Haproxy與LVS之間的對(duì)比
什么是四層負(fù)載均衡?
四層負(fù)載均衡指的是負(fù)載均衡設(shè)備通過(guò)報(bào)文中的目標(biāo)IP地址和端口負(fù)載均衡算法叽讳,選擇到達(dá)目的的內(nèi)部服務(wù)器追他,其主要工作在OSI七層模型的第四層(傳輸層)坟募。四層負(fù)載均衡對(duì)數(shù)據(jù)包只是起一個(gè)數(shù)據(jù)轉(zhuǎn)發(fā)的作用,并不會(huì)干預(yù)客戶端與服務(wù)器之間應(yīng)用層的通信
什么是七層負(fù)載均衡?
七層負(fù)載均衡邑狸,也被稱為“內(nèi)容交換”懈糯,指的是負(fù)載均衡設(shè)備通過(guò)報(bào)文中的應(yīng)用層信息(URL、HTTP頭部等信息)和負(fù)載均衡算法单雾,選擇到達(dá)目的的內(nèi)部服務(wù)器赚哗。
Haproxy與LVS之間的對(duì)比
LVS的特點(diǎn):
1、抗負(fù)載能力強(qiáng)硅堆∮齑ⅲ抗負(fù)載能力強(qiáng)、性能高硬萍,能達(dá)到F5硬件的60%扩所;對(duì)內(nèi)存和cpu資源消耗比較低
2、工作在網(wǎng)絡(luò)4層朴乖,通過(guò)vrrp協(xié)議轉(zhuǎn)發(fā)(僅作分發(fā)之用)祖屏,具體的流量由linux內(nèi)核處理,因此沒有流量的產(chǎn)生买羞。
2袁勺、穩(wěn)定性、可靠性好畜普,自身有完美的熱備方案期丰;(如:LVS+Keepalived)
3、應(yīng)用范圍比較廣吃挑,工作在四層钝荡,所以不用考慮要處理的具體應(yīng)用,可以對(duì)所有應(yīng)用做負(fù)載均衡舶衬;
4埠通、不支持正則處理,不能做動(dòng)靜分離逛犹。
5端辱、支持負(fù)載均衡算法:rr(輪循)、wrr(帶權(quán)輪循)虽画、lc(最小連接)舞蔽、wlc(權(quán)重最小連接)
6、配置復(fù)雜码撰,對(duì)網(wǎng)絡(luò)依賴比較大渗柿,穩(wěn)定性很高。
Ngnix的特點(diǎn):
1脖岛、工作在網(wǎng)絡(luò)的7層之上做祝,可以針對(duì)http應(yīng)用做一些分流的策略砾省,比如針對(duì)域名鸡岗、目錄結(jié)構(gòu)混槐;
2、Nginx對(duì)網(wǎng)絡(luò)的依賴比較小轩性,理論上能ping通就就能進(jìn)行負(fù)載功能声登;
3、Nginx安裝和配置比較簡(jiǎn)單揣苏,測(cè)試起來(lái)比較方便悯嗓;
4、也可以承擔(dān)高的負(fù)載壓力且穩(wěn)定卸察,一般能支撐超過(guò)1萬(wàn)次的并發(fā)脯厨;
5智哀、對(duì)后端服務(wù)器的健康檢查谎痢,只支持通過(guò)端口來(lái)檢測(cè)哮独,不支持通過(guò)url來(lái)檢測(cè)疟丙。
6蔽介、Nginx對(duì)請(qǐng)求的異步處理可以幫助節(jié)點(diǎn)服務(wù)器減輕負(fù)載伸头;
7酪术、Nginx僅能支持http阶剑、https和Email協(xié)議吃沪,適用范圍較小汤善。
8、不支持Session的直接保持票彪,但能通過(guò)ip_hash來(lái)解決红淡。
9、支持負(fù)載均衡算法:Round-robin(輪循)降铸、Weight-round-robin(帶權(quán)輪循)在旱、Ip-hash(Ip哈希)
10、Nginx還能做Web服務(wù)器即Cache功能垮耳。
HAProxy的特點(diǎn):
1颈渊、支持兩種代理模式:TCP(四層)和HTTP(七層),支持虛擬主機(jī)终佛;
2俊嗽、能夠補(bǔ)充Nginx的一些缺點(diǎn)比如Session的保持,Cookie的引導(dǎo)等工作
3铃彰、支持url檢測(cè)后端的服務(wù)器出問(wèn)題的檢測(cè)會(huì)有很好的幫助绍豁。
4、更多的負(fù)載均衡策略比如:動(dòng)態(tài)加權(quán)輪循(Dynamic Round Robin)牙捉,加權(quán)源地址哈希(Weighted Source Hash)竹揍,加權(quán)URL哈希和加權(quán)參數(shù)哈希(Weighted Parameter Hash)已經(jīng)實(shí)現(xiàn)
5敬飒、單純從效率上來(lái)講HAProxy會(huì)比Nginx有更出色的負(fù)載均衡速度。
6芬位、HAProxy可以對(duì)Mysql進(jìn)行負(fù)載均衡无拗,對(duì)后端的DB節(jié)點(diǎn)進(jìn)行檢測(cè)和負(fù)載均衡。
9昧碉、支持負(fù)載均衡算法:Round-robin(輪循)英染、Weight-round-robin(帶權(quán)輪循)、source(原地址保持)被饿、RI(請(qǐng)求URL)四康、rdp-cookie(根據(jù)cookie)
10、不能做Web服務(wù)器即Cache
2狭握、簡(jiǎn)述Haproxy常見的負(fù)載均衡調(diào)度算法及應(yīng)用場(chǎng)景詳解
算法:
roundrobin:
- 動(dòng)態(tài)算法: 支持權(quán)重的運(yùn)行時(shí)調(diào)整,支持慢啟動(dòng);每個(gè)后端中最多支持4095個(gè)server
static-rr:
- 靜態(tài)算法: 不支持權(quán)重的運(yùn)行時(shí)調(diào)整及慢啟動(dòng),后端主機(jī)數(shù)量無(wú)限制
leastconn:
- 推薦使用在具有較長(zhǎng)會(huì)話的場(chǎng)景中, 例如Mysql闪金、LDAP等
first:
- 根據(jù)服務(wù)器在列表中的位置,自上而下進(jìn)行調(diào)度,前面服務(wù)器的連接數(shù)達(dá)到上限后,新請(qǐng)求才會(huì)分配給下一臺(tái)服務(wù)器
source: 源地址hash
- 除權(quán)取余法
- 一致性哈希
uri:
- 對(duì)URI的左半部分做hash計(jì)算,并由服務(wù)器總權(quán)重相除以后派發(fā)至某挑出的服務(wù)器
<scheme>: //<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
- 左半部分: /<path>;<params>
- 整個(gè)uri: /<path>;<params>?<query>#<frag>
url_param:
- 對(duì)用戶請(qǐng)求的uri<params>部分中的參數(shù)的值作hash計(jì)算,并由服務(wù)器總權(quán)重相除以后派發(fā)至某挑出的服務(wù)器;通常用于追蹤用戶,以確保來(lái)自同一個(gè)用戶的請(qǐng)求始終發(fā)往同一個(gè)Backend Server;
hdr(<name>):
- 對(duì)于每個(gè)http請(qǐng)求,此處由<name>指定的http首部將會(huì)被取出做hash計(jì)算,并由服務(wù)器總權(quán)重相除以后派發(fā)至某挑出的服務(wù)器,沒有有效值的會(huì)被輪詢調(diào)度;
- hdr<Cookie>
- rdp-cookie
- rdp-cookie(<name>)
hash-type: 哈希算法
hash-type <method><function><modifier>
- map-based: 除權(quán)取余法,哈希數(shù)據(jù)結(jié)構(gòu)是靜態(tài)的數(shù)組
- consistent: 一致性哈希,哈希數(shù)據(jù)結(jié)構(gòu)是一個(gè)樹
- <function>: 哈希函數(shù)
- sdbm
- djb2
- wt6
- <function>: 哈希函數(shù)
3、通過(guò)Haproxy的ACL規(guī)劃實(shí)現(xiàn)智能負(fù)載均衡论颅,并簡(jiǎn)述tcp哎垦、http、health的配置示例
1).HAProxy的ACL的功能
acl格式:acl <aclname> <criterion> [flags] [operator] [<value>]
aclname:
- 自定義acl的名稱嗅辣,必填項(xiàng)撼泛,只能是大小寫、數(shù)字澡谭、'-'愿题、'_'、'.'蛙奖、':'
criterion
- 表示檢查那些數(shù)據(jù)或內(nèi)容潘酗,例如USERAGENT這個(gè)首部的值
四個(gè)最為常用的criterion為:
src:ip 源IP
src_port:integer 源端口
dst:ip 目標(biāo)IP
dst_port:integer 目標(biāo)端口
flags
- 定義控制條件,例如是否區(qū)分字符大小寫等雁仲,flags的可選參數(shù)如下:
-i 忽略字符大小寫
-m 啟用特定的匹配方式仔夺,一般不用
-n 禁止DNS反向解析
-u 不允許aclname重復(fù),默認(rèn)是可以重名的攒砖,當(dāng)兩個(gè)acl的名稱相同時(shí)缸兔,運(yùn)算為或機(jī)制。
operator
- 判斷匹配條件吹艇,與<criterion>相比較的條件
若匹配整數(shù)值:eq,ge,gt,le,lt
value
- 訪問(wèn)控制的具體內(nèi)容或值惰蜜。value的類型如下:
boolean:布爾值
integer or integer range:整數(shù)或整數(shù)范圍
IP address/network:網(wǎng)絡(luò)地址
string(exact, substring, suffix, prefix, subdir, domain):字符串
regular expression:正則表達(dá)式
hex block
(1).當(dāng)符合指定的條件時(shí)使用特定的backend,<backend>表示設(shè)置的backend名受神,if和unless為判斷條件抛猖,<condition>為比較的對(duì)象,可以是ACL規(guī)則,要注意的是在if和unless后面可以接兩個(gè)ACL财著,默認(rèn)表示兩個(gè)ACL同時(shí)滿足時(shí)才use_backend執(zhí)行联四。
use_backend <backend> [{if | unless} <condition>]
(2).阻塞一個(gè)七層請(qǐng)求滿足/不滿足某一ACL匹配條件。
block { if | unless } <condition>
示例:
acl invalid_src src 192.168.0.10 #acl匹配條件為源地址為192.168.0.10, acl名為invalid_src
block if invalid_src #阻斷滿足名為invalid_src的acl匹配條件
errorfile 403 /etc/fstab #并定義錯(cuò)誤頁(yè)
(3).配置七層的請(qǐng)求訪問(wèn)控制撑教,與block阻塞不同朝墩,http-request更靈活,可做黑白名單控制驮履。只能用在mode http中鱼辙。
http-request { allow | deny } [ { if | unless } <condition> ]
(4).配置四層的請(qǐng)求訪問(wèn)控制。
tcp-request connection {accept|reject} [{if | unless} <condition>]
示例:
listen ssh
bind :22332
balance leastconn
acl invalid_src src 172.16.0.67 #定義acl匹配規(guī)則
tcp-request connection reject if invalid_src #在四層拒絕滿足名為invalid_src的acl匹配規(guī)則
mode tcp
server sshsrv1 172.16.100.6:22 check
server sshsrv2 172.16.100.7:22 check
2).ACL示例
例1:設(shè)置HAProxy狀態(tài)頁(yè)玫镐,只允許指定IP訪問(wèn),設(shè)置如下:
listen stats #定義名稱
bind *:9099 #監(jiān)聽在9099端口
acl stats_page src 192.168.10.100 #匹配名為stats_page且源IP地址為192.168.29.1的ACL規(guī)則
block if ! stats_page #阻斷不匹配stats_page規(guī)則的所有條件怠噪,!為非
stats enable #啟用stats頁(yè)
stats uri /myhaproxy?admin #自定義stats頁(yè)面uri
stats realm "Adminstrator Stats-page"
stats auth admin:admin #設(shè)置狀態(tài)頁(yè)登錄賬號(hào)和密碼
例2:不使用block恐似,使用http-request來(lái)達(dá)到例1的效果。
listen stats
bind *:9099
acl stats_page src 192.168.10.100
http-request deny unless stats_page
stats enable
stats uri /myhaproxy?admin
stats realm "Adminstrator Stats-page"
stats auth admin:admin
例3.七層規(guī)則匹配
path : 精確匹配
path_beg : 匹配字符串開頭的所有內(nèi)容
path_dir : 子路徑匹配
path_dom : 匹配域名
path_end : 匹配字符串結(jié)尾的所有內(nèi)容
path_len : 字符串長(zhǎng)度匹配
path_reg : 正則表達(dá)式匹配
path_sub : 域名子串匹配
- 選兩臺(tái)主機(jī)傍念,安裝Nginx并用Nginx虛擬為4臺(tái)主機(jī)矫夷,兩臺(tái)用來(lái)處理圖片請(qǐng)求,兩臺(tái)用來(lái)處理文本請(qǐng)求憋槐,利用HAProxy負(fù)載均衡的ACL控制機(jī)制實(shí)現(xiàn)
frontend myweb
bind *:80
acl image path_end .png #匹配以.png結(jié)尾的path規(guī)則
acl txt path_end .txt #匹配以.txt結(jié)尾的path規(guī)則
use_backend imagesv if image #將規(guī)則image負(fù)載均衡到服務(wù)器組imagesv
use_backend txtsv if txt #將規(guī)則txt負(fù)載均衡至服務(wù)器組txtsv
default_backend app #默認(rèn)組双藕,無(wú)匹配時(shí)負(fù)載均衡至此
backend imagesv
balance roundrobin
server image1 192.168.10.103:80 check
server image2 192.168.10.103:8080 check
backend txtsv
balance roundrobin
server txt1 192.168.10.102:80 check
server txt2 192.168.10.102:8080 check
backend app
balance leastconn
cookie server insert nocache
server app1 192.168.10.102:80 check cookie svr1
server app2 192.168.10.103:80 check cookie svr2
4、LNMT實(shí)現(xiàn)動(dòng)靜分離實(shí)戰(zhàn)
1). 工作流程:
Client (http) --> nginx (reverseproxy)(http協(xié)議) --> tomcat (http connector 8080)
2). 環(huán)境描述:
虛擬機(jī)Server(CentOS 7系統(tǒng))即作為nginx服務(wù)器又作為Tomcat服務(wù)器阳仔,適配兩個(gè)網(wǎng)卡端口,外網(wǎng)IP:192.168.10.199,內(nèi)網(wǎng)IP:192.168.163.200,客戶端發(fā)來(lái)的請(qǐng)求首先經(jīng)由nginx處理忧陪,如果為靜態(tài)內(nèi)容則直接由nginx響應(yīng),如果為動(dòng)態(tài)內(nèi)容近范,則由nignx反代至后端的Tomcat服務(wù)器組并做負(fù)載均衡.
名稱 | 服務(wù)器ip | 類型 (CentOS 7) |
---|---|---|
Server | 外網(wǎng)192.168.10.199 | nginx |
Server | 內(nèi)網(wǎng)192.168.163.130 | nginx |
node1 | 192.168.163.131 | Tomcat A |
node2 | 192.168.163.132 | Tomcat B |
3). 配置安裝環(huán)境
[root@server ~]#ntpdate ntp1.aliyun.com
6 Mar 02:13:07 ntpdate[1819]: adjust time server 120.25.115.20 offset -0.139221 sec
[root@server ~]#yum install epel-release -y
[root@server ~]#yum repolist
repolist: 24,399
4). node服務(wù)器安裝tomcat
[root@node1 ~]#yum install java-1.8.0-openjdk tomcat tomcat-admin-webapps tomcat-webapps tomcat-docs-webapp -y
5). 配置user管理頁(yè)面
[root@node1 ~]#cd /etc/tomcat/
[root@node1 tomcat]#ls
Catalina catalina.properties context.xml logging.properties tomcat.conf web.xml
catalina.policy conf.d log4j.properties server.xml tomcat-users.xml
[root@node1 tomcat]#vim tomcat-users.xml
<role rolename="admin-gui"/>
<role rolename="manager-gui"/>
<user name="tomcat" password="tomcat" roles="admin-gui,manager-gui" />
6). 創(chuàng)建項(xiàng)目目錄
[root@node1 ~]#mkdir -pv /var/lib/tomcat/webapps/test/{WEB-INF,META-INF,classes,lib}
7). 配置主頁(yè)index.jsp
[root@node1 ~]#vim /var/lib/tomcat/webapps/test/index.jsp
<%@ page language="java" %>
<html>
<head><title>TomcatA</title></head>
<body>
<h1><font color="red">TomcatA.magedu.com</font></h1>
<table align="centre" border="1">
<tr>
<td>Session ID</td>
<% session.setAttribute("magedu.com","magedu.com"); %>
<td><%= session.getId() %></td>
</tr>
<tr>
<td>Created on</td>
<td><%= session.getCreationTime() %></td>
</tr>
</table>
</body>
</html>
8). 復(fù)制配置頁(yè)到node2并做對(duì)應(yīng)的修改
[root@node1 ~]#scp /etc/tomcat/tomcat-users.xml 192.168.163.132:/etc/tomcat/
9). 啟動(dòng)tomcat服務(wù)
[root@node1 ~]#systemctl start tomcat.service
[root@node1 ~]#ss -tnlp
LISTEN 0 1 ::ffff:127.0.0.1:8005 :::* users:(("java",pid=49922,fd=54))
LISTEN 0 100 :::8009 :::* users:(("java",pid=49922,fd=50))
LISTEN 0 128 :::111 :::* users:(("rpcbind",pid=719,fd=11))
LISTEN 0 100 :::8080 :::*
10). 測(cè)試tomcat首頁(yè)
11). 安裝nginx并配置首頁(yè)
[root@server ~]#yum install nginx -y
[root@server ~]#mkdir -pv /data/www/html/
mkdir: created directory ‘/data’
mkdir: created directory ‘/data/www’
mkdir: created directory ‘/data/www/html/’
[root@server ~]#vim /data/www/html/index.html
<h1>Nginx static Server</h1>
12). 配置主配置文件做動(dòng)靜分離
[root@server ~]#vim /etc/nginx/nginx.conf
upstream tomcat {
server 192.168.163.131:8080;
server 192.168.163.132:8080;
}
[root@server ~]#vim /etc/nginx/conf.d/tomcat.conf
server {
listen 80;
server_name 192.168.10.199;
location / {
root /data/www/html/;
index index.html;
}
location ~* \.(jsp|do)$ {
proxy_pass http://tomcat;
}
}
12). 啟動(dòng)nginx
[root@server ~]#systemctl start nginx.service
[root@server ~]#ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:111 *:*
LISTEN 0 128 *:80