本文对于初学 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
几个指令的简单说明
- root 指令可以加在 server 和 location 中,location 会继承自 server 的 root 指令
- proxy_pass 指令用于代理,把请求转发到后端接口
- index 指令用于访问首页
- 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,ip_hash , least_conn 默认是轮询
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;
}
-
使用 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; }
-
使用 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
-
使用 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; }
-
除了使用默认的策略,还可以使用第三方的策略,常用的有
fair
,url_hash
,其中 fair 意为公平策略,按照服务端的响应时间来分配请求,响应时间短的优先分配 。
nginx 缓存 https://www.jianshu.com/p/13eebc596c14
结语
做为一个后端大概也要掌握 nginx 的这些内容,个人理解,大神勿喷。 我的博文大纲:https://blog.csdn.net/sanri1993/article/details/52201255
来源:oschina
链接:https://my.oschina.net/sanri/blog/3167247