03-Nginx代理负载均衡

一、nginx代理

1、什么是代理

正向代理:作用在浏览器和客户端。是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。

正向代理类似一个跳板机,代理访问外部资源。

正向代理的好处:(1)能够隐藏用户的信息(前提是代理服务器隐藏用户信息,高匿代理),因为服务器只知道正向代理的信息,不知道用户的信息。(2)访问被墙的网站。(3)可以做缓存,加速访问资源。(4)对客户端访问授权,上网进行认证。

反向代理:作用在服务器。例如nginx,是给服务器进行分流导航。

反向代理的好处:1. 保证内网(服务器真实的网络)的安全,可以使用反向代理提供WAF功能,阻止web攻击。2.负载均衡,通过反向代理服务器来优化网站的负载,分流功能。

总体图:

2、反向代理支持模式

http            用户请求  响应        JAVA
smtp
websocket        用户可以请求,  服务端响应   服务端可以推送数据
uwsgi            Python
fastcgi            PHP
https

3、代理配置语法

proxy_pass
    proxy_pass http://127.0.0.1:8080;

代理节点的配置  ******* 主机 10.0.0.100 *******

[root@proxy ~]# systemctl disable firewalld
[root@proxy ~]# systemctl stop firewalld
[root@proxy ~]# setenforce 0


    #安装epel
ginx
[root@proxy ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
[root@proxy ~]# yum install vim wget unzip nginx -y

    # 清理nginx.conf 无用的配置
    
    # 将nginx加入开机自启 启动nginx
[root@proxy ~]# systemctl start nginx
[root@proxy ~]# systemctl enable nginx


    # 编写proxy配置文件
[root@proxy ~]# vim /etc/nginx/conf.d/proxy_proxy.workedu.com.conf
server {
    listen 80;
    server_name proxy.workedu.com;

    location / {
        proxy_pass http://10.0.0.201;                    # 后端是什么端口根本不重要
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
    }
}

    # 检查语法,重载服务
[root@proxy ~]# nginx -t
[root@proxy ~]# systemctl restart nginx

用户请求代理
抓包分析: 提炼了几个参数:
proxy_set_header Host $http_host; # 将用户请求的域名携带到后端
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 将用户的真实IP地址,携带到后端,后端有对应的变量解析结果
proxy_http_version 1.1; # 代理请求后端默认走http1.0, 可以调整为http1.1 长连接

web节点的配置  ******* 10.0.0.201 *******

[root@node2 conf.d]# cat proxy.workedu.com.conf 
server {
    listen 80;
    server_name proxy.workedu.com;
    root /code/proxy;

    location / {
        index index.html;
    }
}
[root@node2 conf.d]# mkdir /code/proxy -p
[root@node2 conf.d]# echo "node2...." >> /code/proxy/index.html

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

二、负载均衡

代理并没有解决代理多个web节点,代理延伸出来的一个负载均衡可以实现代理多个web节点

1、什么是负载均衡

负载均衡Load Balance,指的是将工作任务进行平衡,分摊到多个操作单元上运行。

2、为什么需要使用负载均衡

当我们的web服务器直接面向用户,往往要承载大量并发请求,单台服务器难以负荷,我使用多台web服务器组成集群,前端使用Nginx负载均衡,将请求分散的打到我们的后台服务器集群中,实现负载的分发。从而提升整体性能,以及系统的容灾能力。

2.1、负载均衡能实现的应用场景一:四层负载均衡

所谓四层负载均衡指的是OSI七层模型中的传输层,四层仅需要对客户端的请求进行TCP/IP协议的包转发就可以实现负载均衡.四层负载均衡的性能极好、因为只需要底层进行转发处理,而不需要进行一些复杂的逻辑。

2.2、负载均衡能实现的应用场景二:七层负载均衡

七层负载均衡它是在应用层,那么它可以完成很多方面的协议请求,比如我们说Http应用负载均衡,它可以实现http头信息的改写、安全应用规则控制、URI匹配规则控制、及rewrite等功能,所以在应用层里面可以做的内容就更多了。

2.3、四层负载均衡与七层负载均衡区别

四层负载均衡数据包在底层就进行了开发,而七层负载均衡数据包则是在最顶层进行分发,由此可以看出,七层负载均衡效率没有四层负载均衡效率高。

七层负载均衡更贴近于服务,如http协议就是七层协议,我们可以用Nginx可以作URI路径规则匹配、head改写、Rewrite、会话保持等,这些是四层负载均衡无法实现的。

3、Nginx负载均衡配置场景

nginx要实现负载均衡需要用到proxy_pass和upstream两个模块

nginx负载均衡与Nginx反向代理不同地方在于,nginx代理仅代理一台服务器,而Nginx负载均衡则是将客户端请求通过proxy_pass代理至一组upstream资源池

upstream 定义虚拟资源池  ( 将应用服务器逻辑定义为资源池 )

proxy_pass  代理

Syntax: upstream name { ... }
Default : -
Context: http
# upstream例
upstream backend {
    server backend1.example.com   weight=5;
    server backend2.example.com:8000;
    server unix:/tmp/backend3;
    server backup1.example.com:8000  backup;            
}
server {
    location / {
        proxy_pass http://backend;    
    }
} 

 三、多台应用服务器节点的配置

node1: 10.0.0.200
node2: 10.0.0.201
域名: proxy.workedu.com

node1 nginx配置

vim /etc/nginx/conf.d/proxy.workedu.com.conf
server {
    listen 80;
    server_name proxy.workedu.com;
    root /code/proxy;

    location / {
        index index.html;
    }
}
mkdir /code/proxy -p
echo "node1...." > /code/proxy/index.html
systemctl reload nginx

node2 nginxx配置:

vim /etc/nginx/conf.d/proxy.workedu.com.conf
server {
    listen 80;
    server_name proxy.workedu.com;
    root /code/proxy;

    location / {
        index index.html;
    }
}
mkdir /code/proxy -p
echo "node2...." > /code/proxy/index.html
systemctl reload nginx

1、通过nginx负载均衡进行轮训调度

proxy: 10.0.0.100
域名: proxy.workedu.com
vim /etc/nginx/conf.d/proxy_proxy.workedu.com.conf 
upstream node {
    server 10.0.0.200:80;
    server 10.0.0.201:80;
}

server {
    listen 80;
    server_name proxy.workedu.com;

    location / {
        proxy_pass http://node;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
    }
}
nginx -t
systemctl reload nginx

2、调度算法

1、轮询:        默认

2、加权轮询:
    upstream node {
        server 10.0.0.200:80 weight=5;
        server 10.0.0.201:80 weight=1;
    }
静态的,固定200分发5次, 201分发1次,没有办法做到动态

3、ip_hash:    固定将请求调度至某一个节点.  ( session会话保存 )
upstream node {
        ip_hash;
        server 10.0.0.200:80;
        server 10.0.0.201:80;
    }

轮训存在的问题:

"""
nginx轮训到node1存储session id返回cookie存储在浏览器
浏览器携带cookie第二次访问nginx轮训到node2发现没有session与cookie对应
再返回一个cookie值存储在浏览器
导致用户永远都登录不上
"""

为了解决这个问题,有了ip_hash的调度算法(解决session会话保持)

问题:

# 如果来源的都是同一个IP地址,则会造成某一个节点非常的繁忙,而其他的节点没有流量,造成负载不均衡的现象.

解决:

"""
用户访问时,nginx分发到节点,节点先去Redis查找有没有对应的session_id,没有将cookie写入浏览器,
浏览器下次访问携带cookie,另一节点也先去Redis中查找,发现有与cookie对应的session_id,登录成功
"""

四、nginx_proxy + web应用节点(多台) + Redis会话保持

1、搭建好应用节点   ( 所有节点保持一致 )

wget https://files.phpmyadmin.net/phpMyAdmin/5.0.3/phpMyAdmin-5.0.3-all-languages.zip

2、准备phpmyadmin的Nginx配置文件

server {
    listen 80;
    server_name phpmyadmin.workedu.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;
    }
}
systemctl reload nginx
unzip phpMyAdmin-5.0.3-all-languages.zip
mv phpMyAdmin-5.0.3-all-languages /code/phpmyadmin

