• 为什么要使用负载均衡
  • 解决web服务器的单点故障,让web服务器做成一个集群
  • 将请求平均下发给后端的web服务器

Nginx实现七层负载均衡_服务器

负载均衡的叫法

LB:Load Balance

SLB:Server Load Balance

公有云中的叫法

阿里云:SLB

腾讯云:CLB

青云:QLB(LB)

ucloud:ULB

AWS:ELB

负载均衡产品

  • 软件
  • Nginx
  • HAproxy
  • LVS
  • 硬件
  • F5

四层负载均衡和七层负载均衡的区别

  • 1.一个是四层:传输层,一个是七层:应用层
  • 2.四层传输速度要比七层快
  • 3.四层无法识别域名,七层可以识别域名

负载均衡实现场景

Nginx要实现负载均衡需要用到 proxy_pass 代理模块配置 Nginx负载均衡与Nginx代理不同地方在于,Nginx的一个 location 仅能代理一台服务器,而Nginx负载均衡则是 将客户端请求代理转发至一组upstream虚拟服务池.

Nginx实现七层负载均衡_nginx_02

负载均衡

Syntax: upstream name { ... }
Default: —
Context: http


upstream name {
server xxx;
server xxx;
}

官方案例配置

## upstream模块配置
模块名 后端主机池:名字(根据网站域名起名)
upstream backend {
server backend1.example.com weight=5;
server backend2.example.com:8080;
server unix:/tmp/backend3;

server backup1.example.com:8080 backup;
server backup2.example.com:8080 backup;
}

server {
location / {
proxy_pass http://backend;
}
}

upstream blog.yjt.com {
server 172.16.1.7:8888;
server 172.16.1.8;
}

server {
location / {
proxy_pass http://blog.yjt.com;
}
}

配置负载均衡

环境准备

主机名

WanIP

LanIP

角色

应用

lb01

10.0.0.5

172.16.1.5

负载均衡

nginx

web01

10.0.0.7

172.16.1.7

web网站

nginx、php

web02

10.0.0.8

172.16.1.8

web网站

nginx、php

编辑nginx配置文件

[root@web01 conf.d]# vim /etc/nginx/conf.d/lb.yjt.com.conf
server{
listen 9999;
server_name lb.yjt.com;
root /code/lb;
index index.html;
}

[root@web02 conf.d]# vim /etc/nginx/conf.d/lb.yjt.com.conf
server{
listen 9999;
server_name lb.yjt.com;
root /code/lb;
index index.html;
}

[root@web01 conf.d]# mkdir /code/lb
[root@web02 conf.d]# mkdir /code/lb

[root@web01 conf.d]# echo 'web01' > /code/lb/index.html
[root@web02 conf.d]# echo 'web02' > /code/lb/index.html

[root@web01 conf.d]# nginx -t
[root@web01 conf.d]# systemctl reload nginx

[root@web02 conf.d]# nginx -t
[root@web02 conf.d]# systemctl reload nginx

## 域名解析
10.0.0.7 lb.yjt.com

Nginx实现七层负载均衡_nginx_03

Nginx实现七层负载均衡_nginx_04

# 配置负载均衡
[root@lb01 ~]# vim /etc/nginx/conf.d/lb.yjt.com.conf
upstream lb.yjt.com {
server 172.16.1.7:9999;
server 172.16.1.8:9999;
}
server {
listen 80;
server_name lb.yjt.com;

location /{
proxy_pass http://lb.yjt.com;
include proxy_params;
}
}

负载均衡常见典型故障

如果后台服务连接超时,Nginx是本身是有机制的,如果出现一个节点down掉的时候,Nginx会更据你具体负载均衡 的设置,将请求转移到其他的节点上,但是,如果后台服务连接没有down掉,但是返回错误异常码了如:504、 502、500,这个时候你需要加一个负载均衡的设置,如下:proxy_next_upstream http_500 | http_502 | http_503 | http_504 |http_404;意思是,当其中一台返回错误码404,500...等错误时,可以分配到下一台服务器程序继续处 理,提高平台访问成功率。

