Location指令是nginx中最关键的指令之一,location指令的功能是用来匹配不同的url请求,进而对请求做不同的处理和响应,这其中较难理解的是多个location的匹配顺序,本文会作为重点来解释和说明。
开始之前先明确一些约定,我们输入的网址叫做请求uri,nginx用请求uri与location中配置的uri做匹配。
首先我们先简单了解nginx的文件结构,nginx的HTTP配置主要包括三个区块,结构如下:
Global: nginx 运行相关
Events: 与用户的网络连接相关
http
http Global: 代理,缓存,日志,以及第三方模块的配置
server
server Global: 虚拟主机相关
location: 地址定向,数据缓存,应答控制,以及第三方模块的配置
从上面展示的nginx结构中可以看出location属于请求级别配置,这也是我们最常用的配置。
所有的所有的所有的指令,都要以 ; 结尾
Location 块通过指定模式来与客户端请求的URI相匹配。
Location基本语法:
匹配uri类型,有四种参数可选,当然也可以不带参数。
命名location,用@来标识,类似于定义goto语句块。
location [ = | ~ | ~* | ^~ ] /uri/ { … }
location @/name/ { … }
参数 | 解释 |
---|---|
空 | location后没有参数直接跟着URI,表示前缀匹配,代表跟请求中的URI从头开始匹配。 |
= | 用于标准 uri 前,要求请求字符串与其严格匹配,成功则立即处理,nginx停止搜索其他匹配。 |
^~ | 用于标准 uri 前,并要求一旦匹配到就会立即处理,不再去匹配其他的那些个正则 uri,一般用来匹配目录 |
~ | 用于正则 uri 前,表示 uri 包含正则表达式, 区分大小写 |
~* | # 用于正则 uri 前, 表示 uri 包含正则表达式, 不区分大小写 |
@ | ”@“ 定义一个命名的 location,@定义的locaiton名字一般用在内部定向,例如error_page, try_files命令中。它的功能类似于编程中的goto。 |
Nginx有两层指令来匹配请求URI。第一个层次是server指令,它通过域名、ip和端口来做第一层级匹配,当找到匹配的server后就进入此server的location匹配。location的匹配并不完全按照它们在配置文件中出现的顺序来匹配,请求URI会按如下规则跟server里配置的location匹配。
寻找有没有“=”等号参数完全匹配的location,如果有完全匹配的等号location则停止匹配,执行该location中的指令,不去匹配其它类型的location。
匹配所有非正则表达式URI的location(包括空,=,^~ 三种参数)。找到请求URI和location URI按前缀匹配最长的location,如果这个最长的location的参数是 ^~,则停止匹配,执行该location中的指令,否则暂存该location。
匹配正则表达式URI的location(包括~,~*两种参数),按location在配置文件中出现的顺序匹配,如果找到第一个匹配的locaiton则停止匹配,执行该location。
匹配完所有正则表达式都没有匹配的location,则执行第二步中暂存的最长前缀匹配location。
简单来说按这个规则 location 匹配命令的优先级从高到低依次为(序号越小优先级越高):
1. location = /a {…} #精准匹配
2. location ^~ /a {…} #前缀匹配
3. location ~ /a.* {…} #正则匹配(区分大小写)
4. location ~* /a.* {…} #正则匹配(不区分大小写)
5. location /a {…} #最长前缀匹配,但是优先级低于正则匹配。 /a 和 ^~ /a 会冲突,报错
6. location / {} #任何没有匹配成功的,都会匹配这里处理
让我们用一个例子来说明上面的内容:
# 请求:
# /
# /index.html
# /documents/document.html
# /images/1.gif
# /documents/1.jpg
location = / {
# 只匹配 / 的查询.
[ configuration A ]
}
# 能匹配成功: /
location / {
# 匹配任何请求,因为所有请求都是以”/"开始
# 但是更长字符匹配或者正则表达式匹配会优先匹配
[ configuration B ]
}
#能匹配成功:/index.html
location /documents/ {
# 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索/
# 只有后面的正则表达式没有匹配到时,这一条才会采用这一条/
[ configuration C ]
}
# 能匹配成功:/documents/document.html
location ~ /documents/ABC {
# 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索/
# 只有后面的正则表达式没有匹配到时,这一条才会采用这一条/
[ configuration CC ]
}
location ^~ /images/ {
# 匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。/
[ configuration D ]
}
# 能成功匹配:/images/1.gif
location ~* \.(gif|jpg|jpeg)$ {
# 匹配所有以 .gif、.jpg 或 .jpeg 结尾的请求,不区分大小写
# 然而,所有请求 /images/ 下的图片会被 [ config D ] 处理,因为 ^~ 到达不了这一条正则/
[ configuration E ]
}
# 能成功匹配:/documents/1.jpg
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
请求URI中问号后面的参数是不能在location中匹配到的,这些参数存储在$query_string变量中,可以用if来判断。
例如,对于参数中带有单引号’进行匹配然后重定向到错误页面。
/plus/list.php?tid=19&mid=1124’
if ( $query_string ~* “.*[;’<>].*” ){
return 404;
}
这个很多解释不太准确,我有必要多说几句。
对于请求URI结尾是否带有/,一般的处理逻辑是带/表示访问目录,不带/表示访问文件,如果文件不存在也会去匹配目录。例如访问http://www.nginx.cn/images/和...://www.nginx.cn/images,前面的请求会匹配目录,后面的请求会先匹配文件,文件不存再匹配目录
对于locatioin中的URI来说,如果URI的结尾带有/,并且location要执行的命令式是proxy_pass、fastcgi_pass、uwsgi_pass、scgi_pass、memcached_pass、grpc_pass之一。例如:
location /images/ {
proxy_pass http://www.redis.com.cn
}
对于这种情况,nginx会做特殊处理,不管images命名的文件或目录存在不在,如果你访问http://www.nginx.cn/images会...://www.nginx.cn/images/。
所以如果你想这两种请求对应不同的处理,就要明确增加不带/结尾的location配置。
location /images {
proxy_pass http://www.rabbitmq.cn
}
location /images/ {
proxy_pass http://www.redis.com.cn
}
带有”@“的location是用来定义一个命名的location,这种location不参与请求匹配,一般用在内部定向。例如用在error_page, try_files命令中。它的功能类似于编程中的goto。
location /images {
try_files $uri $uri/ @name;
}
location @name {
…
}
所以实际使用中,个人觉得至少有三个匹配规则定义,如下:
直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
location = / {
proxy_pass http://tomcat:8080/index
}
location ^~ /static/ {
root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}
location / {
proxy_pass http://tomcat:8080/
}
前提条件:nginx源码或nginx plus源码、一个代理服务器或一个代理服务器组、SSL证书和私钥,你可以从一个可信任证书颁发机构(CA)购买一个服务器证书,或者你可以使用openssl库创建一个内部CA签名
查看nginx模块,如果看到with-ssl那就是有的。注册ssl证书并下载,配置nginx就比如说,还没有配置https前你配置了80,那么你http://域名/直接默认访问80端口,那么一样的
首先让nginx服务器监听两个端口,分别是80端口和443端口,注意监听443端口的时候需要配置证书的认证以及创建自签名证书!关于证书的认证的以及创建自签名的证书,nginx的配置如下,只给出了两个server的配置,可以直接复制到http块中。
常见的服务器有三种:Nginx、IIS、Apache,都可以配置https,但是没必要全部知道,因为Nginx可以起到反向代理的作用,会配置Nginx就足够了。在/etc/nginx/conf.d目录下新建https.conf
开启Gzip:给Nginx上 ngx_http_gzip_module 这个模块,用 nginx -V 命令查看 configure arguments 是否有,没有的话需要编译加载这个模块;给文件做缓存:图片文件,字体文件,js和css都是些可以用来缓存的文件
ginx和php-fpm对于-USR2、-HUP信号的处理方式不一样:TERM, INT(快速退出,当前的请求不执行完成就退出),QUIT (优雅退出,执行完当前的请求后退出)
php-fpm采用master/worker架构设计, master进程负责CGI、PHP公共环境的初始化及事件监听操作。worker进程负责请求的处理功能。在worker进程处理请求时,无需再次初始化PHP运行环境,这也是php-fpm性能优异的原因之一
总有一些不怀好意的人来访问我的网站,而且频率还很高,所以就用简单的方式禁止访问,就用 Nginx 来实现。想要添加黑名单,只要在 blocksip.conf 中添加 IP ,然后 reload 即可。
客户端就可以通过请求代理服务器,获取想要的资源,但客户端并不知道给他资源的是哪个服务器。这种方式就是反向代理。当一台服务器的单位时间内的访问量越大的时候,服务器的压力会越大。我们通常通过负载均衡的方式来分担服务器的压力。
Nginx作为反向代理服务器,就是把http请求转发到另一个或者一些服务器上。通过把本地一个url前缀映射到要跨域访问的web服务器上,就可以实现跨域访问。对于浏览器来说,访问的就是同源服务器上的一个url
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!