Nginx-正反向代理及负载均衡

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
网络型负载均衡 NLB,每月750个小时 15LCU
简介: Nginx-正反向代理及负载均衡目录正/反向代理代理的方式Nginx代理服务支持的协议代理实战部署web01部署Lb01Nginx代理常用参数添加发往后端服务器的请求头信息代理到后端的TCP连接、响应、返回等超时时间proxy_buffer代理缓冲区配置代理优化文件

Nginx-正反向代理及负载均衡


Nginxyouhuiquan.png

目录

  • 正/反向代理
  • 代理的方式
  • Nginx代理服务支持的协议
  • 代理实战
  • 部署web01
  • 部署Lb01
  • Nginx代理常用参数
  • 添加发往后端服务器的请求头信息
  • 代理到后端的TCP连接、响应、返回等超时时间
  • proxy_buffer代理缓冲区
  • 配置代理优化文件
  • 负载均衡
  • 负载均衡的架构
  • 负载均衡的实现
  • 连接池
  • 实现步骤
  • 负载均衡的比例
  • 轮询
  • 权重
  • ip_hash
  • 负载均衡后端状态
  • down
  • backup
  • max_fails、fail_timeout
  • proxy_next_upstream监控的错误类型
  • 负载均衡部署BBS
  • 部署后端服务
  • 部署Python
  • 部署Django和uwsgi
  • 配置并启动uwsgi
  • 部署负载均衡
  • 补充
  • 页面出现502问题原因

 

正/反向代理

代理的作用是将流量分配

代理的方式

  • 正向代理:找完正向代理之后,还需要找服务器(无法直接访问到目标服务器)
  • 应用:VPN

  • 反向代理:只需要找反向代理,不需要找服务器
  • 应用:负载均衡

Nginx代理服务支持的协议

👉nginx官网

模块 代理语言
ngx_http_uwsgi_module Python
ngx_http_fastcgi_module PHP
ngx_http_scgi_module Java
ngx_http_v2_module Golang
ngx_http_proxy_module HTTP

代理实战#

Lb01虚拟机代理Web01

部署web01#

搭建马里奥小游戏

[root@web01 conf.d]# vim Mario.conf 
server{
    listen 80;
    server_name 192.168.15.7;
    location / {
  root /opt/Super_Mario;
        index index.html;    
    }
    location ~ /images {
        root /opt/image;
    }
}

部署Lb01#

  • Lb01部署Nginx
# 下载Nginx源代码包
[root@lb01 ~]# wget https://nginx.org/download/nginx-1.20.2.tar.gz
# 解压
[root@lb01 ~]# tar -xf nginx-1.20.2.tar.gz
# 进入源代码目录
[root@lb01 ~]# cd nginx-1.20.2
# 安装依赖包
[root@lb01 nginx-1.20.2]# yum install openssl openssl-devel zlib zlib-devel -y
# 设置编译参数
[root@lb01 nginx-1.20.2]# ./configure  --with-http_gzip_static_module    --with-stream     --with-http_ssl_module
# 编译
[root@lb01 nginx-1.20.2]# make 
# 安装
[root@lb01 nginx-1.20.2]# make install 
# 优化
[root@lb01 nginx]# mkdir /etc/nginx
[root@lb01 nginx]# mv /usr/local/nginx/conf/* /etc/nginx/
[root@lb01 nginx]# mkdir /etc/nginx/conf.d
# 修改配置文件(拷贝以下web01的),统一内容
[root@web01 ~]# cat /etc/nginx/nginx.conf
    # 拷贝到lb01配置文件中
