nginx 基本知识

本文对于初学 nginx 是有一定帮助的,目的在于解决初学 nginx 的一些难点,因为我也只是个后端开发,nginx 一般是运维在维护。

nginx 可以做哪些事呢

  • 做代理:现在基本都是前后端分离开发,前端会单独启动一个服务,在开发的时候我们可以使用 vue 的代理功能,但部署的时候就需要使用 nginx 的代理了,不然访问就跨域了;
  • 做缓存:对于前端的一些图片,样式和脚本文件,一般不会经常变化,这时可以使用 nginx 的缓存功能;
  • 负载均衡:nginx 支持负载均衡功能,可以将流量分发到多台服务;
  • 文件上传:nginx 自带有文件上传模块,之前公司有用过
  • ssl 认证和数据压缩

会有一些什么难点

  • location 的匹配规则不清楚
  • nginx 指令的意思 ,常用哪些指令 root,index,rewrite,proxy_pass ,alias
  • 没有匹配到路径时,去哪里找问题
  • 当配置文件特别复杂时,如何分模块配置
  • 当使用 https 时,证书如何弄

写在开头的话

nginx 每一条语句后面必须加分号

nginx 用于对每一个请求进行拦截,然后做相应处理

可以把 nginx 当成一个语言来看,它也有变量,分支,循环等功能

重点关注 location 的匹配规则,其它都只是些指令,弄清楚意思就可以了

基本操作

nginx -s reload # 重新加载配置
nginx -s stop # 关闭

从一个 vue 项目的部署开始

vue 项目打包后,就只有 index.html 和 static 文件夹,然后所有的图片,样式,脚本都在 static 中,它的请求包含后端请求和对 static 中内容的请求,所以我们要配置至少两个 location

我使用的 nginx 版本为 1.16.1

几个指令的简单说明

  1. root 指令可以加在 server 和 location 中,location 会继承自 server 的 root 指令
  2. proxy_pass 指令用于代理,把请求转发到后端接口
  3. index 指令用于访问首页
  4. rewrite 指令用于将地址重写,可以使用正则替换,关于其 flag 可以上官网查

所以nginx 配置文件就这么配置