## 解决方案
### 遇到如下状态码的机器,跳过请求的下发,直接下发到其他正常的服务器
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;

upstream lb.zls.com {
server 172.16.1.7:9999;
server 172.16.1.8:9999;
server 172.16.1.9:9999;
}
server {
listen 80;
server_name lb.yjt.com;

location /{
proxy_pass http://lb.yjt.com;
proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
include proxy_params;
}
}

负载均衡调度算法

调度算法

概述

轮询(rr)

nginx做负载均衡默认使用轮询的调度算法:将请求平均下发到后端的web服务器

加权轮询(wrr)

增加权重,根据服务器的配置,给轮询加上权重

源IP(ip_hash)

根据用户的IP,将同一IP地址的请求,下发到同一台服务器上

源url(url_hash)

根据用户访问的URL,将同一URL的请求,下发到同一台服务器上

最小连接数

哪台服务器的连接数最少,就将请求下发到该服务器上

Nginx实现七层负载均衡_负载均衡_05

Nginx实现七层负载均衡_负载均衡_06

负载均衡后端状态

# 1.down 状态:只是负载均衡不对该标识的服务器下发请求,后端的服务器并没有真正宕机
upstream lb.yjt.com {
server 172.16.1.7:9999;
server 172.16.1.8:9999 down;
server 172.16.1.9:9999;
}
server {
listen 80;
server_name lb.yjt.com;

location /{
proxy_pass http://lb.yjt.com;
include proxy_params;
}
}

# 2.backup 状态:备份,当前其他没有backup标识机器都宕机时,才会给该服务发请求
upstream lb.yjt.com {
server 172.16.1.7:9999;
server 172.16.1.8:9999 backup;
server 172.16.1.9:9999;
}
server {
listen 80;
server_name lb.yjt.com;

location /{
proxy_pass http://lb.yjt.com;
include proxy_params;
}
}

# 3.额外参数
max_fails:负载均衡访问后端,最大错误次数,到该指定次数后,不给该服务器发送请求
fail_timeout:配合max_fails使用,规定不发请求的时间段
[root@lb01 ~]# vim /etc/nginx/conf.d/lb.yjt.com.conf
upstream lb.yjt.com {
server 172.16.1.7:9999 max_fails=3 fail_timeout=10s;
server 172.16.1.8:9999 max_fails=3 fail_timeout=10s;
server 172.16.1.9:9999 max_fails=3 fail_timeout=10s;
}
server {
listen 80;
server_name lb.yjt.com;

location /{
proxy_pass http://lb.yjt.com;
include proxy_params;
}
}

# 4.max_conn:限制该后端web服务器最大连接数为1024个
upstream lb.yjt.com {
server 172.16.1.7:9999 max_fails=3 fail_timeout=10s;
server 172.16.1.9:9999 max_fails=3 fail_timeout=10s;
server 172.16.1.8:9999 max_fails=3 fail_timeout=10smax_conns=1024;
}
server {
listen 80;
server_name lb.yjt.com;

location /{
proxy_pass http://lb.yjt.com;
include proxy_params;
}
}

nginx负载均衡健康检查模块

作用:为了检测后端web的健康状态

​项目地址TP​

# 0.安装依赖
[root@lb01 nginx-1.22.0]# yum install -y pcre-devel openssl-devel

# 1.停掉yum安装的nginx
[root@lb01 ~]# systemctl stop nginx

# 2.下载nginx源码包
[root@lb01 ~]# wget https://nginx.org/download/nginx-1.22.0.tar.gz

# 3.下载nginx健康检查第三方模块
[root@lb01 ~]# wget https://github.com/yaoweibin/nginx_upstream_check_module/archive/master.zip

# 4.解压nginx源码包和第三方模块包
[root@lb01 ~]# mkdir /app
[root@lb01 ~]# tar xf nginx-1.22.0.tar.gz
[root@lb01 ~]# unzip master.zip

# 5.打补丁
[root@lb01 ~]# cd nginx-1.22.0/
[root@lb01 nginx-1.22.0]# patch -p1 </root/nginx_upstream_check_module- master/check_1.20.1+.patch

