• Nginx 快速入门


    一、简述

    1.1 介绍

    传统的 Web 服务器,每个客户端连接作为一个单独的进程或线程处理,需在切换任务时将 CPU 切换到新的任务并创建一个新的运行时上下文,消耗额外的内存和 CPU 时间,当并发请求增加时,服务器响应变慢,从而对性能产生负面影响。
    Nginx 是开源、高性能、高可靠的 Web 和反向代理服务器,而且支持热部署,几乎可以做到 7 * 24 小时不间断运行,即使运行几个月也不需要重新启动,还能在不间断服务的情况下对软件版本进行热更新。性能是 Nginx 最重要的考量,其占用内存少、并发能力强、能支持高达 5w 个并发连接数,最重要的是,Nginx 是免费的并可以商业化,配置使用也比较简单。

    Nginx 的最重要的几个使用场景:

    1. 静态资源服务,通过本地文件系统提供服务;
    2. 反向代理服务,延伸出包括缓存、负载均衡等;
    3. API 服务,OpenResty ;

    对于前端来说 Node.js 不陌生了,Nginx 和 Node.js 的很多理念类似,HTTP 服务器、事件驱动、异步非阻塞等,且 Nginx 的大部分功能使用 Node.js 也可以实现,但 Nginx 和 Node.js 并不冲突,都有自己擅长的领域。Nginx 擅长于底层服务器端资源的处理(静态资源处理转发、反向代理,负载均衡等),Node.js 更擅长上层具体业务逻辑的处理,两者可以完美组合,共同助力前端开发

    1.2 安装启动

    (1)Linux 安装Nginx

    1. 安装之前可以查看nginx包情况及版本 apt list | grep nginx
    root@rion:~# apt list | grep nginx
    
    WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
    
    ......
    nginx-common/focal-updates,focal-security 1.18.0-0ubuntu1.4 all
    nginx-core/focal-updates,focal-security 1.18.0-0ubuntu1.4 amd64
    nginx-doc/focal-updates,focal-security 1.18.0-0ubuntu1.4 all
    nginx-extras/focal-updates,focal-security 1.18.0-0ubuntu1.4 amd64
    nginx-full/focal-updates,focal-security 1.18.0-0ubuntu1.4 amd64
    nginx-light/focal-updates,focal-security 1.18.0-0ubuntu1.4 amd64
    nginx/focal-updates,focal-security 1.18.0-0ubuntu1.4 all
    .....
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    1. 安装nginx,并查看nginx版本
    apt install nginx
    
    root@rion:~# nginx -v
    nginx version: nginx/1.18.0 (Ubuntu)
    
    • 1
    • 2
    • 3
    • 4
    1. 使用whereis nginx 来查看nginx相关的文件的位置
    root@rion:~# whereis nginx
    nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx /usr/share/man/man8/nginx.8.gz
    
    # 文件路径说明
    # /usr/sbin/nginx   终端nginx服务管理的命令
    # /usr/lib/nginx    nginx 相关的包文件
    # /etc/nginx		    nginx 配置文件存放路径
    # /usr/share/nginx  资源存放路径
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 防火墙配置(Centos 需要配置)
    systemctl start firewalld  # 开启防火墙
    systemctl stop firewalld   # 关闭防火墙
    systemctl status firewalld # 查看防火墙开启状态,显示running则是正在运行
    firewall-cmd --reload      # 重启防火墙,永久打开端口需要reload一下
    
    # 添加开启端口,--permanent表示永久打开,不加是临时打开重启之后失效
    firewall-cmd --permanent --zone=public --add-port=8888/tcp
    
    # 查看防火墙,添加的端口也可以看到
    firewall-cmd --list-all
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    1. 启动nginx

    systemctl start nginx

    (2)Docker 安装Nginx

    1. 查询nginx镜像
    docker search nginx	
    
    • 1
    1. 下载镜像,查看镜像
    docker pull nginx
    docker images
    
    • 1
    • 2
    1. 创建nginx配置文件
    # -p 表示递归创建文件夹,不加-p只能创建一层文件夹,创建多层则会报错
    mkdir -p /app/nginx/conf     # /app 是隶属于根下的文件夹,个人喜好
    
    • 1
    • 2

    启动前需要先创建Nginx外部挂载的配置文件( /home/nginx/conf/nginx.conf)
    之所以要先创建 , 是因为Nginx本身容器只存在/etc/nginx 目录 , 本身就不创建 nginx.conf 文件
    当服务器和容器都不存在 nginx.conf 文件时, 执行启动命令的时候 docker会将nginx.conf 作为目录创建 , 这并不是我们想要的结果 。

    1. 创建配置相关文件
    root@rion:~# docker run --name nginx-test -d nginx
    1e3a6ea2eae268e0fcd6a3a5209f26fce8f173ecde42536d6de5ab5fba345fd6
    
    root@rion:~# docker ps -a | grep nginx
    1e3a6ea2eae2   nginx  "/docker-entrypoint.…"   11 seconds ago   Up 10 seconds    80/tcp  nginx-test
    
    • 1
    • 2
    • 3
    • 4
    • 5

    docker 相关命令介绍:
    run 表示启动一个镜像
    –name 表示给将要启动的镜像起个别名
    -d 表示后台启动

    1. 复制nginx中的配置等文件
    # 生成容器
    docker run --name nginx-test -d nginx
    # 将容器nginx.conf文件复制到宿主机
    docker cp nginx-test:/etc/nginx/nginx.conf /app/nginx/conf
    # 将容器conf.d文件夹下内容复制到宿主机
    docker cp nginx-test:/etc/nginx/conf.d /app/nginx/conf/conf.d
    # 将容器中的html文件夹复制到宿主机
    docker cp nginx-test:/usr/share/nginx/html /app/nginx	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    docker cp [SrcAddress] [DstFileAddress]
    栗子:
    docker cp nginx-test:/etc/nginx/nginx.conf /home
    // 表示将nginx-test容器中/etc/nginx/nginx.conf 复制到宿主机(本机)的home目录下
    docker cp /home/1.txt nginx-test:/root
    // 表示将宿主机/home 下的1.txt文件拷贝到nginx-test 容器的/root/目录下

    1. 目录结果查看
    root@rion:/app/nginx# tree
    .
    ├── conf
    │   ├── conf.d
    │   │   └── default.conf
    │   └── nginx.conf
    └── html
        ├── 50x.html
        └── index.html
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    1. 创建nginx容器
    # 1. 停止nginx-test容器
    docker stop nginx-test
    
    # 2. 删除前面创建的nginx-test容器,默认不能直接删除运行中的容器
    docker rm nginx-test
    
    # 3. 创建nginx容器
    docker run \
    -p 80:80 \
    --name nginx \
    -v /app/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
    -v /app/nginx/conf/conf.d:/etc/nginx/conf.d \
    -v /app/nginx/log:/var/log/nginx \
    -v /app/nginx/html:/usr/share/nginx/html \
    -d nginx
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    -v 表示挂载文件,宿主机文件路径 : 容器文件路径
    -p 表示将容器的 80(后面那个) 端口映射到主机的 80(前面那个) 端口
    \ shell 命令换行

    1. 测试nginx
    root@rion:/app/nginx# curl http://127.0.0.1
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
    html { color-scheme: light dark; }
    body { width: 35em; margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif; }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    成功访问了nginx的默认页面,我们修改html中的index.html 文件内容

    root@rion:/app/nginx# vim html/index.html
    <!DOCTYPE html>
    <html>
    <body>
    <h1>Welcome To RION Blog</h1>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    再次访问,成功获取修改后的内容。

    root@rion:/app/nginx# curl http://127.0.0.1
    <!DOCTYPE html>
    <html>
    <body>
    <h1>Welcome To RION Blog</h1>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (3)Windows 安装nginx

    nginx 下载地址:http://nginx.org/en/download.html

    访问nginx下载地址,下载解压后双击nginx.exe程序,此时nginx服务就启动了。如果出错了请检测本机80端口是否被占用了。

    1.3 nginx 基本命令

    nginx 命令

    nginx -s reload  # 向主进程发送信号,重新加载配置文件,热重启
    nginx -s reopen	 # 重启 Nginx
    nginx -s stop    # 快速关闭
    nginx -s quit    # 等待工作进程处理完成后关闭
    nginx -T         # 查看当前 Nginx 最终的配置
    nginx -t -c <配置路径>    # 检查配置是否有问题,如果已经在配置目录,则不需要-c		
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    systemctl 运行 nginx相关

    systemctl start nginx    # 启动 Nginx
    systemctl stop nginx     # 停止 Nginx
    systemctl restart nginx  # 重启 Nginx
    systemctl reload nginx   # 重新加载 Nginx,用于修改配置后
    systemctl enable nginx   # 设置开机启动 Nginx
    systemctl disable nginx  # 关闭开机启动 Nginx
    systemctl status nginx   # 查看 Nginx 运行状态
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    1.4 Nginx 运行基本原理

    image.png

    二、Nginx 配置文件

    2.1 默认nginx.conf 配置文件

    nginx主要的配置文件为/etc/nginx/nginx.conf文件,内部结构大体如下:

    # 主要包含三大块
    main        # 全局配置,对全局生效,即最外层的配置
    ├── events  # 配置影响 Nginx 服务器或与用户的网络连接
    ├── http    # 配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置
    │   ├── upstream # 配置后端服务器具体地址,负载均衡配置不可或缺的部分
    │   ├── server   # 配置虚拟主机的相关参数,一个 http 块中可以有多个 server 块
    │   ├── server
    │   │   ├── location  # server 块可以包含多个 location 块,location 指令用于匹配 uri
    │   │   ├── location
    │   │   └── ...
    │   └── ...
    └── ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    一个 Nginx 配置文件的结构就像 nginx.conf 显示的那样,配置文件的语法规则:

    1. 配置文件由指令与指令块构成;
    2. 每条指令以 ; 分号结尾,指令与参数间以空格符号分隔;
    3. 指令块以 {} 大括号将多条指令组织在一起;
    4. include 语句允许组合多个配置文件以提升可维护性;
    5. 使用 # 符号添加注释,提高可读性;
    6. 使用 $ 符号使用变量;
    7. 部分指令的参数支持正则表达式;

    main 全局块

    user  nginx;						# 以nignx用户运行
    worker_processes  auto; # Nginx 进程数,auto为自动调节
    
    error_log  /var/log/nginx/error.log notice;   # Nginx 的错误日志存放目录
    pid        /var/run/nginx.pid;			# Nginx 服务启动时的 pid 存放位置
    
    • 1
    • 2
    • 3
    • 4
    • 5

    events 块

    events {
        worker_connections  1024;   # 每个进程允许最大并发数
    }
    
    • 1
    • 2
    • 3

    http 块

    # 配置最频繁的部分,代理、缓存、日志等大部分功能和第三方配置
    http {
        include       /etc/nginx/mime.types;     # 文件扩展名与对应的映射表,即http mime类型
        default_type  application/octet-stream;  # 如果mime类型没匹配上,默认使用二进制流的方式传输。
    
      	# 设置日志的记录格式 
        log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for"';
    
        access_log  /var/log/nginx/access.log  main;  # Nginx 访问日志记录位置
    
        # sendfile      on;				# 开启高效传输模式,也就是数据0拷贝
        #tcp_nopush     on;				# 减少网络报文段的数量
    
        keepalive_timeout  65;    # 保持连接的时间,也称为超时时间,单位秒
    
        include /etc/nginx/conf.d/*.conf;    # 最后会加载conf.d 文件夹下的配置文件
    
      	# /etc/nginx/conf.d/default.conf
        server {
            listen       80;   	# 监听端口
            server_name  localhost;		# 配置域名
    
            location / {					# 匹配请求网址
                root   /usr/share/nginx/html;		# 网址根目录,且全局有且仅有一个root
                index  index.html index.htm;		# 默认首页文件
            		deny 172.168.22.11;   # 禁止访问的ip地址,可以为all
            		allow 172.168.33.44; # 允许访问的ip地址,可以为all
            }
        
            #error_page  404              /404.html;  # 404 状态码显示的网页
        
            # redirect server error pages to the static page /50x.html
            #
            error_page   500 502 503 504  /50x.html;  # http状态码为50x的时候对应的页面 
            location = /50x.html {
                root   /usr/share/nginx/html;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    server 块中可以包含多个location,每个location 支持正则匹配
    匹配规则

    1. = 精确匹配路径,用于不含正则表达式的 uri 前,如果匹配成功,不再进行后续的查找;
    2. ^~ 用于不含正则表达式的 uri 前,表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找;
    3. ~ 表示用该符号后面的正则去匹配路径,区分大小写;
    4. ~* 表示用该符号后面的正则去匹配路径,不区分大小写。跟 ~ 优先级都比较低,如有多个location的正则能匹配的话,则使用正则表达式最长的那个;

    如果 url 包含正则表达式,则必须要有 ~ 或 ~* 标志。

    2.2 Nginx 全局变量

    $host:请求信息中的 Host,如果请求中没有 Host 行,则等于设置的服务器名,不包含端口
    $request_method :客户端请求类型,如 GET、POST
    $remote_addr:客户端的 IP 地址
    $args:请求中的参数
    $arg_PARAMETER:GET 请求中变量名 PARAMETER 参数的值,例如:$http_user_agent(Uaer-Agent 值), $http_referer...
    $content_length :请求头中的 Content-length 字段
    $http_user_agent:客户端agent信息
    $http_cookie:客户端cookie信息
    $remote_addr:客户端的IP地址
    $remote_port:客户端的端口
    $http_user_agent:客户端agent信息
    $server_protocol:请求使用的协议,如 HTTP/1.0、HTTP/1.1
    $server_addr:服务器地址
    $server_name:服务器名称
    $server_port:服务器的端口号
    $scheme:HTTP 方法(如http,https)

    三、Nginx代理

    3.1 正向代理(Forward Proxy)

    正常情况下,用户要访问网站直接访问即可,此时用户不想让对方服务器知道自己的信息(比如自己的IP等),就可以通过配置代理服务器,让我们的代理服务器来代替我们发送请求获取数据,并将数据返回给我们。这就叫做正向代理
    正向代理隐藏了真实的客户端信息,对方服务器获取的都是代理服务器的信息
    image.png

    3.2 反向代理

    (1)概念

    当用户访问网站时,使用反向代理服务器之后,用户访问的是我们的代理服务器,而代理服务器会根据nginx配置项来请求真正的服务器,nginx将获取的数据返回给用户。
    反向代理隐藏了服务器信息,在处理跨域时比较常用。
    image.png

    (2)实例1 - 实现所求请求转发到指定的后端服务

    1. 需求说明

    当用户访问 www.rion.top:8080 网站时,nginx将用户的请求转发到一个flask程序中去。
    这里简单的介绍一下用户输入网址的一个解析流程
    image.png

    用户输入网址后,本机先会检测hosts文件是否有IP和域名的对应关系。
    Windows在C:\Windows\System32\drivers\etc\hosts
    Linux 在 /etc/hosts

    2.配置hosts文件
    因为互联网上没有www.rion.top 这个域名,所以我们需改hosts文件,使其指向本地的127.0.0.1,推荐使用vscode打开,其他软件打开可能会出现无法修改的情况
    image.png
    3.启动一个web服务
    本次以flask程序为例,提供了2个api接口

    from flask import Flask
    
    app = Flask(__name__)     # Flask 实例对象
    
    @app.route("/api/home")   # 路由地址
    def home():								# 处理函数
        return "Home Page"    # 响应数据
    
    @app.route("/api/login")
    def login():
        return "Please Login"
    
    if __name__ == "__main__":
        app.run()								# 运行flask程序,默认监听本机127.0.0.1:5000
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    image.png
    4.配置nginx反向解析

    server {
        listen       8080;
        server_name  www.rion.top;
    
        location /api {
            proxy_pass http://127.0.0.1:5000;
        }
      	# proxy_pass 将匹配到的请求转发到后面的url地址去
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    检测nginx配置是否错误,并重载配置文件
    image.png
    5.测试
    当用户输入http://127.0.0.1:8080/api/home时,nginx会将请求转发到我们的flask程序上。
    image.png
    6.总结
    通过proxy_pass来实现请求转发,默认location / 表示截获所有的请求。

    (3)实例2 - 实现url前缀不同访问不同的后端服务

    1.需求
    当用户访问http://127.0.0.1:8080/flask 时,访问我们的flask服务
    当用户访问http://127.0.0.1:8080/django 时,访问我们的django服务
    django 的这边定义了2个简单的api接口,

    # 伪代码,细节代码就不展示了。flask 程序和上面的一样,返回值一点点不一样
    
    # urls.py
    urlpatterns = [
        path('api/login', views.login),
        path('api/home', views.home)
    ]
    
    # views.py
    def home(request):
        return HttpResponse("Django Home !")
    
    def login(request):
        return HttpResponse("Django Login")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.nginx 配置

        server {
            listen  8080;
            server_name www.rion.top;
    
            location /flask/ {
                proxy_pass http://127.0.0.1:5000/;
            }
            location /django/ {
                proxy_pass http://127.0.0.1:8000/;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    3.测试
    测试前记得重载nginx配置文件

    • 访问flask

    image.png

    • 访问django

    image.png
    4.总结
    本质就是通过location 来区分不同的前缀,当nginx发现前缀是/flask时,就会将请求转发到flask程序上,同理访问/django 时,就会将请求转发到django程序上

    3.3 location 配置(带/ 和 不带/ 的区别)

    为什么这里要单独作为一个小节呢?在配置反向代理过程中这里其实是有坑的。因为 location 配置代理时,location 地址匹配结尾带/ 和不带/ 获取的url会不一样。而proxy_pass url末尾带/不带/ 也会出现不同的情况。所以一共会出现四种不同的情况。

    (1)location 结尾不带/ ,url 结尾也不带 /

    1. 当我们的location 不带/ 时,django程序接收的请求
    	location /django {   # 后续location这里的地址匹配我称呼为location 带不带 /
          proxy_pass http://127.0.0.1:8000;   # 后续proxy_pass 后面url地址我称呼为url 带不带/ 
      }
    
    • 1
    • 2
    • 3
    1. 访问django程序时,前端页面提示找不到这个url

    image.png
    此时我们查看django后端接收到的请求路径,发现接收的是/django/api/login,所以django程序返回了404 ,因为压根就没有这个api接口。
    image.png

    1. 当我们尝试访问访问/djangoxxx/api/login,看后端能不能接收到这个请求

    你会发现nginx将/djangoxxx的请求也转发到了django程序
    image.png
    总结:
    当location 不带/ ,url 不带/ 时,nginx会匹配以 /django开头的字符,不管django末尾是什么字符都会成功匹配,并将匹配到的内容追加在url的末尾。就类似于模糊匹配,不过指定了开头。
    如上述实际请求的是http://www.rion.top/djangoxxx/api/login

    (2)location 带 / ,url 不带 /

    1. nginx 配置
    	location /django/ {   # 后续location这里的地址匹配我称呼为location 带不带 /
          proxy_pass http://127.0.0.1:8000;   # 后续proxy_pass 后面url地址我称呼为url 带不带/ 
      }
    
    • 1
    • 2
    • 3
    1. 用户访问/django/api/login 时,nginx 将请求转发到了django程序,此时django程序获取的请求地址为/django/api/login

    image.png

    1. 用户访问 /djangoxxx/api/login时,nginx 并没有将请求转发到django,说明location 匹配失败了,此时我们的django程序也没有收到任何请求。

    image.png

    1. 当用户访问/django 时,nginx 也将请求转发到了django程序,所以nginx 是能够匹配/django 的,并且会自动给你补齐最末尾的/

    image.png
    总结
    当location 带/ 结尾时,就类似于精确匹配,必须是/django/django/结尾才会匹配

    (3)location 不带 /,url 带/

    1. nginx 配置
      location /django {
          proxy_pass http://127.0.0.1:8000/;
      }
    
    • 1
    • 2
    • 3
    1. 用户访问/django/api/login 时,nginx将请求转发到了django程序,但是django响应的还是404,当时你会发现请求的地址不再是以django开头,而是把/django 替换从了 /,所以就变成了//api/login,不明白的可以仔细看看请求的地址/django => / + /api/login ===> //api/login

    image.png

    1. 用户访问/djangoxxx/api/login,nginx匹配成功,但是django程序接收的地址也却是/xxx/api/login,说明/djangoxxx 被nginx 替换成了 /xxx

    image.png
    image.png

    1. 若url 以/yy/ 结尾时,用户请求/djangoxxx/api/login,则最终请求的为/yy/xxx/api/login
      location /django {
          proxy_pass http://127.0.0.1:8000/yy/;
      }
    
    • 1
    • 2
    • 3

    image.png
    总结
    若url 带 / 时,当location 匹配成功,会将匹配的内容替换为 / ,若url 以url 带/yy/ 结尾,则location匹配的内容将会被替换成/yy/在加上剩余部分。

    (4)location 带 /,url 也带 /

    location /django/ {
        proxy_pass http://127.0.0.1:8000/;
    }
    
    • 1
    • 2
    • 3
    1. 结果前面的测试,我们能够猜测出来,若用户以/django/api/login发起请求,nginx会将/django/ 替换成 /,最终的请求为/api/login,此时django程序api接口成功请求成功。

    image.png

    1. 若用户请求/djangoxxx/api/login,会匹配失败。

    总结
    location 带 / ,就类似于精确匹配,url 带 / 则会见匹配到的内容替换为 /

    整体简单概述一下:

    1. location 结尾不带 / ,表示模糊匹配,只要location 开头能匹配上,后面的内容是否有多余都会匹配成功。
    2. location 结尾带 /, 表示只能匹配location 结尾指定内容,匹配内容结尾可以不包含/
    3. url 结尾不带 / ,则会把location 匹配的内容追加到后面
    4. url结尾带 / ,则会将location匹配的内容替换为 url / 后的内容。

    实际项目开发中,location 往往是以/结尾的。url 也往往是以/ 结尾,这样能够有效保障精确的匹配api,并后端服务能够正确的处理。

    例如

    location /admin/api/ {
      	proxy_pass http://127.0.0.1:8000/api/;
    }
    
    • 1
    • 2
    • 3

    将匹配/admin/api/ 替换成 /api/ 开头,
    这样请求 http://www.rion.top/admin/api/ ,实际转发后为 http://127.0.0.1:8000/api/;
    此时对用户来说他是无感知的,但是访问时已经切换到另一个后端服务了。

    四、负载均衡

    4.1 概述

    在早期,用户访问量不大的时候,用户每次请求,nginx将服务器响应的数据返回给用户,当用户访问越来越多时,服后端务器开始处理不过来,此时我们可以配置多台服务器,当A服务器负载较高时,nginx将请求转发到B服务器来响应用户,这样就能保障用户访问时的快速响应。
    例如,晚高峰乘坐地铁的时候,入站口经常会有地铁工作人员大喇叭“请走 B 口,B 口人少车空…”,这个工作人员的作用就是负载均衡。
    image.png
    一般来说,都需要将动态资源和静态资源分开,由于 Nginx 的高并发和静态资源缓存等特性,经常将静态资源部署在 Nginx 上。如果请求的是静态资源,直接到静态资源目录获取资源,如果是动态资源的请求,则利用反向代理的原理,把请求转发给对应后台应用去处理,从而实现动静分离。

    使用前后端分离后,可以很大程度提升静态资源的访问速度,即使动态服务不可用,静态资源的访问也不会受到影响。

    4.2 实现负载均衡

    1. 当请求过来时,nginx 判断每台服务器的负载情况来决定请求转发到那台服务器上。
    upstream flask {
        server 127.0.0.1:5000 weight=2; # weight : 权重,表示3次请求有2次请求会发送到 5000 端口的服务器
        server 127.0.0.1:5001 weight=1;
    }
    
    server {
        listen  8080;
        server_name www.rion.top;
        location / {
            proxy_pass http://flask;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    当服务器性能不一致时,权重就需要调整设置了。默认都是1,表示依次轮询。
    参数介绍:
    down:表示当前的server暂时不参与负载
    weight:默认为1.weight越大,负载的权重就越大。
    backup: 其它所有的非backup机器down或者忙的时候,请求backup机器。

    1. 我们启动两个flask程序来处理用户请求,当请求三次时,会发现有2次请求在5000端口的服务器 上,1次请求在5001端口的服务器上

    image.png
    注意:
    前面我们提到需要注意location 和 url 是否带 / 的问题,在这里也是同样的道理。

    1. location 不带 / ,则请求/flask/api/login到flask程序时,nginx会在url后面拼接上/flask
        upstream flask {
            server 127.0.0.1:5000 weight=2;
            server 127.0.0.1:5001 weight=1;
        }
    
        server {
            listen  8080;
            server_name www.rion.top;
            location /flask {
                proxy_pass http://flask;
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    image.png

    1. location 带 / ,url 带 / 时的配置。请求/flask/api/login
        upstream flask {
            server 127.0.0.1:5000 weight=2;
            server 127.0.0.1:5001 weight=1;
        }
    
        server {
            listen  8080;
            server_name www.rion.top;
            location /flask/ {
                proxy_pass http://flask/;    # 注意,url的 / 是加在这里,并不是加在upstream 中
            }
        }	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    image.png

    其余两种情况,朋友们可以自己去测试了。

    nginx 的基本使用就介绍到这里了,有任何错误欢迎大家指出~

    参考链接: https://blog.csdn.net/BThinker/article/details/123507820
    参考链接: https://www.nginx.org.cn/article/detail/545

  • 相关阅读:
    jvm的结构以及如何调优
    React函数式写法和类式写法的区别(以一个计数器功能为例子)
    软件工程毕业设计课题(13)基于python的毕业设计python教室实验室预约系统毕设作品源码
    计算机视觉40例之案例11以图搜图
    网络编程入门
    Java-1101
    京东如何批量制作全店透明图?
    2022.10.9-10.16 AI行业周刊(第119期):相信坚持的力量
    socat管理haproxy配置
    网络语言错误是指在编程中出现的错误或故障,导致程序无法正常运行或产生意外的结果
  • 原文地址:https://blog.csdn.net/m0_56966142/article/details/127944189