[root@lb01 nginx]# vim /etc/nginx/nginx.conf
[root@lb01 nginx]# groupadd www -g 666
[root@lb01 nginx]# useradd www -u 666 -g 666 -M -r -s /sbin/nologin
[root@lb01 nginx]# vim /usr/lib/systemd/system/nginx.service
[Unit]
Description=nginx - high performance web server
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=/var/run/nginx.pid
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/bin/sh -c "/bin/kill -s HUP $(/bin/cat /var/run/nginx.pid)"
ExecStop=/bin/sh -c "/bin/kill -s TERM $(/bin/cat /var/run/nginx.pid)"
[Install]
WantedBy=multi-user.target
[root@lb01 sbin]# ln -s /etc/nginx/nginx.conf /usr/local/nginx/conf/nginx.conf
[root@lb01 sbin]# mv /usr/local/nginx/sbin/nginx /usr/sbin/
# 重载 
[root@lb01 sbin]# systemctl daemon-reload
[root@lb01 sbin]# mkdir /var/log/nginx
[root@lb01 sbin]# systemctl start nginx 
# 查看模块
[root@lb01 nginx]# nginx -V
  • 部署反向代理
[root@lb01 conf.d]# vim /etc/nginx/conf.d/game.conf 
server {
    listen 80;
    server_name _;
    location / {
        proxy_pass http://172.16.1.7:80;
    }
}
# 测试
真机访问192.168.15.5(lb01)


Nginx代理常用参数

添加发往后端服务器的请求头信息#

通过tail -f /var/log/nginx/access.log监控日志,发现客户端ip是lb01的,通过以下三个参数修改就能记录真实的客户端ip

Syntax:    proxy_set_header field value;
Default:    proxy_set_header Host $http_host;
            proxy_set_header Connection close;
