
Nginx是Igor Sysoev用C语言编写的一个web服务器,通常用于负载均衡、反向代理和HTTP缓存等。Nginx用异步的事件驱动(event-driven)的方式来处理请求,因此负载能力很强。
Nginx使用Block(如 server block, location block)来组成配置文件的层级结构,并在接收到客户端请求之后根据请求的域名(domain name),端口(port),IP地址判断处理该请求的server block,然后根据请求的资源和URI决定处理该请求的location block
Server Block
管理员可以定义多个server block作为不相关的虚拟web服务器实体,然后通过listen和server_name决定处理请求的server block
listen指令
Nginx首先会检查请求的IP地址和端口,并根据所有server block建立一个列表来处理请求。每个server block中的listen定义了这个server block能处理的IP和端口(root用户运行默认为0.0.0.0:80,非root用户运行的为0.0.0.0:8080)
listen后可以指定:
IP:port的IP地址和端口- 仅IP(端口将默认为80)
- 仅port,将监听所有接口的这个port
- 到某个
Unix socket的路径(在服务器间转发请求的时候会用到)
在将listen的值与请求进行匹配之前,Nginx会先将listen的值中所缺省的部分补充完整。然后将优先匹配准确的IP,如果不存在完全准确匹配的IP才会匹配到0.0.0.0,如果有多个IP:port匹配度相同,Nginx将会继续检查server_name
server_name指令
Nginx将server_name与请求头中的Host进行匹配,匹配的顺序:
-
优先选择第一个精确匹配到的block。
server { listen 80; server_name host.example.com; ... } -
选择以*开头的进行匹配,并优先选择最长的。
server { listen 80; server_name *.example.com; ... } -
选择以*结尾的进行匹配,并优先选择最长的。
server { listen 80; server_name www.example.*; ... } -
选择以~开头的用正则表达式进行匹配,并优先选择第一个。
server { listen 80; server_name ~^(www|host).*\.example\.com$; ... }
-
如果以上规则都无法匹配,则选择
default_server定义的默认的server_block(每个server_block只能有一个default_server),默认的default_server是localhostserver { listen 80 default_server; server_name _; ... }
Location Block
location block是server block的一部分,决定了如何处理请求的URI,格式:
location [modifier] location_match {
...
}
modifier
modifier是一个可选的参数,决定了如何解析后面的location match,modifier可选的值有:
-
(none)
前缀匹配, 如
location /site { ... }将匹配以
/site开头的URI -
=(equal sign)
完整匹配,如
location = /page { ... }将匹配
/page,而不会响应/page/index.html的请求 -
~(tilde)
大小写敏感的正则匹配, 如
location ~ \.(jpe?g|png|gif|ico)$ { ... }将匹配以
.jpg/.jpeg/.png/.gif/.ico结尾的URI, 但不会响应.JPG -
~*(tilde + asterisk)
大小写无关的正则匹配, 如
location ~* \.(jpe?g|png|gif|ico)$ { ... }.jpg和.JPG都会匹配 -
^~(carat + tilde)
非正则匹配,如
location ^~ /page { ... }能够匹配
/page/index.html
匹配顺序
Nginx优先选择正则表达式进行匹配,但是使用=和^~这两个modifier可以覆盖这一特性。排序对匹配过程也有一定的影响,因为Nginx在匹配到最长最精确的location之后就会停止匹配。
- 将所有非正则表达式的
location_match与请求的URI进行对比。 - 与
modifier为=的进行完整匹配。 - 选择最长
location_match前缀进行匹配,如果modifier为^~则匹配成功。 - 进行正则表达式匹配
- 用其他前缀匹配
其他指令
-
index
语法:
index file ...;默认为index index.html;index指令指定了被作为index的文件,比如上面的index.html但是在下面这种情况下,对
/index.html的请求将会被第二个location block处理,因为第一个与/index.html并不是完全匹配。location = / { index index.html; } location / { ... } -
try_files
root /var/www/main;location / { try_files $uri $uri.html $uri/ /fallback/index.html; } location /fallback { root /var/www/another; }对
/page的请求将会首先进入第一个location, 然后尝试在/var/www/main下依次查找page,page.html,page/,如果都没有找到的话将会被重定向到/fallback/index.html,并由第二个location提供/var/www/another/fallback/index.html -
rewrite
通过Perl兼容的正则表达式改变请求的URI,语法:
rewrite regex replacement [flag];flag的值可以是:
-
last
结束当前的rewrite指令,并用修改过的URI去匹配其他的
location block。 -
break
结束当前的rewrite指令。
-
redirect
当替换的URI(
replacement)不以“http://”,“https://”,“$scheme”开头时进行状态码为302的暂时性的重定向。 -
permanent
返回一个状态码为301的永久重定向。
-
-
error_page
root /var/www/main; location / { error_page 404 /another/whoops.html; } location /another { root /var/www; }除了
/another之外的请求都会在/var/www/main查找请求的资源,如果没有找到相关资源将会重定向到/another/whoops.html,由第二个location block处理,查找/var/www/another/whoops.html