3、配置phpmyadmin连接数据库地址

cp /code/phpmyadmin/config.sample.inc.php /code/phpmyadmin/config.inc.php

vim
/code/phpmyadmin/config.inc.php /* Server parameters */ $cfg['Servers'][$i]['host'] = '10.0.0.202';

4、授权session存储本地目录为进程的用户身份

chown -R nginx.nginx /var/lib/php/session

5、部署node2节点的phpmyadmin, 需要将代码和nginx配置拷贝一份

scp -rp root@10.0.0.200:/code/phpmyadmin /code/
chown -R nginx.nginx /code/phpmyadmin/
scp root@10.0.0.200:/etc/nginx/conf.d/phpadmin.workedu.com.conf /etc/nginx/conf.d/
chown -R nginx.nginx /var/lib/php/session/
nginx -t
systemctl reload nginx

6、为应用节点,接入负载均衡

vim /etc/nginx/conf.d/proxy_phpadmin.workedu.com.conf
upstream php {
    server 10.0.0.200:80;
    server 10.0.0.201:80;
}

server {
    listen 80;
    server_name phpmyadmin.workedu.com;
    
    location / {
        proxy_pass http://php;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    
    }
}    

7、检查轮询是否会造成无法登陆情况, 配置IP_hash测试是否能正常登陆(可试可不试)

轮询一定会造成无法登陆成功.

可以采用ip_hash的方式解决.
upstream php {
    ip_hash;
    server 10.0.0.200:80;
    server 10.0.0.201:80;
}

8、采用Redis共享的方式来解决会话无法登陆的问题,  需要先将负载均衡恢复至轮询模式,然后在继续.

1、安装Redis 10.0.0.202

yum install redis -y
vim /etc/redis.conf    # 添加本机的内网IP地址 ( 不要写错了 )
bind 127.0.0.1 10.0.0.202
systemctl enable redis
systemctl start redis
netstat -lntp | grep redis
# tcp        0      0 10.0.0.202:6379         0.0.0.0:*               LISTEN      10699/redis-server  
# tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      10699/redis-server 

2、通过其他的节点测试是否能正常访问Redis

yum install redis -y
redis-cli -h 10.0.0.202

3、配置应用节点接入Redis,  [ 应用程序php必须有redis的模块,否则无法正常连接 ]   两个节点配置一样,都需要操作

# 将应用程序解析器连接至 Redis 
# vim /etc/php.ini
[Session]
;session.save_handler = files        #注释掉
session.save_handler = redis
session.save_path = "tcp://10.0.0.202:6379?weight=1&timeout=2.5"

# 注释如下两行内容
[root@oldboy-pythonedu ~]# 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@oldboy-pythonedu ~]# systemctl restart php-fpm

测试是否能正常登陆,然后检查浏览器中的session是否与redis中存储的session一致.

[root@node-mysql ~]# redis-cli
    127.0.0.1:6379> keys *
    1) "python_key"
    2) "PHPREDIS_SESSION:f0ad1e364f79a85bd93b46883403f6ec"
原文地址:https://www.cnblogs.com/kongxiangqun/p/13812238.html