nginx主要是公司运维同窗必须掌握的知识,涉及到反向代理、负载均衡等服务器配置。前端开发尤为是纯前端开发来讲对nginx接触的并很少,可是在一些状况下,nginx仍是须要前端本身来搞;例如咱们公司的开发环境和测试环境,虽然qa能够帮助搞定配置,可是每新增一个前端模块或者模块nginx配置常常变动都求着qa搞,麻烦别人还不如本身来搞,这样更能理解本身的需求。这些都须要前端开发对nginx有所理解,下面咱们来讲说nginx最基础的server和location匹配规则。php
nginx的server
块能够配置多个,那么一个请求该匹配那个server块呢,这主要是根据server块的server_name
和listen
来决定的。其中server_name
仅仅检查请求的“Host”头以决定该请求应由哪一个虚拟主机来处理。css
先看一个例子:html
server { listen 8001; server_name *.net; } server { listen 8001; server_name baidu.net; } server { listen 8001; server_name baidu.*; }
经过测试,发现相同listen端口的状况下,多个server的匹配顺序以下:前端
以上若都没有匹配,那么其会走默认的server,即:nginx
一种特殊状况,若是nginx中只为某个listen端口配置一个server块的话,那么nginx是不会根据该端口的server_name进行匹配的。由于只有一个server域,那么根据上面没有匹配的规则的状况下会走第一个匹配listen端口的server块。web
server { listen 8001; server_name baidu.net; } server { # server没有配置listen的话,root用户默认是80端口,非root用户默认8080 server_name server.com; }
如上面8001端口只有一个server的状况下,任何server_name访问server_name:8001
都会匹配上面server块(前提是server_name对应域名能请求到该机器上)。正则表达式
另外一种特殊状况,server块配置的虚拟主机是基于域名和IP混合的。以下所示:后端
server { listen 192.168.1.1:8001; server_name example.org www.example.org; ... } server { listen 192.168.1.1:8002; server_name example.com www.example.com; ... }
这种状况下,其匹配顺序是:tomcat
第二点须要补充一下,看请求的Host头是否匹配server_name,要知足一个条件,即经过server_name指定的域名能够访问到当前nginx配置所在的机器,由于经过域名访问nginx所在的机器最终仍是经过ip的形式来访问的。服务器
好比,访问www.example.org,最终经过dns解析出nginx所在的ip地址来进行访问的,又由于该server监听8001端口,因此经过www.example.org:8001也能够命中192.168.1.1:8001所在的server块。
一个示例:
location = / { # 精确匹配 / ,主机名后面不能带任何字符串 [ configuration A ] } location / { # 由于全部的地址都以 / 开头,因此这条规则将匹配到全部请求 # 可是正则和最长字符串会优先匹配 [ configuration B ] } location /documents/ { # 匹配任何以 /documents/ 开头的地址,匹配符合之后,还要继续往下搜索 # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条 [ configuration C ] } location ~ /documents/Abc { # 匹配任何以 /documents/Abc 开头的地址,匹配符合之后,还要继续往下搜索 # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条 [ configuration CC ] } location ^~ /images/ { # 匹配任何以 /images/ 开头的地址,匹配符合之后,中止往下搜索正则,采用这一条。 [ configuration D ] } location ~* \.(gif|jpg|jpeg)$ { # 匹配全部以 gif,jpg或jpeg 结尾的请求 # 然而,全部请求 /images/ 下的图片会被 config D 处理,由于 ^~ 到达不了这一条正则 [ configuration E ] } location /images/ { # 字符匹配到 /images/,继续往下,会发现 ^~ 存在 [ configuration F ] } location /images/abc { # 最长字符匹配到 /images/abc,继续往下,会发现 ^~ 存在 # F与G的放置顺序是没有关系的 [ configuration G ] } location ~ /images/abc/ { # 只有去掉 config D 才有效:先最长匹配 config G 开头的地址,继续往下搜索,匹配到这一条正则,采用 [ configuration H ] } location ~* /js/.*/\.js { # 不区分大小写匹配 [ configuration I ] }
=
开头表示精确匹配,匹配则终止后续查找;如 A 中只匹配根目录结尾的请求,后面不能带任何字符串.^~
开头表示uri以某个常规字符串开头,不是正则匹配,匹配则终止后续查找,包括正则匹配,它依然支持最长匹配原则~
开头表示区分大小写的正则匹配;~*
开头表示不区分大小写的正则匹配/
通用匹配, 若是没有其它匹配,任何请求都会匹配到location 顺序 no优先级:
关于location的优先级须要认知三点:
最长匹配
原则;正则location匹配与顺序有关,可是正则location依然采用最长匹配
原则^~
则一旦该普通规则匹配上,则不会进行后续匹配了,即便是正则匹配;=
严格匹配一旦匹配,也不会后续正则匹配因此,location的优先级以下:
(location =) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 完整路径) > (location 部分起始路径) > (/)
按照上面的location写法,如下的匹配示例成立:
config A
config B
configuration D
config D
config C
configuration E
config CC
因此实际使用中,我的以为至少有三个匹配规则定义,以下: #直接匹配网站根,经过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。 #这里是直接转发给后端应用服务器了,也能够是一个静态首页 # 第一个必选规则 location = / { proxy_pass http://tomcat:8080/index } # 第二个必选规则是处理静态文件请求,这是nginx做为http服务器的强项 # 有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用 location ^~ /static/ { root /webroot/static/; } location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ { root /webroot/res/; } #第三个规则就是通用规则,用来转发动态请求到后端应用服务器 #非静态文件请求就默认是动态请求,本身根据实际把握 #毕竟目前的一些框架的流行,带.php,.jsp后缀的状况不多了 location / { proxy_pass http://tomcat:8080/ }