当前位置: 首页 > article >正文

Nginx部署前端需要了解的知识

Nginx部署前端项目

Nginx 是一个高性能的HTTP和反向代理服务器。作为前端开发的同学,了解反向代理的概念是非常必要的,特别是在构建现代应用时。

反向代理的基本概念

反向代理与正向代理的区别在于代理对象的不同。正向代理是客户端主动通过代理服务器访问互联网,例如使用 VPN 翻墙。当我们访问国外网站时,可能会遇到速度慢或无法访问的问题,这时正向代理可以帮助我们解决这些问题。

与之相对,反向代理则是在服务器端,通过反向代理服务器来选择目标服务器处理请求。客户端无需配置,只需将请求发送到反向代理服务器,由它来获取数据并返回给客户端。这种方式不仅隐藏了真实服务器的 IP 地址,还能够将请求分发到多台后端服务器,从而提高系统的可用性和负载均衡能力,增强整体安全性。

在这里插入图片描述

反向代理工作原理

客户端配置代理服务器,通过代理服务器进行互联网访问。代理对象是客户端,而服务端则隐藏在反向代理之后。简单来说,当用户请求资源时,反向代理服务器会处理这些请求并转发到合适的后端服务器。这样,外部用户只需知道反向代理的地址,而不需要知道真实的服务器地址。

在这里插入图片描述

nginx的配置文件目录

在这里插入图片描述

  • /etc/nginx/nginx.conf 核心配置文件
  • /etc/nginx/conf.d/default.conf 默认http服务器配置文件
  • /etc/nginx/fastcgi_params fastcgi配置
  • /etc/nginx/scgi_params scgi配置
  • /etc/nginx/uwsgi_params uwsgi配置
  • /etc/nginx/koi-utf
  • /etc/nginx/koi-win
  • /etc/nginx/win-utf 这三个文件是编码映射文件,因为作者是俄国人
  • /etc/nginx/mime.types 设置HTTP协议的Content-Type与扩展名对应关系的文件
  • /usr/lib/systemd/system/nginx-debug.service
  • /usr/lib/systemd/system/nginx.service
  • /etc/sysconfig/nginx
  • /etc/sysconfig/nginx-debug 这四个文件是用来配置守护进程管理的
  • /etc/nginx/modules 基本共享库和内核模块
  • /usr/share/doc/nginx-1.18.0 帮助文档
  • /usr/share/doc/nginx-1.18.0/COPYRIGHT 版权声明
  • /usr/share/man/man8/nginx.8.gz 手册
  • /var/cache/nginx Nginx的缓存目录
  • /var/log/nginx Nginx的日志目录
  • /usr/sbin/nginx 可执行命令
  • /usr/sbin/nginx-debug 调试执行可执行命令

nginx核心模块

nginx的核心配置文件nginx.conf主要由3个部分组成:

基本配置
#user  nobody;                  #配置worker进程运行用户

worker_processes  1;            #配置工作进程数目,根据硬件调整,通常等于CPU数量或者2倍于CPU数量

#error_log  logs/error.log;     # 配置全局错误日志及类型
events配置
    events {

        worker_connections  1024;  #配置每个worker进程连接数上限,nginx支持的总连接数等于worker_connections*worker_processes
   }
http基本配置
http {
    include       mime.types;
    default_type  application/octet-stream;
    client_max_body_size 100m;

    sendfile        on;    #开启高效文件传输模式
    #tcp_nopush     on;  #防止网络阻塞

    keepalive_timeout  0;
    
    gzip on; //启动
    gzip_buffers 32 4K;
    gzip_comp_level 6; //压缩级别,1-10,数字越大压缩的越好
    gzip_min_length 100; //不压缩临界值,大于100的才压缩,一般不用改
    gzip_types application/javascript text/css text/xml;
  }
  • client_max_body_size表示 客户端请求服务器最大允许大小,如果请求正文数据大于设定值,HTTP协议会报413错误 Request Entity Too Large,如果需要上传大文件是需要修改这个值的。
  • keepalive_timeout :长连接超时时间,单位是秒,Nginx使用 keepalive_timeout 来指定 KeepAlive 的超时时间(timeout)。指定每个 TCP 连接最多可以保持多长时间。
    Nginx 的默认值是 75 秒,有些浏览器最多只保持 60秒,所以可以设定为 60 秒。若将它设置为 0,就禁止了 keepalive 连接。做好这些超时时间的限定,
    判定超时后资源被释放,用来处理其他的请求,以此提升 Nginx 的性能
  • gzip:在不设置服务器gzip的情况下,我们访问网站

