开发者学堂课程【Nginx 企业级 Web 服务实战:Nginx location 基础使用、四层访问控制、账户认证及自定义日志路径】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/649/detail/10757
Nginx location 基础使用、四层访问控制、账户认证及自定义日志路径(二)
三、匹配案例
(一)精确匹配
1、首先试一下做精确匹配,精确匹配就是如果有些资源有固定的名称,很少变动,可以这样匹配一下。
假如写个 location,匹配图片的名称,这个图片的名称是 1.jpg,放到 root 里面,这个路径可以随便写,一般都放在一起,把它放在 data下的 nginx下的 static,一般会有个目录叫 static,是专门放动态资源的,后面再加个 jpg
location =1.jpg {
root/data/nginx/static/jpg
]
这样就创建了这个目录,然后找个图片放进来,去 www.magedu.com 找,下载这个图片可以找这个网站的路径,可以截图但是效果不太好,定位这个路径把 uri 复制一下,复制之后先试一下能不能单独访问,然后 wget 下来,这个图片名称可以 mv一下,之后把 nginx reload 一下,再访问这个图片 www.magedu.net,这个是 pc端,然后加上资源名称 1.jpg:www.magedu.net/1.jpg,图片名称现在就被定位到刚才那个绝对路径里了,因为这个地方有个精确匹配,可以试一下有没有生效。
2、如果有两个名称都叫1.jpg
一个在这:
location =1.jpg {
root/data/nginx/static/jpg
]
另一个在这
location/ {
root /data/nginx/html/pc
index index.html index.html
}
看它显示哪个,把下面这个精确匹配注释掉,这个地方会涉及到优先级,有些时候这个资源可能被多个 location 找到,它只能返回一个不会把多个都返回过去。
最终会返回哪个要看优先级,所以先 cd 到默认的目录,然后再找个图片,这两个图片都叫1.jpg,然后再把 nginx reload 一下,这个时候是把之前那个配置注释了,注释了等于这个精确没有打开,它是走的第二个路径,一刷新它就可能显示之前那个图片。
3、如果把精确打开,它就显示新的图片,也就是精确匹配下的图片。这就是精确匹配的优先级,一定高于其他模糊匹配的优先级,精确匹配的优先级是最高的,一旦到了这它就直接显示,不再往下匹配了,无论在下面还有没有内容。
(二)区分大小写和不区分大小写
1、还有区分大小写和不区分大小写,涉及的内容有些绕, 所以要认真学。在location 里面,区分大小写和不区分大小写有什么区别,也就是如果用户请求的 uri中包含大写或者小写字母,是怎么匹配的,这里有个示例
location~/A.?\.jpg
index index.html;
root /opt/nginx/html/image;
这个示例就是先区分大小写,如果下面这个 location 当中匹配 Ax.jpg,这个 x 就是一个名称和一个任意的单个字符,匹配的方式是为根下的 a. ?,‘. ?’就是任意的零或者单个字符,如果访问的时候传了一个任意的名称,如何显示主要是由 A 决定的,可以是大写也可以小写,主要是匹配-这个地方,这个地方由于是规定了匹配 A,这个 A 必须是大写,要是小写就返不了或者找不着,因为这个 nginx 会到指定的 root目录里,就是去找这个 A 开头的,?这个地方是任意传的字符,这个地方没有要求,但这个 A 一定要和 location 一模一样,这样才能找到。也就是波浪线是区分大小写的,那么当用户的请求被执行匹配时发现 location 中定义的是大写的 A,如果 a 是小写的,就匹配不成功了,如果有别的 location 它就会再往下走,如果没有或者再匹配其它 location 之后没有匹配成功,那就会404。
2、再写一个,先写匹配大小写,写一个 Aa.jpg,一个大写的 A,一个小写的 a
location ~/Aa.jpg {
root /data/nginx/static/jpg
}
把这个保存,保存之后需要到这个目录 /data/nginx/static/jpg
,再写一个这样的资源才行,之后拷贝就可以了,拷贝1. jpg,把它拷成两个 AA,这两个 AA 是不能访问的,因为这是用户的请求,如果到了 nginx 这里,location 会判断请求是不是符合它发的要求。
以这个为例,假如有个 image,location~ /image,把这个改成 Aa.jpg,location~ /Aa.jpg 是精确匹配的,不区分大小写但是会匹配文件的名称 Aa.jpg,判断 A 符合或者不符合,a 符合或者不符合。
也就是这个文件名称必须完全等于 Aa.jpg 才会转发,两个 aa 也是不成功的,或者第二个本来应该是 a 但是写成 A了,也是匹配不成功。
3、保存之后 reload 一下,然后看一下效果,再拷贝一下 Aa.jpg 这个资源。
这样资源就有了,如果访问 www.magedu.net/AA.jpb 会报404,也就是访问 AA.jpb一定是失败的,
在 apps/nginx/logs/error.log 会匹配不成功, No such file or directory 是地址访问的,访问的是 uri,匹配不成功,因为 nginx 这层直接拒绝了,这个时候必须得访问相同的资源名称 Aa.jpg,但是如果把表达式换成不区分大小写,
把两个 AA 删了或者移走,先移到 opt
现在只有 Aa.jpg 这个图片名称,然后把 nginx 表达式改了,把它改成不区分大小写,在后面加个星号就可以了
location ~*/Aa.jpg {
root /data/nginx/static/jpg
}
加个星号就表示不区分大小写,就是请求到了 nginx 这层,到了这层之后它的字母会自动转换,只要是字母 a 就行,不管是大写还是小写。
4、所以这个时候用户访问之后,可以访问任意两个 a.jpg 的图片,不要求 a 是大写还是小写,这个时候其实可以允许通过四个图片的名称,因为是两个字母,可以任意组合,比如 AA.jpg、aa.jpg、Aa.jpg、aA.jpg,对于 nginx 来说,正常表达式就可以匹配以上四个文件名称了,会把这四个文件名称转换到 location ~/Aa.jpg {
root /data/nginx/image} 这个路径,只要这个路径里面有这个图片名称,它就可以显示出来,保存之后重启一下 nginx,把它 reload 一下,改成都是 a 的
这个时候访问 www.magedu.net/aa.jpb 是能成功的,如果把它改成区分大小写,就访问不成功了,所以一般都会使用这种不区分大小写的。
5、把星号去掉就变成区分大小写了,这个时候文件名就必须区分大小写。如果写的是 aa.jpb,就会报404了。但是对于公司来说,不知道这些名称叫什么,所以有时会写正则表达式,这个正则表达式就是看文件名称,location~/A.?\.jpg 这个地方可以写星号,具体什么名称不要求,不区分大小写,通常都会这么做,这里只是举个例子,只有一个名称使用正当表达式来写的,可以不用做得这么复杂,就看实例就可以,就写个文件名,比如 ab.jpg 或者 abc.jpg,然后把其中某个字符换成大写或小写,再结合 location 区分大小写和 location 不区分大小写试一下,试一下就出来了。
(三)URI 开始
1、uri 可以匹配用户请求到某一个部分的开头。
location^ ~/images {
root /data/nginx;
index index.html;
}
location /images1 {
alias /data/nginx/html/pc;
index index.html;
}
可以^ ~某定它的开头,匹配开头和匹配文件名后缀都是为后面做动静分离做铺垫。
有两个 images,相当于之前举的例子,有多个目录放不同资源的图片,所以可以写多个 location 把它定位到具体的地方,或者是直接用一个^ ~号。
2、匹配开头,不管后面是多少,一般都往‘ } ’转,试一下再写个 location,这个location 是匹配开头,开头就叫 static,然后往后转, root 放到根下 opt 里,在这里面创建一个项目名称 linux39,这个就相当于是一个业务,在这个业务下面会有各种计算资源,想把这些都转到这,写个 index
location^~ /static {
root /opt/linux39;
index index.html;
}
这里可能会有一些文件,之后在 linux39下面创建几个资源目录,比如 /opt/linux39/static1 ,/opt/linux39/staic2,/opt/linux39/static3
先创建三个,创建完之后,给它echo一些文件,比如 echo“static1”,把这个放到根下 opt,然后 linux39,static1,index,后面放一些不同的静态资源
/opt/linux39/static1/index.html
/opt/linux39/static2/index.html
/opt/linux39/static3/index.html
这就相当于一个业务下面有多个静态资源,要把这些基本资源统一捕获到,然后转化到一个相同路径。访问匹配的uri开头,然后往后面转,把这个重启一下
/apps/nginx/sbin/nginx-s reload
reload 一下就可以去访问了,访问 static1结果就是1,访问 static2结果就是2。
这个时候就不要求后面是多少了,只看这个开头,只要前几个字符匹配成功就可以,类似于某个文件名中的切片,切片之后就看见前几个字符是什么名,根据前几个字符来做匹配,这个匹配是实现动静分离的方式之一,但是用的比较多的是下面这个方式。
(四)文件名后缀
1、很多公司要做动静分离,通过访问匹配的后缀,后缀是公司已经统计好的。
location ~*\.(gif | jpg |jpeg | bmp| png | tiff | tif | ico| wmf | js) $ {
root /data/nginx/images1;
index index.html;
}
图片大概就是这些格式:gif, jpg,jpeg,bmp,png, tiff,tif,ico, wmf 和 js ,把这些文件的后缀锁定,然后用括号括起来,这就是一个元组,这个元组里面有多个元素,每一个元素中间用竖线隔开,
如果后缀是其中一种,比如就是 js 文件,也放到 root /data/nginx/images1;这个目录里面去处理。一般就基于这样的方式来匹配用户请求的uri,但这个uri不是用户输入的,就像这个网站一样,用户只要点一下首页就行了,这个首页里面会有html文件去调用,其实就是在用户请求的那个页面里面做各种调用,像 js 文件、jpg 文件、gif 文件,包括各种编辑文件都会捕获到。所以这里就基本包含了所有类型的图片格式,把这些匹配成功之后,就把它放到一个资源目录里去显示一个静态资源目录。
location ~*\.(gif | jpg |jpeg | bmp| png | tiff | tif | ico| wmf | js)$ {
root /data/nginx/images1;
index index.html;
}
这个也是不区分大小写的,这个目录就放在 data/nginx/images1;
,image 这个地方通常都是 static。那么就需要在static 里面放各种各样的资源,再cd 过去,拷贝一个1.jpg,拷完之后把 nginx reload 一下就可以测试了:/apps/nginx/sbin/nginx-s reload
。这个时候再访问资源都会往上转,只要是这些文件就可以,比如 js,看看能不能捕获到。echo 一个 js,让它访问到 linux39.js,访问 jpg 图片或者 js 文件的时候,它也会到 nginx,nginx 通过后缀转换到相应的 location 里处理,location 当中定义的路径就会到 data/nginx/images,会在这里找这些图片。现在就可以去测试了,比如访问 1.jpg,访问 js 文件也是没有问题的。
2、大多数公司都是基于这样的方式来实现动静分离的
location ~*\.(gif | jpg |jpeg | bmp| png | tiff | tif | ico| wmf | js)$ {
root /data/nginx/images1;
index index.html;
}
这个使用场合非常多,还有一些是基于 tfs 这个路径的,这个路径可以某定它的开头,也可以不某定,像淘宝那种可能需要 tfs,一旦匹配到 tfs 后就往上转。
(五)优先级
1、在众多优先级中,精确匹配的优先级是最高的,它通常用于精确匹配指定文件,比如 favicon.ico,这是一个图标,浏览器会找这个图标,第一次都会报错,因为服务器上现在还没有放这个。 通常会用于匹配公司的图标,比如 logo 图标或者 js 文件,包括 jsp 这种固定格式的或者叫固定名称的文件,可以用=/。
2、location 优先级:
(location =)>(location 完整路径)>(location ^~路径)>(location~,~*正则顺序)>(location 部分起始路径)>(/)
等于号大于完整的域名,假如写个 location,这个 location 叫 about,这个优先级是次高的。再往下就是这个通过尖角号某定的模糊开头,某定的开头就是static12345678,因为它后面还要匹配一些字符,这个优先级排第三,about 优先级高于 static。再往下是区分大小写和不区分大小写,再往下是模糊匹配。这里用的比较多的是完整的路径匹配,就是基于正常表达式去匹配一个完整的路径来做调度。像淘宝可能就用到了,tfs 会匹配到。
还有这种区分大小写或者不区分大小写的,最早是不区分大小写的方式去匹配用户请求uri的后缀来做动静分离,这个用的次数比较多。部分起始路径是部分机制,/就类似于没有匹配开头的一种,这个是部分机制。等于号是最高的,^~是次的,然后是区分和不区分大小写。最后是模糊匹配,所有匹配成功之后都会到这
location/ {
root /data/nginx/html/pc;
index index.html index.htm;,
}
如果写了很多 location,但是用户请求的都没在这里,那么就到这个路径 /data/nginx/html/pc 里找,有就会显示没有就会出现404。
(六)生产使用案例
1、生产里面有这个示例,把这个示例列出来。
location= /{
……;
}
等于号有时候会加上,有的用户在网站访问的时候会加斜线,如果加上斜线会直接优先匹配,如果访问的就是跟,就会优先显示,不再往其它 location 转了。
location /{
……;
}
这个是默认的 location,如果所有的 location 都没有匹配成功,再走这, location= /是用于优先匹配的,如果加斜线就会直接显示,如果斜线下面再加什么资源,那么就再往下走。
location ^~ /static/{
……;
}
这个是匹配技能,也有做动静分离的。
lacation -* \.(gif | jpg | jpeg | png | css | js | ico)$ {
……;
}
或者做后缀名动静分离。
location ~*/app1 {
……;
}
location ~*/app2 {
……;
}
这个是做判断启用的,有个概念就是如果用户的请求后面加了 app1,app2 这样的路径,这个应用名称一般是那些强化服务的名称,这个时候就再往后面的 tomcat 服务器转,就不在本机处理了。后面还有很多 tomcat 服务器,如果扫到 uri,nginx 处理不了的时候,就基于 location 做匹配,匹配到那些处理不了的 uri,这个也就是所说的动静分离。
2、nginx 只做静态资源,比如这些 js 文件,加号程序就往后面转也就是那些动态资源。这些 jsp 文件里面会写很多类或者函数,然后去连数据库和中间键,做一些和数据相关的操作。这个要用加法程序来实现,静态文件是实现不了的,比如构造 MQ 做业务调度,就由它们再调后端数据层的服务。nginx 指数类图片,包括 js 文件,去处理这些数据库或者 MQ,或者 Kappa 的数据交互, 所以静态层在 nginx 上,动态层在后面那些 php 或者 tomcat 上,目前大部分是在 tomcat 上。因为有很多方式可以实现跑加号服务,不一定是 tomcat,大部分中小型互联网公司都是用 tomcat。
3、这个就是 location 的主要使用方式。区位大小写和不区分大小写比较重要,基于文件的后缀实现动静分离也很重要。