1、简述四层和七层负载均衡的特点及Haproxy与LVS之间的对比
什么是四层负载均衡?
四层负载均衡指的是负载均衡设备通过报文中的目标IP地址和端口负载均衡算法,选择到达目的的内部服务器,其主要工作在OSI七层模型的第四层(传输层)。四层负载均衡对数据包只是起一个数据转发的作用,并不会干预客户端与服务器之间应用层的通信
什么是七层负载均衡?
七层负载均衡,也被称为“内容交换”,指的是负载均衡设备通过报文中的应用层信息(URL、HTTP头部等信息)和负载均衡算法,选择到达目的的内部服务器。
Haproxy与LVS之间的对比
LVS的特点:
1、抗负载能力强。抗负载能力强、性能高,能达到F5硬件的60%;对内存和cpu资源消耗比较低
2、工作在网络4层,通过vrrp协议转发(仅作分发之用),具体的流量由linux内核处理,因此没有流量的产生。
2、稳定性、可靠性好,自身有完美的热备方案;(如:LVS+Keepalived)
3、应用范围比较广,工作在四层,所以不用考虑要处理的具体应用,可以对所有应用做负载均衡;
4、不支持正则处理,不能做动静分离。
5、支持负载均衡算法:rr(轮循)、wrr(带权轮循)、lc(最小连接)、wlc(权重最小连接)
6、配置复杂,对网络依赖比较大,稳定性很高。
Ngnix的特点:
1、工作在网络的7层之上,可以针对http应用做一些分流的策略,比如针对域名、目录结构;
2、Nginx对网络的依赖比较小,理论上能ping通就就能进行负载功能;
3、Nginx安装和配置比较简单,测试起来比较方便;
4、也可以承担高的负载压力且稳定,一般能支撑超过1万次的并发;
5、对后端服务器的健康检查,只支持通过端口来检测,不支持通过url来检测。
6、Nginx对请求的异步处理可以帮助节点服务器减轻负载;
7、Nginx仅能支持http、https和Email协议,适用范围较小。
8、不支持Session的直接保持,但能通过ip_hash来解决。
9、支持负载均衡算法:Round-robin(轮循)、Weight-round-robin(带权轮循)、Ip-hash(Ip哈希)
10、Nginx还能做Web服务器即Cache功能。
HAProxy的特点:
1、支持两种代理模式:TCP(四层)和HTTP(七层),支持虚拟主机;
2、能够补充Nginx的一些缺点比如Session的保持,Cookie的引导等工作
3、支持url检测后端的服务器出问题的检测会有很好的帮助。
4、更多的负载均衡策略比如:动态加权轮循(Dynamic Round Robin),加权源地址哈希(Weighted Source Hash),加权URL哈希和加权参数哈希(Weighted Parameter Hash)已经实现
5、单纯从效率上来讲HAProxy会比Nginx有更出色的负载均衡速度。
6、HAProxy可以对Mysql进行负载均衡,对后端的DB节点进行检测和负载均衡。
9、支持负载均衡算法:Round-robin(轮循)、Weight-round-robin(带权轮循)、source(原地址保持)、RI(请求URL)、rdp-cookie(根据cookie)
10、不能做Web服务器即Cache
2、简述Haproxy常见的负载均衡调度算法及应用场景详解
算法:
roundrobin:
- 动态算法: 支持权重的运行时调整,支持慢启动;每个后端中最多支持4095个server
static-rr:
- 静态算法: 不支持权重的运行时调整及慢启动,后端主机数量无限制
leastconn:
- 推荐使用在具有较长会话的场景中, 例如Mysql、LDAP等
first:
- 根据服务器在列表中的位置,自上而下进行调度,前面服务器的连接数达到上限后,新请求才会分配给下一台服务器
source: 源地址hash
- 除权取余法
- 一致性哈希
uri:
- 对URI的左半部分做hash计算,并由服务器总权重相除以后派发至某挑出的服务器
<scheme>: //<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
- 左半部分: /<path>;<params>
- 整个uri: /<path>;<params>?<query>#<frag>
url_param:
- 对用户请求的uri<params>部分中的参数的值作hash计算,并由服务器总权重相除以后派发至某挑出的服务器;通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个Backend Server;
hdr(<name>):
- 对于每个http请求,此处由<name>指定的http首部将会被取出做hash计算,并由服务器总权重相除以后派发至某挑出的服务器,没有有效值的会被轮询调度;
- hdr<Cookie>
- rdp-cookie
- rdp-cookie(<name>)
hash-type: 哈希算法
hash-type <method><function><modifier>
- map-based: 除权取余法,哈希数据结构是静态的数组
- consistent: 一致性哈希,哈希数据结构是一个树
- <function>: 哈希函数
- sdbm
- djb2
- wt6
- <function>: 哈希函数
3、通过Haproxy的ACL规划实现智能负载均衡,并简述tcp、http、health的配置示例
1).HAProxy的ACL的功能
acl格式:acl <aclname> <criterion> [flags] [operator] [<value>]
aclname:
- 自定义acl的名称,必填项,只能是大小写、数字、'-'、'_'、'.'、':'
criterion
- 表示检查那些数据或内容,例如USERAGENT这个首部的值
四个最为常用的criterion为:
src:ip 源IP
src_port:integer 源端口
dst:ip 目标IP
dst_port:integer 目标端口
flags
- 定义控制条件,例如是否区分字符大小写等,flags的可选参数如下:
-i 忽略字符大小写
-m 启用特定的匹配方式,一般不用
-n 禁止DNS反向解析
-u 不允许aclname重复,默认是可以重名的,当两个acl的名称相同时,运算为或机制。
operator
- 判断匹配条件,与<criterion>相比较的条件
若匹配整数值:eq,ge,gt,le,lt
value
- 访问控制的具体内容或值。value的类型如下:
boolean:布尔值
integer or integer range:整数或整数范围
IP address/network:网络地址
string(exact, substring, suffix, prefix, subdir, domain):字符串
regular expression:正则表达式
hex block
(1).当符合指定的条件时使用特定的backend,<backend>表示设置的backend名,if和unless为判断条件,<condition>为比较的对象,可以是ACL规则,要注意的是在if和unless后面可以接两个ACL,默认表示两个ACL同时满足时才use_backend执行。
use_backend <backend> [{if | unless} <condition>]
(2).阻塞一个七层请求满足/不满足某一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 #并定义错误页
(3).配置七层的请求访问控制,与block阻塞不同,http-request更灵活,可做黑白名单控制。只能用在mode http中。
http-request { allow | deny } [ { if | unless } <condition> ]
(4).配置四层的请求访问控制。
tcp-request connection {accept|reject} [{if | unless} <condition>]
示例:
listen ssh
bind :22332
balance leastconn
acl invalid_src src 172.16.0.67 #定义acl匹配规则
tcp-request connection reject if invalid_src #在四层拒绝满足名为invalid_src的acl匹配规则
mode tcp
server sshsrv1 172.16.100.6:22 check
server sshsrv2 172.16.100.7:22 check
2).ACL示例
例1:设置HAProxy状态页,只允许指定IP访问,设置如下:
listen stats #定义名称
bind *:9099 #监听在9099端口
acl stats_page src 192.168.10.100 #匹配名为stats_page且源IP地址为192.168.29.1的ACL规则
block if ! stats_page #阻断不匹配stats_page规则的所有条件,!为非
stats enable #启用stats页
stats uri /myhaproxy?admin #自定义stats页面uri
stats realm "Adminstrator Stats-page"
stats auth admin:admin #设置状态页登录账号和密码
例2:不使用block,使用http-request来达到例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.七层规则匹配
path : 精确匹配
path_beg : 匹配字符串开头的所有内容
path_dir : 子路径匹配
path_dom : 匹配域名
path_end : 匹配字符串结尾的所有内容
path_len : 字符串长度匹配
path_reg : 正则表达式匹配
path_sub : 域名子串匹配
- 选两台主机,安装Nginx并用Nginx虚拟为4台主机,两台用来处理图片请求,两台用来处理文本请求,利用HAProxy负载均衡的ACL控制机制实现
frontend myweb
bind *:80
acl image path_end .png #匹配以.png结尾的path规则
acl txt path_end .txt #匹配以.txt结尾的path规则
use_backend imagesv if image #将规则image负载均衡到服务器组imagesv
use_backend txtsv if txt #将规则txt负载均衡至服务器组txtsv
default_backend app #默认组,无匹配时负载均衡至此
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实现动静分离实战
1). 工作流程:
Client (http) --> nginx (reverseproxy)(http协议) --> tomcat (http connector 8080)
2). 环境描述:
虚拟机Server(CentOS 7系统)即作为nginx服务器又作为Tomcat服务器,适配两个网卡端口,外网IP:192.168.10.199,内网IP:192.168.163.200,客户端发来的请求首先经由nginx处理,如果为静态内容则直接由nginx响应,如果为动态内容,则由nignx反代至后端的Tomcat服务器组并做负载均衡.
名称 | 服务器ip | 类型 (CentOS 7) |
---|---|---|
Server | 外网192.168.10.199 | nginx |
Server | 内网192.168.163.130 | nginx |
node1 | 192.168.163.131 | Tomcat A |
node2 | 192.168.163.132 | Tomcat B |
3). 配置安装环境
[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服务器安装tomcat
[root@node1 ~]#yum install java-1.8.0-openjdk tomcat tomcat-admin-webapps tomcat-webapps tomcat-docs-webapp -y
5). 配置user管理页面
[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). 创建项目目录
[root@node1 ~]#mkdir -pv /var/lib/tomcat/webapps/test/{WEB-INF,META-INF,classes,lib}
7). 配置主页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). 复制配置页到node2并做对应的修改
[root@node1 ~]#scp /etc/tomcat/tomcat-users.xml 192.168.163.132:/etc/tomcat/
9). 启动tomcat服务
[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). 测试tomcat首页
11). 安装nginx并配置首页
[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). 配置主配置文件做动静分离
[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). 启动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