1.负载均衡实现的方式
硬件:f5、 软件: 七层:Nginx Haproxy 四层:LVS ( Nginx:四层代理实现负载均衡-受到随机端口的数量限制-且只能保证web集群的高可用状态-并不能保证自身的高可用(借助keepalive软件) 、Haproxy四层负载均衡 ) 云厂商: LB产品,它支持四层和七层?同时你只需要购买你需要的连接数即可? 云厂商负载均衡的名词: SLB 阿里 CLB 腾讯 ULB ucloud QLB 青云
四层:性能好,支持功能弱。
七层:性能差,支持功能强。
四层结合七层 共同使用。相互弥补。 四层SLB:无端口数量限制
PS:四层负载均衡与七层负载均衡的区别: 四层负载均衡数据包在底层就进程了分发 七层负载均衡数据包则是在最顶层进行分发。 —> 由此可以看出: 七层负载均衡效率没有四层负载均衡效率高。
但七层负载均衡更贴近与服务,(http协议就是七层协议)
我们可以用Nginxz做URI路径规则匹配,Head改写。RWwirte,会话保持等,这些都是四层均衡负载无法实现的。
1.1 Nginx七层负载均衡示例
资源池节点 | 资源池 ip |
---|---|
web01 | 172.16.1.7 |
web02 | 172.16.1.8 |
配置webserver
[root@web01 ~]# cat /etc/nginx/conf.d/node.oldxu.com.conf server { listen 80; server_name node.oldxu.com; root /node; location / { index index.html; } }
[root@web01 ~]# nginx -t
[root@web01 ~]# systemctl restart nginx
[root@web01 ~]# mkdir /node
[root@web01 ~]# echo "Web01..." > /node/index.html
web02同
- 配置负载均衡
[root@lb01 ~]#cat /etc/nginx/conf.d/proxy_node.oldxu.com.conf
#定义负载均衡资源池名称 ```bash upstream node { server 172.16.1.7:80; server 172.16.1.8:80; }
server { listen 80; server_name node.oldxu.com;
location / {
proxy_pass http://node;
include proxy_params;
}
}
- 请求测试:<br />[root[@lb01 ](/lb01 ) ~]# `curl -H Host:node.oldxu.com 172.16.1.7`<br />Web01...<br />[root[@lb01 ](/lb01 ) ~]# `curl -H Host:node.oldxu.com 172.16.1.8`<br />Web02...<br />访问网页发现:web1,web2,会均衡的提供服务。
实践: wecenter 接入到负载均衡:
| ip | 域名 |
| --- | --- |
| 172.16.1.7 | blog.oldxu.com zh.oldxu.com |
| 172.16.1.8 | blog.oldxu.com zh.oldxu.com |
负载均衡的配置:<br />[root[@lb01 ](/lb01 ) ~]# `cat ``/etc/nginx/conf.d/proxy_zh.oldxu.com.conf`
```bash
upstream zh {
server 172.16.1.7:80;
server 172.16.1.8:80;
}
server {
listen 80;
server_name zh.oldxu.com;
location / {
proxy_pass http://zh;
include proxy_params;
}
}
*2.调度算法
调度算法 | 作用 |
---|---|
轮询(默认) | 按时间顺序逐一分配到不同的后端服务器(默认) |
weight(加权轮询) | 加权轮询,weight值越大,分配到的访问几率越高 |
ip_hash | 每个请求按访问IP的hash结果分配,这样来自同一IP的固定访问一个后端服务器 |
least_conn | 将请求传递到活动连接数最少的服务器。 |
2.1 Nginx负载均衡轮询具体配置
upstream load_pass {
server 10.0.0.7:80;
server 10.0.0.8:80;
}
2.2 Nginx负载均衡 [weight] 权重轮询具体配置
upstream load_pass {
server 10.0.0.7:80 weight=5;
server 10.0.0.8:80;
}
2.3 Nginx负载均衡 [ip_hash] 具体配置, 不能和使用加权轮询weight也不能使用backup标记状态
#如果客户端都走相同代理, 会导致某一台服务器连接过多
upstream load_pass {
#ip_hash;
server 10.0.0.7:80 weight=5;
server 10.0.0.8:80;
}
Ps: IP_hash 实现会话保持功能的原理: Specifies that a group should use a load balancing method where requests are distributed between servers based on client IP addresses. The first three octets of the client IPv4 address, or the entire IPv6 address, are used as a hashing key. The method ensures that requests from the same client will always be passed to the same server except when this server is unavailable. In the latter case client requests will be passed to another server. Most probably, it will always be the same server as well.
*3. 后端Web服务器在前端Nginx负载均衡调度中的状态
状态 | 概述 |
---|---|
down | 当前的server暂时不参与负载均衡 相当于注释 |
backup | 预留的备份服务器 (所有都宕机,还会使用它) |
max_fails | 允许请求失败的次数 |
fail_timeout | 经过max_fails失败后, 服务暂停时间 |
max_conns | 限制最大的接收连接数 |
解决:会话保持的问题 ip_hash: 缺陷:会造成后端某一个节点压力过大,而其他节点没什么压力。 ( NAT ) CPU 内存 IO 一模一样。丝毫不差 既要保证轮询调度到后端的每个节点是公平调度的,同时还要保证 会话保持问题? IP_HASH pass掉 ————->>>> redis来存储用户的会话信息,然后共享的方式来实现。
4. keepalive
(适合频繁连接的勤快,保持连接,减少资源调动)
[root@lb01 ~]# cat /etc/nginx/conf.d/proxy_node.oldxu.com.conf
#定义负载均衡资源池名词
upstream node {
server 172.16.1.7:80 max_fails=3 fail_timeout=10s;
server 172.16.1.8:80 max_fails=3 fail_timeout=10s;
keepalive 16;
keepalive_timeout 100s;
}
server {
listen 80;
server_name node.oldxu.com;
location / {
proxy_pass http://node;
include proxy_params;
}
}
linux客户端:
[root@web01 ~]# echo "10.0.0.5 node.oldxu.com" >> /etc/hosts
[root@web01 ~]# yum install httpd-tools -y
[root@web01 ~]# ab -n 10000 -c200 -k [http://node.oldxu.com/](http://node.oldxu.com/)
#模拟1000w个连接
[root@lb01 ~]# netstat -an | grep ESTABLISHED
负载均衡节点通过netstat查看ESTABILED的状态
企业案例: 使用nginx负载均衡时,如何将后端请求超时的服务器流量平滑的切换到另一台上。如果后台服务连接超时,Nginx是本身是有机制的,如果出现一个节点down掉的时候,Nginx会更据你具体负载均衡的设置,将请求转移到其他的节点上,但是,如果后台服务连接没有down掉,但是返回错误异常码了如:504、502、500,应该如何处理。
可以在负载均衡添加如下配置proxy_next_upstream http_500 | http_502 | http_503 | http_504 |http_404;当其中一台返回错误码404,500…等错误时,可以分配到下一台服务器程序继续处理,提高平台访问成功率。
[root@lb01 ~]# cat /etc/nginx/conf.d/proxy_blog.oldxu.com.conf
upstream blog {
server 172.16.1.7:80;
server 172.16.1.8:80;
}
server {
listen 80;
server_name blog.oldxu.com;
location / {
proxy_pass http://blog;
include proxy_params;
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
}
}
*5. 七层负载均衡+ Redis会话共享
点击查看应用场景——> Rids功能
1.session 由服务端程序生成, 生成的是 一个 叫 session_ID 的编号。 存储在服务端( 没登录状态 ) 2.应用程序Nginx,会将程序生成的Session_ID 回传给 浏览器 ,通过的Header方式 set-cookies 3.浏览器 收到服务端的Session_ID 会将该Session_ID 存储至 Cookies中。 4.当我尝试登陆网站时,输入用户名称 + 用户密码 + Session_ID 5.登陆成功,我们的服务端会存储该 Session 至 本地,并将该sessionID与对应登陆的用户名称捆绑,标记已登陆 6.当浏览器再起发送请求, 还会携带 cookies 中的 Session_ID,服务端校验Session_ID, 比对成功,则会话保持。
5.1 搭建Nginx+WEB的轮序调度
1.1在两台web节点上安装phpmyadmin
[root@web01 ~]# unzip phpMyAdmin-5.0.2-all-languages.zip -d /code/
[root@web01 code]# ln -s /code/phpMyAdmin-5.0.2-all-languages/ /code/phpmyadmin
[root@web01 code]# cd /code/phpmyadmin/
[root@web01 phpmyadmin]# cp config.sample.inc.php config.inc.php
[root@web01 phpmyadmin]# vim config.inc.php
/* Server parameters */
$cfg['Servers'][$i]['host'] = '172.16.1.51';
1.2授权
[root@web01 phpmyadmin]# chown -R www.www /var/lib/php/
1.3Nginx配置文件
[root@web01 code]# cat /etc/nginx/conf.d/phpmyadmin.oldxu.com.conf
server {
listen 80;
server_name phpmyadmin.oldxu.com;
root /code/phpmyadmin;
location / {
index index.php;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
[root@web01 code]# nginx -t
[root@web01 code]# systemctl reload nginx
4.配置web02 1.拷贝配置文件 2.拷贝代码 3.重建软链接 4.授权 5.重启Nginx
5.2接入负载均衡
[root@lb01 ~]# cat /etc/nginx/conf.d/proxy_phpmyadmin.oldxu.com.conf
upstream php {
server 172.16.1.7:80;
server 172.16.1.8:80;
}
server {
listen 80;
server_name phpmyadmin.oldxu.com;
location / {
proxy_pass http://php;
include proxy_params;
}
}
nginx -t
systemctl restart nginx
6.将存储在本地的Session,让其存储在Redis中。
3.1 安装Redis
[root@db01 ~]# yum install redis -y
3.2 配置 Redis (这个IP地址是本机的内网IP地址)
[root@db01 ~]# sed -i '/^bind/c bind 127.0.0.1 172.16.1.51' /etc/redis.conf
3.3 启动Redis(暂时运行在db1服务器)
[root@db01 ~]# systemctl start redis
[root@db01 ~]# systemctl enable redis
[root@db01 ~]# netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 172.16.1.51:6379 0.0.0.0:* LISTEN 8966/redis-server 1
7. 配置Sessionid指向
修改( web01 web02 ) php程序,将原本存储至本地的SessionID,修改为存储至远程的Redis服务器,web1相同操作
[root@web02 ~]# vim /etc/php.ini
session.save_handler = redis
session.save_path = "tcp://172.16.1.51:6379?weight=1&timeout=2.5" #连接redis
;session.save_path = "tcp://172.16.1.51:6379?auth=123456&weight=1&timeout=2.5" #redis有密码的连接方式
注释; php-fpm中控制session存储的路径**
[root@web02 ~]# vim /etc/php-fpm.d/www.conf
;php_value[session.save_handler] = files
;php_value[session.save_path] = /var/lib/php/session
重启php-fpm
[root@web02 ~]# systemctl restart php-fpm
重启redi
5.测试访问,查看效果。
[root@db01 ~]# redis-cli
>keys * #查看 session
Ps: web页面查看session
扩展:
能不能图形界面展示负载均衡的状态?
编译Nginx,如果你去到一家公司,需要给Nginx添加新模板,怎么办?