Nginx location的使用

Nginx是一款自由的、开源的、高性能的HTTP服务器和反向代理服务器,此文主要是记录一下在Nginx配置时,location应该如何配置。

http区块

Nginx的HTTP配置主要包括三个区块,结构如下:

http { //这个是协议级别
  include mime.types;
  default_type application/octet-stream;
  keepalive_timeout 65;
  gzip on;
    server { //这个是服务器级别
      listen 80;
      server_name localhost;
        location / { //这个是请求级别
          root html;
          index index.html index.htm;
        }
      }
}

location区块

location是Nginx服务器非常核心的配置,用于匹配指定的uri(请求uri不包含查询字符串,如http://localhost:8080/test?id=10,请求uri是/test)。一般在修改Nginx配置时,大部分也是围绕着location这个配置进行修改。

不部分情况下其实是不需要很复杂的配置的,做个动静分离已经能满足绝大多数单体服务的;而在分布式环境下,某个server中通常需要配置很多location,来将请求分发到不同的微服务下,此时你必须非常熟悉location 的配置和匹配规则,否则真是无从下手。

下面来看一下一个简单的location配置:


location / {
     root   home/;
     index  index.html;
}

基本语法

location [ = | ~ | ~* | ^~ | @] uri {...}

意思是可以用 = ~ ~ *或 ^~ @ 符号为前缀,当然也可以没有前缀(因为 [A] 是表示可选的 A ; A|B 表示 A 和 B 选一个,上面的样例就属于没有符号前缀的例子),紧接着是 uri ,再接着是{…} 指令块,整个意思是对于满足这样条件的 uri 适用指令块 {…} 的指令。

匹配模式

所有的模式可以分为两种,匹配顺序也是基于这两种模式来进行处理的:

  • 普通字符串(literal strings) ,是以无前缀、 = ^~ 三种模式的 uri;
  • 正则表达式(regular expression),是以 ~ ~* 前缀两种模式的uri;

匹配顺序

  1. 普通字符 = 精确匹配。如果发现精确匹配,nginx停止搜索其他匹配
  2. 其他普通字符匹配,先匹配所有普通字符串,将最精确(命中长度)的匹配暂时存储;
  3. 如果第2步中有 ^~ 命中的,则跳过第4步,直接到第5步;
  4. 按照配置文件中的声明顺序进行正则表达式匹配,只要匹配到一条正则表达式,则停止匹配,取正则表达式为匹配结果;
  5. 如果所有正则表达式都匹配不上,则取之前普通字符串中存储的结果;
  6. 如果普通字符串和正则表达式都匹配不上,则报404 NOT FOUND。

总结一下就是: 普通命中顺序无所谓,因为是按命中精准度来确定的 ;正则命中区分顺序,因为是从前往后命中的,命中一个后就不会继续匹配下一个正则。

example

  1. 无前缀表示:必须以指定模式开始:

    server {
      listen 80;
      server_name localhost;
      location /abc {
        ……
      }
    }
    那么,如下是对的:
    http://baidu.com/abc
    http://baidu.com/abc?p1
    http://baidu.com/abc/
    http://baidu.com/abcde
  2. ^~ 表示:类似于无前缀修饰符的行为,区别是,如果此模式匹配,是会停止搜索正则匹配的,但是会继续搜索普通模式。
  3. =表示:必须与指定的uri精确匹配

    server {
      listen 80;
      server_name localhost;
      location = /abc {
        ……
      }
    }
    那么,如下是对的:
    http://baidu.com/abc
    http://baidu.com/abc?p1
    如下是错的:
    http://baidu.com/abc/
    http://baidu.com/abcde
  4. ~ 表示:指定的正则表达式要区分大小写

    server {
      listen 80;
      server_name localhost;
               location    ~   ^/abc$ {
        ……
      }
    }
    那么,如下是对的:
    http://baidu.com/abc
    http://baidu.com/abc?p1=11&p2=22
    如下是错的:
    http://baidu.com/ABC
    http://baidu.com/abc/
    http://baidu.com/abcde
  5. ~* 表示:指定的正则表达式不区分大小写

    server {
      listen 80;
      server_name localhost;
            location ~* ^/abc$ {
        ……
      }
    }
    那么,如下是对的:
    http://baidu.com/abc
    http://baidu..com/ABC
    http://baidu..com/abc?p1=11&p2=22
    如下是错的:
    http://baidu..com/abc/
    http://baidu..com/abcde
  6. @表示:这些location区段客户端不能访问,只可以由内部产生的请求来访问,如try_files或error_page等,以error_page为例:

        server {
      listen 80;
      server_name localhost;
      error_page 404 @fallback
          
              location /abc {
                 //检测文件4.html和5.html,如果存在正常显示,不存在就去查找@qwe值  
                try_files    /4.html        /5.html      @fallback;      
               }   
              location @fallback  {
                 proxy_pass http://www.baidu.com;    --跳转到百度页面
          }
      }

    当uri匹配上/abc时,会按顺序检测文件的存在性,并且返回找到的第一个文件,最后一项就是跳转到百度,这种写法可以替代原本常用的rewrite,貌似可以提高解析效率;

root&alias区别

Nginx指定文件路径有两种方式root和alias,两种指令有不同的使用方法和作用域,root可以配置在http、server、location、if区块中,但是alias只能配置在location区块中。

root与alias主要区别在于Nginx如何解释location后面的uri,这会使两者分别以不同的方式将请求映射到服务器文件上。

  • root的处理结果是:root路径+location路径

    location ^~ /appImg/{
        root /home/nginx;
    }

    这个location相当于访问服务器上的文件路径: /home/nginx/appImg/abc.jpg

  • alias的处理结果是:使用alias路径替换location路径

    location ^~ /appImg/{
        alias /home/nginx/;
    }

    这个location相当于访问服务器上的文件目录:/home/nginx/abc.jpg(即alias不会使用location后面配置的路径),而且如果alias 指定的是目录,后面一定要加上 /,否则会找不到文件。

你可能感兴趣的:(后端,nginx)