在这里插入图片描述

设置了gzip后访问情况如下

在这里插入图片描述

  • 经过对比,我们发现,设置gzip之后,获取同样的数据。压缩之后的数据量大概是原始数据的1/4。同样的,获取数据的时间也大大降低。极大的优化了用户的体验。
Server配置
server {
    listen       80;
    server_name  localhost;

    # 定义根目录
    root /home/test;

    # 主要的请求处理
    location / {
          ##默认的匹配斜杠/的请求,当访问路径中有/,会被该localtion匹配到并进行处理
        try_files $uri $uri/ /index.html;
        index index.html;
    }

    # API请求代理
    location /api {
        proxy_pass http://ip;  # 替换为实际APIURL
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    # 静态资源处理
    location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ { 
        root /home/test/html/static;
    }

    # 图片防盗链
    location ~* \.(jpg|jpeg|png|gif|webp)$ {
        valid_referers none blocked *.deeruby.com;
        if ($invalid_referer) {
            return 403;
        }
    }

    # 静态文件访问限制
    location /static {
        allow 39.xxx.xxx.xxx;
        deny all;
    }

    # 自定义404错误页面
    error_page 404 /404.html;
}
location / {
                try_files $uri $uri/ /index.html;  
    	  }
  • 以上这段代码主要是为了解决vue项目history模式下刷新页面出现404的问题,目前开发 使用一般前后端分离技术,并且前端负责路由。为了美观,会采用前端会采用history 模式的路由。但刷新页面时,前端真的会按照假路由去寻找文件。此时,必须返回index(index.html)文件才不至于返回404,如果没有使用该段代码,地址栏的#号依旧会消失,但是你无法通过直接输入路由地址直接进入到对应的页面。主要原因是路由的路径资源并不是一个真实的路径,所以无法找到具体的文件因此需要rewrite到index.html中,然后交给路由在处理请求资源,try_files 为文件匹配,先找真实的地址($uri),如果找不到,再找index.html文件

  • error_page在一次请求中只能响应一次,对应的Nginx有另外一个配置可以控制这个选项:recursive_error_pages默认为false,作用是控制error_page能否在一次请求中触发多次。

在这里特别注意一下关于proxy_pass处理代理时url末尾 带/与不带/的区别

  • proxy_pass配置中url末尾带/时,nginx转发时,会将原uri去除location匹配表达式后的内容拼接在proxy_pass中url之后。

    测试地址:http://ip
    
    场景一:
    location ^~ /test/ {
        proxy_pass http://ip/server/;
    }
    代理后实际访问地址:http://ip/server/api
    
    场景二:
    location ^~ /test {
        proxy_pass http://ip/server/;
    }
    
    代理后实际访问地址:http://ip/server//api
    
    
    场景三:
    location ^~ /test/ {
        proxy_pass http://ip/;
    }
    
    代理后实际访问地址:http://ip/api
    
    
    场景四:
    location ^~ /test {
        proxy_pass http://ip/;
    }
    
    代理后实际访问地址:http://ip//api
    
  • proxy_pass配置中url末尾不带/时,如url中不包含path,则直接将原uri拼接在proxy_pass中url之后;如url中包含path,则将原uri去除location匹配表达式后的内容拼接在proxy_pass中的url之后

测试地址:http://ip
 场景一:
 location ^~ /test/{
	proxy_pass http://ip/server;
 }
 代理后实际访问地址:http://ip/serverapi
 
场景二:
location ^~ /test {
    proxy_pass http://ip/server;
}
代理后实际访问地址:http://ip/server/api

场景三:
location ^~ /test/ {
    proxy_pass http://ip;
}
代理后实际访问地址:http://ip

场景四:
location ^~ /test {
    proxy_pass http://ip;
}
代理后实际访问地址:http://ip

关于Nginx location匹配规则

  • Nginx 的 location 实现了对请求的细分处理,有些 URI 返回静态内容,有些分发到后端服务器等,在这里我们也做一个梳理:

    location 支持的语法 location [=|~|~*|^~] pattern { ... }
    
「=」 修饰符:要求路径完全匹配
server {
    server_name baidu.com;
    location = /wsknet {
    []
    }
}
  • http://baidu.com/wsknet匹配
  • http://baidu.com/WSKNET可能会匹配 ,也可以不匹配,取决于操作系统的文件系统是否大小写敏感(case-sensitive)。ps: Mac 默认是大小写不敏感的,git 使用会有大坑。
  • http://baidu.com/wsknet?param1&param2匹配,忽略 querystring
  • http://baidu.com/wsknet/不匹配,带有结尾的/
  • http://baidu.com/wsknete不匹配
「~」修饰符:区分大小写的正则匹配
server {
    server_name baidu.com;
    location ~ ^/wsknet$  {
    []
    }
}
  • http://baidu.com/wsknet匹配(完全匹配)
  • http://baidu.com/WSKNET不匹配,大小写敏感
  • http://baidu.com/wsknet?param1&param2匹配
  • http://baidu.com/wsknet/不匹配,不能匹配正则表达式
  • http://baidu.com/wsknete不匹配,不能匹配正则表达式
「~*」不区分大小写的正则匹配
server {
    server_name baidu.com;
    location ~* ^/wsknet$ {
    []
    }
}
  • http://baidu.com/wsknet匹配 (完全匹配)
  • http://baidu.com/WSKNET匹配 (大小写不敏感)
  • http://baidu.com/wsknet?param1&param2匹配
  • http://baidu.com/wsknet/不匹配,不能匹配正则表达式
  • http://baidu.com/wsknets 不匹配,不能匹配正则表达式
  • 「^~」修饰符:前缀匹配 如果该 location 是最佳的匹配,那么对于匹配这个 location 的字符串, 该修饰符不再进行正则表达式检测。注意,这不是一个正则表达式匹配,它的目的是优先于正则表达式的匹配
查找的顺序及优先级

当有多条 location 规则时,nginx 有一套比较复杂的规则,优先级如下:

  • 精确匹配 =

  • 前缀匹配 ^~(立刻停止后续的正则搜索)

  • 按文件中顺序的正则匹配 *

  • 匹配不带任何修饰的前缀匹配。

这个规则是这样的:

  • 先精确匹配,没有则查找带有 ^~的前缀匹配,没有则进行正则匹配,最后才返回前缀匹配的结果(如果有的话)

Nginx的rewrite模块

rewrite模块即ngx_http_rewrite_module模块,主要功能是改写请求URI,是Nginx默认安装的模块。rewrite模块会根据PCRE正则匹配重写URI,然后发起内部跳转再匹配location
rewrite指令所执行的顺序如下:

  • 首先在server上下文中依照顺序执行rewrite模块指令;
  • 如果server中行了rewrite重写,那么以新URI发起内部跳转,直接匹配location,不会再执行server里的rewrite指令
    • 新URI直接匹配location
    • 如果匹配上某个location,那么其中的rewrite模块指令同样依照顺序执行
    • 如果再次导致URI的rewrite,那么再一次进行内部跳转去匹配location,但跳转的总次数不能超过10次
rewrite
基本语法: rewrite regex replacement [flag]`
`上下文:server, location, if

regex是PCRE风格的,如果regex匹配URI,那么URI就会被替换成replacement,replacement 就是新的URI。如果rewrite同一个上下文中有多个这样的正则,匹配会依照rewrite指令出现的顺序先后依次进行下去,匹配到一个之后并不会终止,而是继续往下匹配,直到返回最后一个匹配上的为止。如果想要中止继续往下匹配,可以使用第三个参数flag。

如果新URI字符中有关于协议的任何东西,比如http://或者https://等,进一步的处理就终止了

  • flag 参数值:

    • last:如果有last参数,那么停止处理任何rewrite相关的指令,立即用替换后的新URI开始下一轮的location匹配

      server {
         listen 80;
         server_name baidu.com;
         location ^~ /wsknet {
             rewrite ^/wsknet/(.*) /test/$1 last;
             root /home/test;
         }
         location ^~ /test {
             return 200 "hello world";
         }
      }
      
      #curl http://baidu.com/wsknet/index.html => http://baidu.com/test/index.html => hello world
      

      url由重写前的

      http://baidu.com/wsknet/index.html
      

      变为

      http://baidu.com/test/index.html
      

重新进行location匹配后,匹配到第二个location条件,所以请求url得到的响应是hello wold

在配置rewrite last时,请求跳出当前location,进入server块,重新进行location匹配,超过10次匹配不到报500错误。客户端的url不变

- break: 停止处理任何rewrite的相关指令。如果出现在location里面,那么所有后面的rewrite模块指令都不会再执行,也不发起内部重定向,而是直接用新的URI进一步处理请求。

server {
   listen 80;
   server_name baidu.com
   location ^~ /wsknet {
       rewrite ^/wsknet/(.*) /test/$1 break;
       root /home/test;
   }
   location ^~ /test {
       return 200 "hello world";
   }
}

#curl -s http://baidu.com/wsknet/index.html => test
#curl -s http://baidu.com/test/index.html => test
url由重写前的http://baidu.com/wsknet/index.html变为http://baidu.com/test/index.html,nginx按照重写后的url进行资源匹配,匹配到的资源文件是/home/test/index.html,所以请求url得到的响应就是/home/test/index.html文件中的内容:test。

配置rewrite break时,请求不会跳出当前location,但资源匹配会按照重写后的url进行,如果location里面配置的是proxy_pass到后端,后端服务器收到的请求url也会是重写后的url。客户端的url不变。

last的break的相同点在于,立即停止执行所有当前上下文的rewrite模块指令;不同点在于last参数接着用新的URI马上搜寻新的location,而break不会搜寻新的location,直接用这个新的URI来处理请求,这样能避免重复rewite。因此,在server上下文中使用last,而在location上下文中使用break。

  • rewrite在实际开发中的示例:

        location /club {
            rewrite /club(.*) $1 break; # $1表示路径中正则表达式匹配的第一个参数
            proxy_pass http://ip;
        }
    
    curl ip/club/mongodb/version #这里的/mongodb/version便是匹配到的$1
    
    result-> http://ip/mongodb/version
    

适配PC与移动环境

  • 当用户从移动端打开PC端的场景时,将自动跳转至移动端wsknet.com,本质上是Nginx可以通过内置变量$http_user_agent,获取到请求客户端的userAgent,从而知道当前用户当前终端是移动端还是PC,进而重定向到H5站还是PC站

        server {
             location / {
                    //移动、pc设备agent获取
    
                    if ($http_user_agent ~* '(Android|baiduOS|iPhone)') {
                        set $mobile_request '1';
                    }
                    if ($mobile_request = '1') {
                        rewrite ^.+ http://wsknet.com;
                    }
                } 
            }
    

Nginx配置https


# 配置监听 80 端口的服务器,用于 HTTPHTTPS 的重定向
server {
  listen 80;                               # 监听端口 80
  server_name www.xxx.com;                 # 服务器名称
  return 301 https://$server_name$request_uri;  # 重定向到 HTTPS
}

# 配置监听 443 端口的服务器,启用 SSL
server {
  listen 443 ssl;                           # 监听端口 443,启用 SSL
  server_name www.xxx.com;                  # 服务器名称
  
  ssl_certificate /etc/nginx/ssl/www.xxx.com.pem;   # SSL 证书的路径
  ssl_certificate_key /etc/nginx/ssl/www.xxx.com.key; # SSL 证书密钥的路径
  ssl_session_timeout 10m;                   # SSL 会话超时设置
  ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; # 加密套件
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;       # 启用的 SSL 协议
  ssl_prefer_server_ciphers on;              # 优先使用服务器的加密套件

  location / {
    root /project/xxx;                    # 网站根目录
    index index.html index.htm index.md;  # 默认页面
    try_files $uri $uri/ /index.html;    # 尝试查找请求的文件,如果找不到则返回 index.html
  }
}

nginx 端口映射多个应用

  • 几个单页应用同时需要部署在同一台电脑上,并且都需要占用80或者443端口,可以采用以下的方式
    server {
        listen       80;
        root /root/test;  #baidu服务器目录;
        location ^~ /a/{
          try_files $uri /a/index.html;  #如果找不到文件,就返回 /toot/test/a/index.html
        }
        location ^~ /b/{
         try_files $uri /b/index.html;   #如果找不到文件,就返回 /toot/test/b/index.html
        }
       
   }

Nginx 负载均衡配置

# 定义一个名为 my_upstream 的后端服务器组
upstream my_upstream {
  server http://localhost:9001;  # 后端服务器 1
  server http://localhost:9002;  # 后端服务器 2
  server http://localhost:9003;  # 后端服务器 3
}

# 配置监听 9000 端口的服务器
server {
  listen 9000;                   # 监听端口
  server_name test.com;          # 服务器名称
  location / {
    proxy_pass my_upstream;      # 将请求转发到 my_upstream
    proxy_set_header Host $proxy_host;                      # 设置 Host 头
    proxy_set_header X-Real-IP $remote_addr;               # 传递真实客户端 IP
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 传递转发的 IP
  }
}

Nginx中的URI变量

Nginx支持多个与URI相关的变量,这些变量可用于条件判断和重定向:

$uri:当前URI
$request_uri:包含请求参数的原始URI
$args:请求参数
$remote_addr:客户端IP地址

在nginx中有几个关于uri的变量,包括$uri $request_uri $document_uri,
它们的区别 :



$args #这个变量等于请求行中的参数。
$content_length #请求头中的Content-length字段。
$content_type #请求头中的Content-Type字段。
$document_root #当前请求在root指令中指定的值。
$host #请求主机头字段,否则为服务器名称。
$http_user_agent #客户端agent信息
$http_cookie #客户端cookie信息
$limit_rate #这个变量可以限制连接速率。
$request_body_file #客户端请求主体信息的临时文件名。
$request_method #客户端请求的动作,通常为GETPOST。
$remote_addr #客户端的IP地址。
$remote_port #客户端的端口。
$remote_user #已经经过Auth Basic Module验证的用户名。
$request_filename #当前请求的文件路径,由root或alias指令与URI请求生成。
$query_string #与$args相同。
$scheme #HTTP方法(如http,https)。
$server_protocol #请求使用的协议,通常是HTTP/1.0HTTP/1.1。
$server_addr #服务器地址,在完成一次系统调用后可以确定这个值。
$server_name #服务器名称。
$server_port #请求到达服务器的端口号。
$request_uri #包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。
$uri #不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。
$document_uri #与$uri相同。

总结

Nginx 是强大的反向代理服务器,适合部署前端应用程序。通过合理配置,可以提高应用的性能、安全性和可扩展性。

参考:
nginx中如何设置gzip: https://www.cnblogs.com/Renyi-Fan/p/11047490.html

http://blog.sina.com.cn/s/articlelist_1834459124_0_1.html

https://openresty.org/download/agentzh-nginx-tutorials-zhcn.html#02-NginxDirectiveExecOrder01

https://juejin.cn/post/7196859948554715195


http://www.kler.cn/a/373541.html

相关文章:

  • EfficientNet-B6模型实现ISIC皮肤镜图像数据集分类
  • 整合SSM框架(2)
  • 雷赛DMC5X10系列脉冲运动控制卡——机械原点和工作原点原理
  • BGP 及 4+ 的一些特性及配置笔记
  • 外包干了7天,技术明显退步。。。。。
  • Go:package
  • 传奇架设教程,M2报错无法找到城堡信息文件的解决方法
  • 【c++篇】:模拟实现string类--探索字符串操作的底层逻辑
  • oracle获取中文拼音/WB
  • isp框架代码理解
  • python debug作业
  • 前端vue2迁移至uni-app
  • 产品宣传册制作成电子产品宣传册用什么软件?
  • ollama 在 Linux 环境的安装
  • Leetcode 79 Word search
  • 保障农民工工资!我们这么做:
  • 前端面试题-token的登录流程、JWT
  • Django+Vue智慧分析居家养老系统统的设计与实现
  • 【Vulnhub靶场】DC-5
  • 构建旋转变换矩阵对二维到高维空间的线段点进行旋转