Context:    http, server, location
# 用户请求的时候HOST的值是linux.proxy.com, 那么代理服务会像后端传递请求的还是linux.proxy.com
proxy_set_header Host $http_host;
# 将$remote_addr的值放进变量X-Real-IP中,$remote_addr的值为客户端的ip
proxy_set_header X-Real-IP $remote_addr;
# 客户端通过代理服务访问后端服务, 后端服务通过该变量会记录真实客户端地址
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 添加参数
[root@lb01 nginx]# vim /etc/nginx/conf.d/game.conf
server {
    listen 80;
    server_name _;
    location / {
        proxy_pass http://172.16.1.7:80;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
[root@lb01 nginx]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@lb01 nginx]# systemctl restart nginx

再次监控web01,发现真实ip为”xff”: "192.168.15.1"

代理到后端的TCP连接、响应、返回等超时时间#

#nginx代理与后端服务器连接超时时间(代理连接超时)
Syntax: proxy_connect_timeout time;
Default: proxy_connect_timeout 60s;
Context: http, server, location
#nginx代理等待后端服务器的响应时间
Syntax:    proxy_read_timeout time;
Default:    proxy_read_timeout 60s;
Context:    http, server, location
#后端服务器数据回传给nginx代理超时时间
Syntax: proxy_send_timeout time;
Default: proxy_send_timeout 60s;
Context: http, server, location
# 添加以下参数
proxy_connect_timeout 1s;   # 连接时间
proxy_read_timeout 3s;     # 响应时间
proxy_send_timeout 3s;     # 回传代理时间
[root@lb01 nginx]# cat /etc/nginx/conf.d/game.conf
server {
    listen 80;
    server_name _;
    location / {
        proxy_pass http://172.16.1.7:80;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        # -----------------------------------------------------
        proxy_connect_timeout 1s;
        proxy_read_timeout 3s;
        proxy_send_timeout 3s;
    }
}

proxy_buffer代理缓冲区#

代理缓冲区的存在增快了访问速度

#nignx会把后端返回的内容先放到缓冲区当中,然后再返回给客户端,边收边传, 不是全部接收完再传给客户端
Syntax: proxy_buffering on | off;
Default: proxy_buffering on;  
Context: http, server, location
#设置nginx代理保存用户头信息的缓冲区大小
Syntax: proxy_buffer_size size;
Default: proxy_buffer_size 4k|8k;
Context: http, server, location
#proxy_buffers 缓冲区
Syntax: proxy_buffers number size;
Default: proxy_buffers 8 4k|8k;
Context: http, server, location
proxy_buffering on; 
proxy_buffer_size 8k;
proxy_buffers 8 8k;
# 添加参数
proxy_buffering on;  # 打开缓冲区
proxy_buffer_size 8k;   # 缓冲区大小,设置为8kb
proxy_buffers 8 8k;   # 8个缓冲区,每个缓冲区8kb
[root@lb01 nginx]# cat /etc/nginx/conf.d/game.conf
server {
    listen 80;
    server_name _;
    location / {
        proxy_pass http://172.16.1.7:80;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        # -----------------------------------------------------
        proxy_connect_timeout 1s;
        proxy_read_timeout 3s;
        proxy_send_timeout 3s;
        # ----------------------------------------------------
        proxy_buffering on;
        proxy_buffer_size 8k;
        proxy_buffers 8 8k;
    }
}

配置代理优化文件#

因为上面参数在配置的时候是不需要修改的,通过写入到文件内来优化

[root@lb01 ~]# cd /etc/nginx/
[root@lb01 ~]# vim /etc/nginx/proxy_params 
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_connect_timeout 10s;
proxy_read_timeout 10s;
proxy_send_timeout 10s;
proxy_buffering on;
proxy_buffer_size 8k;
proxy_buffers 8 8k;
# 编辑配置文件,通过添加外部配置文件-include,就不需要写上述的参数了
[root@lb01 conf.d]# vim game.conf 
server {
    listen 80;
    server_name _;
    location / {
        proxy_pass http://172.16.1.7:80;
        include /etc/nginx/proxy_params;
    }
}
# 测试
通过监控进程来查看真实ip是否为本机访问的真实ip即可
tail -f /var/log/nginx/access.log

负载均衡

为什么要用负载均衡?

可以拓展代理,使用负载均衡可以代理多个主机,

负载均衡的架构#

通过代理将流量按照一定的比例,转发到后端。

负载均衡的实现#

连接池#

将后端服务打包成一个IP连接池。
1、反向代理格式
server {
    listen 80;
    server_name _;
    location / {
        proxy_pass http://[连接池];
    }
}
2、IP连接池格式
upstream [连接池名称] {
    server [ip]:[port];
    server [ip]:[port];
    server [ip]:[port];
}

实现步骤#

# 搭建
web02和web03 用nginx搭建马里奥小游戏
1、上传文件到/opt/目录下
[root@web01 conf.d]# scp Super_Mario.tar.gz 172.16.1.8:/opt/
[root@web01 conf.d]# scp Super_Mario.tar.gz 172.16.1.9:/opt/
2、下载nginx : yum install nginx
3、编辑配置文件:Mario.conf
[root@web01 conf.d]# scp Mario.conf 172.16.1.8:/etc/nginx/conf.d/
[root@web01 conf.d]# scp Mario.conf 172.16.1.9:/etc/nginx/conf.d/
4、修改配置文件和web01统一
[root@web01 conf.d]# scp /etc/nginx/nginx.conf 172.16.1.8:/etc/nginx/nginx.conf 
[root@web01 conf.d]# scp /etc/nginx/nginx.conf 172.16.1.9:/etc/nginx/nginx.conf 
5、web02和web03测试配置文件和重启服务
 nginx -t -c /etc/nginx/nginx.conf
 systemctl restart nginx 
# lb01实现负载均衡
6、创建连接池
[root@lb01 conf.d]# vim /etc/nginx/conf.d/game.conf
upstream supermarie {
    server 172.16.1.7:80;
    server 172.16.1.8:80;
    server 172.16.1.9:80;
}
server {
    listen 80;
    server_name _;
    location / {
        proxy_pass http://supermarie;
        include /etc/nginx/proxy_params;
    }
}
[root@lb01 conf.d]# nginx -t
[root@lb01 conf.d]# systemctl restart nginx 
# 测试真机访问lb01 ip

这样的负载均衡访问,访问流量是平均分配的,如何实现负载均衡流量比例不一样呢?👉负载均衡比例

负载均衡的比例#

流量比例示例如下

轮询#

# 通过web01字符显示示例
[root@web01 Super_Mario]# echo Web01 > web.html
[root@web01 Super_Mario]# echo Web02 > web.html
[root@web01 Super_Mario]# echo Web03 > web.html
# 默认情况下,Nginx负载均衡的轮询状态。
upstream supermarie {
    server 172.16.1.7:80;
    server 172.16.1.8:80;
    server 172.16.1.9:80;
}

权重#

# Nginx中的权重0-100,数字越大,权重越高。
upstream supermarie {
    server 172.16.1.7:80 weight=9;
    server 172.16.1.8:80 weight=5;
    server 172.16.1.9:80 weight=1;
}
# 这样web01获得流量分配的几率就大

ip_hash#

# 每一个IP固定访问某一个后端。
upstream supermarie {
    server 172.16.1.7:80;
    server 172.16.1.8:80;
    server 172.16.1.9:80;
    ip_hash;
}
# 这样就固定访问web01服务器ip,172.16.1.7

负载均衡后端状态#

状态 概述
down 当前的server暂时不参与负载均衡
backup 预留的备份服务器
max_fails 允许请求失败的次数
fail_timeout 经过max_fails失败后, 服务暂停时间

down#

# 暂时不分配流量
upstream supermarie {
    server 172.16.1.7:80 down;
    server 172.16.1.8:80;
    server 172.16.1.9:80;
}
server {
    listen 80;
    server_name _;
    location / {
        proxy_pass http://supermarie;
        include /etc/nginx/proxy_params;
    }
}
# 这样172.16.1.7这个服务器暂时就不会分配流量,不参与负载均衡

backup#

# 只有当所有的机器全部宕机,才能启动。
upstream supermarie {
    server 172.16.1.7:80 backup;
    server 172.16.1.8:80;
    server 172.16.1.9:80;
}
server {
    listen 80;
    server_name _;
    location / {
        proxy_pass http://supermarie;
        include /etc/nginx/proxy_params;
    }
}
# 这样只有web02和web03宕机了才会访问172.16.1.7服务器

max_fails、fail_timeout#

max_fails、fail_timeout一起使用

max_fails:允许请求失败的次数
fail_timeout:经过max_fails失败后, 服务暂停时间
# proxy_next_upstream 后端错误标识
[root@lb01 ~]# cat /etc/nginx/conf.d/game.conf 
upstream supermarie {
    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 _;
    location / {
        proxy_pass http://supermarie;
        proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_404; 
        include /etc/nginx/proxy_params;
    }
}
# 后端出现错误,会自动干掉服务,不会去访问
proxy_next_upstream监控的错误类型#
# proxy_next_upstream可以指定的错误类型如下👇:
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#

部署后端服务#

部署Python#

web01、web02、web03部署,统一步骤

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
3、上传文件
[root@web01 ~]# scp bbs.zip 172.16.1.8:/opt/
[root@web01 ~]# scp bbs.zip 172.16.1.9:/opt/
部署Django和uwsgi#
4、安装Django和uwsgi
[root@web01 opt]# pip3 install django==1.11
[root@web01 opt]# pip3 install uwsgi
[root@web01 opt]# pip3 install pymysql
5、创建项目
[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': '123456',
        'HOST': '172.16.1.61',
        'PORT': 3306,
        'CHARSET': 'utf8'
    }
}
# 启动测试
[root@web01 bbs]# python3 manage.py runserver 0.0.0.0:8000
# 注意数据库远程连接必须开启
配置并启动uwsgi#
6、编辑项目配置文件
[root@web01 bbs]# 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
7、启动uwsgi(在bbs目录测试)
[root@web01 bbs]# uwsgi -d --ini myweb_uwsgi.ini --uid 666
-d    : 以守护进程方式运行
--ini : 指定配置文件路径
--uid : 指定uid
TCP 服务
8、编辑Nginx配置文件
[root@web01 ~]# 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;
    }
}
9、测试且重启Nginx配置
nginx -t
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;
    }
}
[root@lb01 conf.d]# nginx -t
[root@lb01 conf.d]# systemctl restart nginx 
# 域名解析
windows下hosts文件
# 注意连接池的名称不能相同,和其他的负载均衡连接池区分
# 真机测试是否成功


