负载均衡
负载均衡:Load Balance,简称LB,是一种服务或基于硬件设备等实现的高可用反向代理技术,负载均衡将特定的业务(web服务、网络流量等)分担给指定的一个或多个后端特定的服务器或设备,从而提高了公司业务的并发处理能力、保证了业务的高可用性、方便了业务后期的水平动态扩展。
为什么用负载均衡
- Web服务器的动态水平扩展----->对用户无感知
- 增加业务并发访问及处理能力-->解决单服务器瓶颈问题
- 节约公网IP地址-------------------->降低IT支出成本
- 隐藏内部服务器IP----------------->提高内部服务器安全性
- 配置简单----------------------------->固定格式的配置文件
- 功能丰富----------------------------->支持四层和七层,支持动态下线主机
- 性能较强----------------------------->并发数万甚至数十万
四层负载均衡
- 通过ip+port决定负载均衡的去向。
- 对流量请求进行NAT处理,转发至后台服务器。
- 记录tcp、udp流量分别是由哪台服务器处理,后续该请求连接的流量都通过该服务器处理
- 支持四层的软件
- Ivs:重量级四层负载均衡器
- Nginx:轻量级四层负载均衡器,可缓存。(nginx四层是通过upstream模块)
- Haproxy:模拟四层转发。
七层负载均衡
- 通过虚拟ur|或主机ip进行流量识别,根据应用层信息进行解析,决定是否需要进行负载均衡
- 代理后台服务器与客户端建立连接,如nginx可代理前后端,与前端客户端tcp连接,与后端服务器建立tcp连接,
- 支持7层代理的软件:
- Nginx:基于http协议(nginx七层是通过proxy_pass)
- Haproxy:七层代理,会话保持、标记、路径转移等。
四层与七层的区别
所谓的四到七层负载均衡,就是在对后台的服务器进行负载均衡时,依据四层的信息或七层的信息来决定怎么样转发流量
四层的负载均衡,就是通过发布三层的IP地址 (VIP),然后加四层的端口号,来决定哪些流量需要做负载均衡,对需要处理的流量进行NAT处理,转发至后台服务器,并记录下这个TCP或者UDP的流量是由哪台服务器处理的,后续这个连接的所有流量都同样转发到同一台服务器处理
七层的负载均衡,就是在四层的基础上(没有四层是绝对不可能有七层的),再考虑应用层的特征,比如同一个Web服务器的负载均衡,除了根据VIP加80端口辨别是否需要处理的流量,还可根据七层的URL、浏览器类别、语言来决定是否要进行负载均衡。
- 分层位置:四层负载均衡在传输层及以下,七层负载均衡在应用层及以下
- 性能:四层负载均衡架构无需解析报文消息内容,在网络吞吐量与处理能力上较高:七层可支持解析应用层报文消息内容,识别URL、Cookie、HTTP header等信息。、
- 原理 :四层负载均衡是基于ip+port;七层是基于虚拟的URL或主机IP等。
- 功能类比:四层负载均衡类似于路由器;七层类似于代理服务器。
- 安全性:四层负载均衡无法识别DDoS攻击;七层可防御SYN Cookie/Flood攻击
实验
准备三台主机
一台:haproxy服务机 ip 172.25.119.100
两台:server机
webserver1 ip 172.25.119.10
webserver2 ip 172.25.119.20
实验前配置
关闭防火墙和selinux
systemctl stop firewalld
setenforce 0
haproxy主机
下载haproxy服务
yum install haproxy -y
更改haproxy的配置
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
一般写法
两条合并的写法
webserver1
ip信息
下载在nginx 做测试
yum install nginx -y
在网页文件中写入数据做测试查看
[root@webserver1 ~]# echo webserver1 172.25.119.10 >/usr/share/nginx/html/index.html
启动nginx服务
[root@webserver1 ~]# systemctl enable --now nginx
webserver2
ip信息
下载在nginx 做测试
yum install nginx -y
在网页文件中写入数据做测试查看
[root@webserver2 ~]# echo webserver2 172.25.119.20 >/usr/share/nginx/html/index.html
启动nginx服务
[root@webserver2 ~]# systemctl enable --now nginx
测试
开启多线程
修改配置文件
[root@haproxy ~]# vim /etc/haproxy/haproxy.cfg
测试
指定为进程提供服务的CPU
cpu-map 1 0 1表示第一个进程 0表示第一个 cpu核心
cpu-map 2 1 2表示第二个进程 1表示第二个cpu核心
开启多线程
注意:多进程和多线程不能同时开启否则服务将起不来
当多线程与多进程一起开启是 起服务将报错
正常起服务:
进程最大并发连接数
日志重定向
打开日志配置文件开启UDP配置
vim /etc/rsyslog.conf
检查
haproxy代理参数
nter 2 -------------------> 每过两秒检查一次连接是否健康
fall 3 --------------------> 最大失败次数 3 连续3次检查失败将视为下线了
rise 5 ---------------------> 断开后连续5次检查成功视为重新上线
weighe 2 ---------------->权重 2
disabled ----------------------->强制下线
backup -----------------------> 当上面的连接全部下线了 将使用这个链接告诉用户链接断开了 无法连接
网页重定向
当在浏览器上输入ip地址172.25.119.100后将会自动跳转到百度界面
socat 工具
对服务器动态权重和其它状态可以利用 socat工具进行调整,Socat 是 Linux 下的一个多功能的网络工具,名字来由是Socket CAT,相当于netCAT的增强版.Socat 的主要特点就是在两个数据流之间建立双向通道,且支持众多协议和链接方式。如IP、TCP、UDP、IPv6、Socket文件等
范例:利用工具socat 对服务器动态权重调整
下载socat
yum install socat -y
socat 查看帮助
socat 改haproxy 设置
改haproxy配置文件 提权
查看权重
echo get weight webcluster/web1 | socat stdio /var/lib/haproxy/stats
echo get weight webcluster/web2 | socat stdio /var/lib/haproxy/stats
更改权重
echo "set weight webcluster/web1 1" | socat stdio /var/lib/haproxy/stats
echo "set weight webcluster/web1 2" | socat stdio /var/lib/haproxy/stats
查看状态
echo 'disable server webcluster/web1' | socat stdio /var/lib/haproxy/stats
强制下线某一个(web1)设备
开启设备,关闭强制下线
echo 'enable server webcluster/web1' | socat stdio /var/lib/haproxy/stats
多线程热处理
在配置文件中开启多线程
vim /etc/haproxy/haproxy.cfg
查看结果
echo "show info" | socat stdio /var/lib/haproxy/stats1
echo "show info" | socat stdio /var/lib/haproxy/stats2
haproxy算法
静态算法
关闭防火墙和selinux
static-rr基于权重的轮询调度
- 不支持运行时利用socat进行权重的动态调度(只支持1 0 不支持其他值)
- 不支持服务器慢启动
- 其后端主机数量没有限制,相当于LVS中的wrr
配置:
vim /etc/haproxy/haproxy.cfg
first
根据服务器在列表中的位置,自上而下进行调度
其只会在第一台服务器到达链接上线后 ,才会将新请求分发给下一个服务器
会忽略服务器的权重
不支持socat进行动态修改权重,可以设置0和1,也可以设置其他值但是无效
配置
测试:设置的权重 web1是 2 web2 是1 通过结果来看显然权重是没有效果的
动态算法
roundrobin
基于权重的轮询调度算法
支持权重的运行时调整,不同与LVS中的rr轮询模式
HAProxy中的roundrobin 支持慢启动
其每个后端backend中最多支持4095个real server
支持对deal server 权重的动态调整
roundrobin 为默认调度算法,此算法使用广泛
配置
我们可以看到初始权重为 web1 是2 web2 是1 调度是也是两个webserver 1 一个webserver2 动态改完权重后调度是 一个一个来
leastconn
leastconn 加权的最少连接的动态
支持权重的运行时调度和慢启动,即:根据当前链接少的后端服务器而非权重进行有限调度
比较适合长连接的场景使用 ,比如:MySQL等场景
配置
其他算法
source
源地址hash,基于用户源地址hash并将请求发送到后端服务器,后续同一个源地址请求将被转发到同一台后端服务器。此方式当后端服务器数量发生变化时,会导致很多用户的请求转发到新的后端服务器,默认为静止方式,但是可以通过hash-type支持选项更改这一算法
配置:静态
配置:动态
初始状态 web1 的权重大 访问时选择web1 当将web2 的权重给为 5时 访问选择web2
uri
基于对用户的请求的URI的左半部分或者整个URI做hash,再将hash结果对总权重进行取模后根据最终的结果将请求转发到后端指定的服务器
适用于后端是缓存服务器的场景
此算法基于应用层,所以只支持mode http 不支持 mode tcp
配置 :静态
配置:动态
url_param
url_param对用户请求的URL中的params部分中的一个参数key对应的value值做hash计算,并由服务器总权重相除以后派发至,某挑出的服务器,后端搜索同一个数据会被调度到同一个服务器,多用与电商
通常用于追踪用户,以确保来自同一个用户的请求始终发往同一个real server
如果没有 key 将按照roundrobin算法
配置:静态
配置:动态
hdr
针对每个用户http头部(header)请求中的指定信息做hash
此处有name指定http首部将会取出并做hash计算,
然后又服务器总权重取模以后派发至挑出的服务器,如果无有效值,则会使用默认的轮询调度。
配置:静态
配置:动态
算法总结
静态:
static-rr ---------------> tcp/http #做了session共享的web集群
first---------------------->tcp/http #使用较少
动态:
roundrobin----------->tcp/http
leastconn-------------->tcp/http #数据库
random----------------->tcp/http
其他算法 静态和动态取决于hash_type是否 consistent
source------------------->tcp/http
Uri------------------------->http #缓存服务器,CDN服务器,蓝汛,百度,阿里云,腾讯
url_param-------------->http #可以实现sessionn保持
hdr------------------------>http #基于客户端请求报文头部做下一步处理
haproxy状态页
配置文件
vim /etc/haproxy/haproxy.cfg
浏览器访问测试
HAProxy高级功能
haproxy-基于cookie的会话保持
给访问的连接加上cookie值
测试
在浏览器测试查看cookie的值
ip透传
可以通过日志内容看到访问者的源iP地址
七层透传
将这一块注释掉将不会进行ip透传
nginx本身自带不需要配置
Apache没有需要改配置文件
vim /etc/httpd/conf/httpd.conf
在日志内容这一块加上 %{X-Forwarded-For}i
测试
没做ip透传之前
nginx:
apache:
做了IP透传
nginx:
Apache:
四层IP透传
haproxy服务器:
vim /etc/haproxy/haproxy.cfg
nginx服务器:
vim /etc/nginx/nginx.conf
测试:
nginx:
haproxy的访问控制列表应用
ACL 访问控制列表
用ACL来定义声明一个acl
acl 名称 匹配规范 匹配模式 具体操作 操作对象类型
名称
可以使用A-Z或a-z、0-9 冒号:点 . 顿号、横线 - 下划线 _ 严格区分大小写
匹配规范
hdr
<scheme>://<user>:<password>@#<host>:<port>/<path>;<params>#?<query>#<frag>
hdr string 提取在一个http报文的首部
hdr_beg 前缀匹配
hdr_end 后缀匹配
hdr_dom 域匹配
hdr_dir 路径匹配
hdr_len 长度匹配
hdr_reg 正则表达式匹配
hdr_sub 子串匹配
base
#返回第一个主机头和请求的路径部分的连接,该请求从主机名开始,并在问号之前结束,对虚拟主机有用(加粗部分)
<scheme>://<user>:<password>@#<host>:<port>/<path>;<params>#?<query>#<frag>
base : exact string match
base_beg : prefix match
base_dir : subdir match
base dom : domain match
base_end : uffix match
base len :length match
base_reg :regex match
base_sub :substring match
path
#提取请求的URL路径,该路径从第一个斜杠开始,并在问号之前结束(无主机部分) (加粗部分)
<scheme>://<user>:<password>@#<host>:<port>/<path>;<params>#?<query>#<frag>
path_beg :prefix match #请求的URL开头,如/static、/images、/img、/css
path_end : suffix match #请求的URL中资源的结尾,如gifpngcssjsjpgjpeg
path dom :domain match
path_dir : subdir match
path_len :length match
path_reg : regex match
path_sub :substring match
url
#提取请求中的整个URL。一个典型的应用是具有预取能力的缓存,以及需要从数据库聚合多个信息并将它们保存在缓存中的网页门户入口,推荐使用path
<scheme>://<user>:<password>@#<host>:<port>/<path>;<params>#?<query>#<frag>
url_beg : prefix match
url_dir :subdir match
url_dom :domain match
url_end :suffix match
url_len :length match
url_reg :regex match
url_sub :substring match
匹配模式
-i不区分大小写
-m使用指定的正则表达式匹配方法
-n 不做DNS解析
-u禁止ac1重名,否则多个同名ACL匹配或关系
实例
以域名做访问控制
配置:
vim /etc/haproxy/haproxy.cfg
在本机访问需要做域名解析
测试:
以域名.com为结尾的访问控制
基于字符的访问控制
创建一个新的网页测试
[root@webserver1 ~]#mkdir /var/www/html/li -p
[root@webserver1 ~]# echo 172.25.119.10 webserver li >/var/www/html/li/index.html
path 与 base 相似 ,不过base的范围不path的大,base包含path。操作一样
ACL组合调用方式
与:隐式(默认)使用
或:使用“or”或“|"表示
否定:使用"!”表示
基于ip的反向访问控制
拒绝访问
基于浏览器的访问控制
haproxy-利用acl做动静分离等访问控制
下载php做测试
yum install php -y
检查能否访问
vim /var/www/html/index.php
<?php
phpinfo();
?>
浏览器访问 172.25.119.100 将访问到172.25.119.20
浏览器访问 172.25.119.100/index.html 将访问到172.25.119.20/index.html
浏览器访问 172.25.119.100/index.php 将访问到172.25.119.10/index.php
haproxy-自动逸错误页面内容
对指定的报错进行重定向
关闭httpd服务器和nginx服务器,让访问报错
制定报错文件
定向报错文件位置
测试
访问报错重定向到网页
当访问报错时会自动跳转到百度页面
haproxy-hapoxy的四层负载示例
针对除http以外的tcp协议应用服务访问的应用场景,以mariadb为例子
分别在server1和server2上下载mariadb
yum install mariadb-server -y
更改数据库server_id 方便测试查看
vim /etc/my.cnf.d/mariadb-server.cnf
进入数据库创建可以远程登录的用户
mysql--------->进入数据库
create user li@'%' identified by "li" --------------> 创建用户及密码
grant all on *.* to li@'%'-------------->给li用户所有库所有表的权限
更改添加haproxy配置
vim /etc/haproxy/haproxy.cfg
测试:
haproxy-https的加密访问
haproxy 可以实现https的证书安全,从用户到haproxy为https,从haproxy到后端服务器用http通信但基于性能考虑,生产中的证书都是在后端服务器比如nginx上实现
建立一个文件夹用来存放秘钥
mkdir -p /etc/haproxy/certs
制作秘钥
[root@haproxy ~]# openssl req -newkey rsa:2048 -nodes -sha512 -keyout /etc/haproxy/certs/li.key -x509 -days 365 -out /etc/haproxy/certs/li.crt
rsa:2048 rsa的2048为加密
-nodes 自动加密不用每次登录都是密码
-sha512 加密方式
-keyout 秘钥定向
-x509 证书格式
-days 365 一年有效
将秘钥和公钥导入一个文件
[root@haproxy ~]# cat /etc/haproxy/certs/li.key /etc/haproxy/certs/li.crt >/etc/haproxy/certs/li.pem
更改添加haproxy的配置文件
访问测试
全站加密
全栈加密后当你在输入172.25.119.100或者访问时将自动以https://172.25.119.100的形式访问
相等于默认https的形式
子配置文件
/etc/haproxy/conf.d/
将配置写入配置文件一样可以正常加载,而且可以使配置文件更清晰整洁