# 6.生成
[root@lb01 nginx-1.22.0]# ./configure --prefix=/app/nginx-1.22.0 --with-compat -- with-file-aio --with-threads --with-http_addition_module --with- http_auth_request_module --with-http_dav_module --with-http_flv_module --with- http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with- http_random_index_module --with-http_realip_module --with-http_secure_link_module -- with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with- http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with- stream --with-stream_realip_module --with-stream_ssl_module --with- stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 - fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie' --add- module=/root/nginx_upstream_check_module-master

# 6.编译 && 安装
[root@lb01 nginx-1.22.0]# make && make install

# 7.nginx主配置文件,添加conf.d
[root@lb01 nginx-1.22.0]# vim /app/nginx-1.22.0/conf/nginx.conf
在最后加 `include /app/nginx-1.22.0/conf/conf.d/*.conf;

# 8.创建虚拟主机配置文件存放目录
[root@lb01 conf]# mkdir /app/nginx-1.22.0/conf/conf.d

# 9.编写负载均衡配置文件,添加location
[root@lb01 nginx-1.22.0]# cat /app/nginx-1.22.0/conf/conf.d/lb.yjt.com.conf
upstream lb.yjt.com {
server 172.16.1.7:9999 max_fails=3 fail_timeout=10s;
server 172.16.1.8:9999 max_fails=3 fail_timeout=10s;
server 172.16.1.9:9999 max_fails=3 fail_timeout=10s max_conns=1024;
check interval=3000 rise=2 fall=3 timeout=1000 type=tcp;
#interval 检测间隔时间,单位为毫秒
#rise 表示请求2次正常,标记此后端的状态为up
#fall 表示请求3次失败,标记此后端的状态为down
#type 类型为tcp
#timeout 超时时间,单位为毫秒
}
server {
listen 80;
server_name lb.yjt.com;

location /{
proxy_pass http://lb.yjt.com;
include proxy_params;
}

location /check_health{
check_status;
}
}


# 10.添加proxy_params;
[root@lb01 conf]# cp /etc/nginx/proxy_params /app/nginx-1.22.0/conf
或者在配置文件里添加绝对路径/etc/nginx/proxy_params,一定要有proxy_params这个文件

# 11.语法检测
[root@lb01 conf]# /app/nginx-1.22.0/sbin/nginx -t


# 12.启动nginx
[root@lb01 conf]# /app/nginx-1.22.0/sbin/nginx

# 13.上网测试
http://lb.yjt.com/check_health

Nginx实现七层负载均衡_负载均衡_07

nginx 七层负载-会话共享

会话保持相关信息存储

  • cookie:
  • 前端开发人员将用户登录的信息没保存到浏览器中(开发者工具->Application->Cookies)
  • 如果仅将用户的登录信息记录在Cookie中,随时可以在浏览器中篡改
  • session
  • 后端开发人员,将用户登录信息记录在 服务器上(共享存储,某一个文件夹下的某个文件、数据库中、缓 存数据库中....)session是对cookie做的加密,保存在服务器上

Nginx实现七层负载均衡_服务器_08

部署php Myadmin

环境准备

主机名

WanIP

LanIP

角色

应用

lb01

10.0.0.5

172.16.1.5

负载均衡

nginx

web01

10.0.0.7

172.16.1.7

phpmyadmin网站

nginx,php

web02

10.0.0.8

172.16.1.8

phpmyadmin网站

nginx,php

db01

10.0.0.51

172.16.51

数据库

MariaDB

部署

# 1.下载phpmyadmin代码
[root@web01 code]# wget http://test.driverzeng.com/Nginx_Code/phpMyAdmin-4.9.0.1-all- languages.zip

# 2.解压代码
[root@web01 code]# unzip phpMyAdmin-4.9.0.1-all-languages.zip

# 3.添加nginx虚拟主机配置文件
[root@web01 ~]# vim /etc/nginx/conf.d/php.yjt.com.conf
server{
listen 80;
server_name php.yjt.com;
root /code/phpmyadmin;
index index.php index.html;

location ~ \.php$ {
fastcgi_pass unix:/dev/shm/php.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}

[root@web02 ~]# vim /etc/nginx/conf.d/php.yjt.com.conf
server{
listen 80;
server_name php.yjt.com;
root /code/phpmyadmin;
index index.php index.html;

location ~ \.php$ {
fastcgi_pass unix:/dev/shm/php.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}

# 4.修改代码连接数据库的配置文件
先改名:[root@web01 code]# mv phpMyAdmin-4.9.0.1-all-languages phpmyadmin

将站点目录下的案例配置文件改名
[root@web01 phpmyadmin]# cp config.sample.inc.php config.inc.php
[root@web01 phpmyadmin]# vim config.inc.php
将第31行的localhost改成自己数据库的ip地址
$cfg['Servers'][$i]['host'] = '172.16.1.51';

# 5.web01上的代码发送到web02站点目录下
[root@web01 phpmyadmin]# scp -r /code/phpmyadmin 172.16.1.8:/code/

# 6.nginx重启
[root@web01 phpmyadmin]# systemctl restart nginx
[root@web02 phpmyadmin]# systemctl restart nginx

报错:

存放session的目录没有权限

Nginx实现七层负载均衡_负载均衡_09

[root@web01 phpmyadmin]# chown www.www /var/lib/php/session/
[root@web02 phpmyadmin]# chown www.www /var/lib/php/session/

Nginx实现七层负载均衡_nginx_10

使用数据库的用户名和密码登录:之前的wordpress用户和密码就可以使用

# 1.连接数据库
[root@db01 ~]# mysql -uroot -p123

# 2.创建一个数据库的新用户
MariaDB [(none)]> grant all on *.* to phpadmin@'%' identified by '123';

登录的用户名:phpadmin 登录的密码:123

添加phpmyadmin的均衡负载

# 1.在负载均衡上添加nginx配置文件
[root@lb01 ~]# vim /etc/nginx/conf.d/php.yjt.com.conf

upstream php.yjt.com {
server 172.16.1.7;
server 172.16.1.8;
}
server {
listen 80;
server_name php.yjt.com;

location /{
proxy_pass http://php.yjt.com;
include proxy_params;
}
}

# 2.将域名解析到负载均衡
10.0.0.5 php.yjt.com

报错

用户的登录信息,session没有做共享

Nginx实现七层负载均衡_负载均衡_11

制作session共享

##  redis端口:6379

# 1.在db01上安装redis数据库
[root@db01 ~]# yum install -y redis

# 2.修改redis配置文件
[root@db01 ~]# vim /etc/redis.conf
将第61行的bind后面IP地址改为 0.0.0.0
bind 0.0.0.0

# 3.启动服务
[root@db01 ~]# systemctl start redis

# 4.修改php程序配置文件
[root@web01 phpmyadmin]# vim /etc/php.ini
1231 session.save_handler = files
将以上内容改为以下内容
session.save_handler = redis

在第1265行添加如下内容
session.save_path = "tcp://172.16.1.51:6379"

1295 session.auto_start = 0
将以上内容改为以下内容
session.auto_start = 1

# 5.修改php启动程序配置文件、
[root@web01 phpmyadmin]# vim /etc/php-fpm.d/www.conf
源配置
398 php_value[session.save_handler] = files
399 php_value[session.save_path] = /var/lib/php/session

将以上两行内容使用';'注释
;php_value[session.save_handler] = files
;php_value[session.save_path] = /var/lib/php/session

# 6.重启php
[root@web01 phpmyadmin]# systemctl restart php-fpm

# 7.将改好的配置文件拷贝到web02
[root@web01 phpmyadmin]# scp /etc/php.ini 172.16.1.8:/etc/
[root@web01 phpmyadmin]# scp /etc/php-fpm.d/www.conf 172.16.1.8:/etc/php-fpm.d/

# 8.重启web02上的php
# 9.重新去网上输入域名php.yjt.com,然后登陆密码账号进入