补充

页面出现502问题原因#

原文地址https://www.cnblogs.com/48xz/p/15772975.html

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
9月前
|
负载均衡 网络协议 算法
一文读懂什么是Nginx?它能否实现IM的负载均衡?
Nginx(及其衍生产品)是目前被大量使用的服务端反向代理和负载均衡方案,从某种意义上来讲,Nginx几乎是低成本、高负载Web服务端代名词。 如此深入人心的Nginx,很多人也想当然的认为,在IM或消息推送等场景下是否也能使用Nginx来解决负载均衡问题? 另外,即时通讯网的论坛和QQ群里也经常有人问起,Nginx是否能支持TCP、UDP、WebSocket的负载
259 4
|
10月前
|
网络协议 应用服务中间件 网络安全
Nginx,正向代理
本文介绍了Nginx作为HTTPS正向代理的两种方案:HTTP CONNECT隧道(7层)和NGINX stream(4层)。HTTP CONNECT隧道需要客户端手动配置代理,通过CONNECT请求建立隧道;而NGINX stream则更适合透明代理,利用SNI字段实现流量转发。文章详细讲解了两者的原理、环境搭建、使用场景及常见问题,并提供了配置示例和最佳实践建议。内容转载自阿里云开发者社区@怀知的文章,推荐读者参阅原文获取更多信息。感谢您的阅读!
1407 80
Nginx,正向代理
|
6月前
|
负载均衡 前端开发 应用服务中间件
Tomcat的负载均衡和动静分离(与nginx联动)
总的来说,负载均衡和动静分离是提高Web应用性能的两个重要手段。通过合理的配置和使用,我们可以让Web应用更好地服务于用户。
208 21
|
6月前
|
负载均衡 Java 应用服务中间件
Tomcat与Nginx的负载均衡与动静分离技巧
总的来说,Tomcat和Nginx各有各的优点,在负载均衡和动静分离这两方面它们都有很好的应用。灵活使用这两个工具能够让Web应用具有更好的扩展性和用户体验。
194 14
|
6月前
|
负载均衡 前端开发 JavaScript
LVS-DR模式、keepalived、Nginx与Tomcat合作,打造动静分离,高效负载均衡与高可用性
为了采用这样的架构,你需要对LVS-DR、Keepalived、Nginx与Tomcat有一定的理解和掌握,同时也需要投入一些时间去研究和配置,但是一旦你把它运行起来,你将会发现,这一切都是值得的。
262 11
|
8月前
|
负载均衡 算法 应用服务中间件
Nginx长连接负载均衡详细说明以及案例
本文详细介绍了Nginx长连接负载均衡的配置与原理。长连接(Keepalive)允许客户端和服务器保持连接,减少建立和关闭连接的开销。Nginx支持多种负载均衡算法,如轮询、IP哈希等。通过在Nginx配置文件中使用`upstream`模块和`keepalive`指令,可以实现长连接负载均衡,从而提高系统的性能和响应速度。示例配置展示了如何设置后端服务器组、长连接数及HTTP/1.1协议,确保连接复用,降低延迟。
509 5
|
负载均衡 监控 应用服务中间件
配置Nginx反向代理时如何指定后端服务器的权重?
配置Nginx反向代理时如何指定后端服务器的权重?
546 61
|
安全 应用服务中间件 网络安全
如何测试Nginx反向代理实现SSL加密访问的配置是否正确?
如何测试Nginx反向代理实现SSL加密访问的配置是否正确?
677 60
|
安全 应用服务中间件 网络安全
配置Nginx反向代理实现SSL加密访问的步骤是什么?
我们可以成功地配置 Nginx 反向代理实现 SSL 加密访问,为用户提供更安全、可靠的网络服务。同时,在实际应用中,还需要根据具体情况进行进一步的优化和调整,以满足不同的需求。SSL 加密是网络安全的重要保障,合理配置和维护是确保系统安全稳定运行的关键。
694 60
|
10月前
|
缓存 负载均衡 应用服务中间件
Nginx七层(应用层)反向代理:HTTP反向代理proxy_pass篇
通过使用Nginx的反向代理功能,可以有效地提高Web应用的性能、安全性和可扩展性。配置过程中需要注意不同场景下的具体需求,如负载均衡、SSL终止和缓存策略等。正确配置和优化Nginx反向代理可以显著提升系统的整体表现。
1619 20
下一篇
oss云网关配置