server {
    listen       80;
    server_name  localhost;
    
    # 前端项目的根路径,可以把所有的前端项目都放到这个目录下,每个项目使用一个虚拟路径访问
    root C:/pathdev/server/nginx1161/webapps;
    
    # 访问 apis 的走后端代理,如果需要带上请求头信息使用指令 proxy_set_header
    location /apis {
        proxy_pass http://ip:port;
    }
    
    # 访问前端的走本地文件 
    location /appname {
        # 因为已经定义 root ,只要这个项目名称在 webapps 下名字也叫 appname 就可以访问到资源,只需要加一个首页即可
        index index.html
    }
    
    # 此时可能图片出不来,查看日志是图片路径不正确,我们还需要配置 /static 路径的转发
    # 这里使用 rewrite 指令,flag 为 last ,将会重新发起 location 匹配,即匹配到第二个 location 规则,使用 server 定义的 root ,最终访问路径就是 $root/appname/static/*** 
    location /static {
       rewrite ^(.*) /appname/$1;
    }

注:这样部署一个 vue 项目后,你已经基本入门了,接下来就可以直接看官方文档的指令来操作了,博客只是辅助入门和经典问题解答,最好还是看官方文档。

官方文档: https://www.nginx.cn/doc/index.html

location 的匹配规则

优秀博文推荐: https://www.cnblogs.com/lidabo/p/4169396.html

第一次看公司 location 的写法,各种乱七八糟的符号,一下就懵了,其实静下心来,就那几样规则,主要是里面有一些正则,把大家吓到了,它的规则就这几样

location   /uri/ {}
location = /uri/ {}
location ^~ /uri/ {}
location ~ /uri/ {}
location ~* /uri/ {}
location @ /uri/ {} # 这个是官方文档中说的,但我没用过这种,应该运维知道啥意思

当我配置了各种各样的 location 规则,一个请求过来,肯定会有多个都是可以匹配的,它是按顺序走的吗,不是,想想 css 的匹配规则就清楚了,想象成路径选择器。

其中第1 条规则为普通规则,4,5 为正则规则,一个请求过来先会匹配普通规则,以最大前缀匹配,但是匹配到了是并不结束的,还会继续匹配正则规则,如果正则匹配到了就使用正则匹配,否则使用普通规则。

那如何不按这种规则呢,第 2,3 就是了,第 2 种是精准匹配,只有完全匹配才能选择得到,第 3 种还是最大前缀,但不会继续匹配正则。

第 4,5 条规则为正则规则,区别是后者忽略大小写,对于正则匹配的顺序来说,写在前面的最先匹配

部分指令详解

使用指令需要注意的,第一个是语法,第二个就是使用位置

root 和 alias

root 是一个基础目录的意思 ;可以用在 http、server、location、if 中

alias 是一个目录别名的意思,会使用 alias 路径替换 location 路径 ; 只能用在 location 块中

location ^~ /t/ {
    root /data/app
}
# 访问 /t/app.html 会到 /data/app/t/app.html 请求资源 
location ^~ /t/ {
    alias /data/app/resource/ # alias 目录后一定要加 / 
}
# 访问 /t/app.html 会到 /data/app/resource/app.html 请求资源 

index

作用域: http、server、location

index 会按照顺序查找首页资源,使用 root + index 资源路径,重新发起 location 匹配,最终找到资源,如果找不到资源将会查找下一个

rewrite

作用域:server、location、if

rewrite 指令用于将 url 地址重写,并重新发起 location 匹配,当然也可以不让其重新发起 location 匹配,由 flag 决定 ,它的格式为

rewrite regex <rewritepath> [flag]

例子的话,上面有 vue 项目部署的示例 ,其中 flag 可以有这四个 抄自官网

  • last - completes processing of rewrite directives, after which searches for corresponding URI and location
  • break - completes processing of rewrite directives
  • redirect - returns temporary redirect with code 302; it is used if the substituting line begins with http://
  • permanent - returns permanent redirect with code 301

其中网说说得最多的就是 last 和 break 了,break 执行完重写地址后不会再去进行 location 匹配,所以这个资源必须是存在的资源,不能是一个路径 ,否则会出 404 错误

upstream

这个是用来弄负载均衡的,配置在 http 中,最常见的均衡策略有:轮询,weight,iphash , leastconn 默认是轮询

upstream appserver {
    server ip:port;
    server ip:port backup; # 标记为备用服务,主服务挂掉了,会启用备用服务 
    server ip:port down ;  # 手动标记服务停止,可能是服务有问题
}

可以有参数配置失败后的处理,但并不是网上说的会自动剔除服务器,比如这样的配置

upstream appserver {
    server 127.0.0.1:8083 max_fails=3 fail_timeout=30s;
    server 127.0.0.1:8084 max_fails=3 fail_timeout=30s;
}

这个配置代表在 30 s 内失败 3 次,认为服务挂了,然后等待 30 秒,这 30 秒后不会有请求来这台服务器,过完 30 秒后,又尝试连接并且仅尝试 1 次,如果还是失败,继续等待 30 秒后,循环,直到恢复。所以如果一直没恢复的话,到这台服务上的请求比平常的请求要超出一定的时间,是周期性的。

那什么样的请求会被认为是请求失败呢,默认情况下 404 在 nginx 看来是请求成功的,所以可能会出现感觉上配置 fail 策略无效的问题,我们可以通过指令 proxy_next_upstream 配置什么是失败的请求,一般来说,超时,错误,404,500,503 认为失败

server {  
     proxy_next_upstream error timeout invalid_header http_500 http_503 http_404; 
}

  1. 使用 weight 策略

使用 weight 可以增加轮询到的几率,例子如下

   upstream appserver {
       server 127.0.0.1:8083 max_fails=3 fail_timeout=30s;
       server 127.0.0.1:8084 weight=2 max_fails=3 fail_timeout=30s;
   }

  1. 使用 ip_hash 策略
   upstream appserver {
       ip_hash;
       server 127.0.0.1:8083 max_fails=3 fail_timeout=30s;
       server 127.0.0.1:8084 weight=2 max_fails=3 fail_timeout=30s;
   }

  • 在 nginx版本 1.3.1 之前,不能在 ip_hash 中使用 weight
  • ip_hash 不能与 backup 同时使用
  • 当有服务器需要剔除,必须手动 down
    1. 使用 least_conn

把请求发给连接数较少的服务,可以更好的负载均衡

   upstream appserver {
       least_conn;
       server 127.0.0.1:8083 max_fails=3 fail_timeout=30s;
       server 127.0.0.1:8084 weight=2 max_fails=3 fail_timeout=30s;
   } 

  1. 除了使用默认的策略,还可以使用第三方的策略,常用的有 fairurl_hash,其中 fair 意为公平策略,按照服务端的响应时间来分配请求,响应时间短的优先分配 。

nginx 缓存 https://www.jianshu.com/p/13eebc596c14

结语

做为一个后端大概也要掌握 nginx 的这些内容,个人理解,大神勿喷。我的博文大纲:https://blog.csdn.net/sanri1993/article/details/52201255

猜你喜欢

转载自blog.csdn.net/sanri1993/article/details/104354082