负载均衡
负载均衡
将请求平均的分配给后端服务器,防止单个服务器的压力过大导致宕机。
为什么要是用负载均衡
- 当我们的Web服务器直接面向用户,往往要承载大量并发请求,单台服务器难以负荷,我使用多台Web服务器组成集群,前端使用Nginx负载均衡,将请求分散的打到我们的后端服务器集群中,实现负载的分发。那么会大大提升系统的吞吐率、请求性能、高容灾
- 往往我们接触的最多的是SLB(Server Load Balance)负载均衡,实现最多的也是SLB、那么SLB它的调度节点和服务节点通常是在一个地域里面。那么它在这个小的逻辑地域里面决定了他对部分服务的实时性、响应性是非常好的。
- 所以说当海量用户请求过来以后,它同样是请求调度节点,调度节点将用户的请求转发给后端对应的服务节点,服务节点处理完请求后在转发给调度节点,调度节点最后响应给用户节点。这样也能实现一个均衡的作用,那么Nginx则是一个典型的SLB!
负载均衡语法
# ngx_http_upstream_module
#语法
Syntax: upstream name { ... }
Default: —
Context: http
#例子
# 在配置文件内,准备连接池,代理转发至连接池
upstream supermarie {
server 172.16.1.7:80;
server 172.16.1.8:80;
server 172.16.1.9:80;
}
server {
... ...
location / {
proxy_pass http://supermarie;
}
}
# 这样就实现了负载均衡.
负载均衡实现案例
1.准备工作
服务器 | IP |
lb01 | 172.16.1.31 |
web01 | 172.16.1.7 |
web02 | 172.16.1.8 |
web03 | 172.16.1.9 |
首先在三台服务器配置好超级玛丽游戏
2.服务器
将后端服务打包成一个IP连接池。
[root@lb01 conf.d]# vim supermary.conf
# 定义一个IP连接池
upstream supermary {
server 172.16.1.7:80;
server 172.16.1.8:80;
server 172.16.1.9:80;
}
server {
listen 80;
server_name py.test1.com;
location / {
proxy_pass http://supermary;
include /etc/nginx/proxy_params;
}
}
3.验证
轮循
默认情况Nginx负载均衡的轮循环状态,即接收的请求按顺序依次分配
1.负载均衡服务器
[root@lb01 conf.d]# vim supermary.conf
# 定义一个IP连接池
upstream supermary {
server 172.16.1.7:80;
server 172.16.1.8:80;
server 172.16.1.9:80;
}
server {
listen 80;
server_name py.test1.com;
location / {
proxy_pass http://supermary;
include /etc/nginx/proxy_params;
}
}
2.后端服务器
# 在web01服务器
[root@web01 Super_Mary]# pwd
/opt/Super_Mary
[root@web01 Super_Mary]# echo web01 > web.html
# 在web02服务器
[root@web02 Super_Mary]# pwd
/opt/Super_Mary
[root@web02 Super_Mary]# echo web02 > web.html
# 在web03服务器
[root@web03 Super_Mary]# pwd
/opt/Super_Mary
[root@web03 Super_Mary]# echo web03 > web.html
3.验证
在浏览器输入http://py.test1.com/web.html,显示结果
结果显示平均分配
权重
Nginx中的权重0-100,数字越大,权重越高。
语法
upstream supermary {
server 172.16.1.7:80 weight=9;
server 172.16.1.8:80 weight=5;
server 172.16.1.9:80 weight=1;
}
验证
在浏览器输入http://youxi.com/web.html,显示的结果为
ip_hash(固定ip)
每一个IP固定访问某一个后端
负载均衡服务器
[root@lb01 conf.d]# vim supermary.conf
upstream supermary {
server 172.16.1.7:80;
server 172.16.1.8:80;
server 172.16.1.9:80;
ip_hash; # 在这定义
}
server {
listen 80;
server_name youxi.com;
location / {
proxy_pass http://supermary;
include /etc/nginx/proxy_params;
}
}
验证
浏览器输入http://youxi.com/web.html,显示的结果为
由此可得ip已经被固定访问一台服务器
负载均衡后端的状态
状态 | 概述 |
down | 当前的server暂时不参与负载均衡 |
backup | 预留的备份服务器 |
max_fails | 允许请求失败的次数 |
fail_timeout | 经过max_fails失败后, 服务暂停时间 |
down
指定服务器暂时不分配流量
[root@lb01 conf.d]# vim supermary.conf
upstream supermary {
server 172.16.1.7:80 down; # 指定这台服务器暂不分配流量
server 172.16.1.8:80;
server 172.16.1.9:80;
}
server {
listen 80;
server_name youxi.com;
location / {
proxy_pass http://supermary;
include /etc/nginx/proxy_params;
}
}
backup
只有当所有的机器全部宕机,才能启动。
[root@lb01 conf.d]# vim supermary.conf
upstream supermary {
server 172.16.1.7:80 backup; # 在这调用
server 172.16.1.8:80;
server 172.16.1.9:80;
}
server {
listen 80;
server_name youxi.com;
location / {
proxy_pass http://supermary;
include /etc/nginx/proxy_params;
}
}
只有web02和web03都宕机web01才会被分配流量
max_fails、fail_timeout
max_fails表示允许请求失败的次数,fail_timeout表示经过max_fails失败后, 服务暂停的时间。
需要与proxy_next_upstream配合使用,由proxy_next_upstream标识错误
作用: 如果其中有一台服务器出了问题,会把它标识然后会把它排除,过会再把流量分配给它
[root@lb01 ~]# vim /etc/nginx/conf.d/game.conf
upstream supermary {
server 172.16.1.7:80 max_fails=3 fail_timeout=3s;
server 172.16.1.8:80 max_fails=3 fail_timeout=3s;
server 172.16.1.9:80 max_fails=3 fail_timeout=3s;
}
server {
listen 80;
server_name youxi.com;
location / {
proxy_pass http://supermary;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_404;
include /etc/nginx/proxy_params;
}
}
error # 与服务器建立连接,向其传递请求或读取响应头时发生错误;
timeout # 在与服务器建立连接,向其传递请求或读取响应头时发生超时;
invalid_header # 服务器返回空的或无效的响应;
http_500 # 服务器返回代码为500的响应;
http_502 # 服务器返回代码为502的响应;
http_503 # 服务器返回代码为503的响应;
http_504 # 服务器返回代码504的响应;
http_403 # 服务器返回代码为403的响应;
http_404 # 服务器返回代码为404的响应;
http_429 # 服务器返回代码为429的响应(1.11.13);
non_idempotent # 通常,请求与 非幂等 方法(POST,LOCK,PATCH)不传递到请求是否已被发送到上游服务器(1.9.13)的下一个服务器; 启用此选项显式允许重试此类请求;
off # 禁用将请求传递给下一个服务器。
负载均衡部署BBS
部署后端服务
之前我们把web01里BBS部署成功了,所以只需要部署web02和web03上的BBS
1.部署Python
在web02、03上
1、创建用户
[root@web01 opt]# groupadd django -g 888
[root@web01 opt]# useradd django -u 888 -g 888 -r -M -s /bin/sh
2、安装依赖软件
[root@web01 opt]# yum install python3 libxml* python-devel gcc* pcre-devel openssl-devel python3-devel -y
2.部署Django和uwsgi
3、安装Django和uwsgi
[root@web01 opt]# pip3 install django==1.11
[root@web01 opt]# pip3 install uwsgi
[root@web01 opt]# pip3 install pymysql
# 因为之前在web01里已经进行了数据库迁移,所以现在db01上已经有bbs的数据库信息了,就不需要再次做迁移
4、创建项目
[root@web01 opt]# unzip bbs.zip
[root@web03 bbs]# pwd
/opt/bbs
[root@web03 bbs]# vim bbs/settings.py
ALLOWED_HOSTS = ['*']
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'bbs',
'USER': 'root',
'PASSWORD': '123',
'HOST': '172.16.1.61',
'PORT': 3306,
'CHARSET': 'utf8'
}
}
# 启动测试
[root@web01 bbs]# python3 manage.py runserver 0.0.0.0:8000
3.配置并启动
5、编辑项目配置文件
[root@localhost ~]# vim /opt/bbs/myweb_uwsgi.ini
[uwsgi]
# 端口号
socket = :8000
# 指定项目的目录
chdir = /opt/bbs
# wsgi文件路径
wsgi-file = bbs/wsgi.py
# 模块wsgi路径
module = bbs.wsgi
# 是否开启master进程
master = true
# 工作进程的最大数目
processes = 4
# 结束后是否清理文件
vacuum = true
6、启动uwsgi
[root@web01 linux]# uwsgi -d --ini myweb_uwsgi.ini --uid 666
-d : 以守护进程方式运行
--ini : 指定配置文件路径
--uid : 指定uid
7、编辑Nginx配置文件
[root@localhost ~]# vim /etc/nginx/conf.d/python.conf
server {
listen 80;
server_name py.test.com;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8000;
uwsgi_read_timeout 2;
uwsgi_param UWSGI_SCRIPT bbs.wsgi;
uwsgi_param UWSGI_CHDIR /opt/bbs;
index index.html index.htm;
client_max_body_size 35m;
}
}
8、重启Nginx配置
systemctl restart nginx
部署负载均衡
[root@lb01 conf.d]# vim python.conf
upstream bbs {
server 172.16.1.7:80 max_fails=3 fail_timeout=3s;
server 172.16.1.8:80 max_fails=3 fail_timeout=3s;
server 172.16.1.9:80 max_fails=3 fail_timeout=3s;
}
server {
listen 80;
server_name py.test.com;
location / {
proxy_pass http://bbs;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_404;
include /etc/nginx/proxy_params;
}
}