我们在使用 nginx 做反向代理的时候,通常会配置 upstream,server,location。这篇文章不会对 nginx 的配置做深入的探讨,主要关注点在于:
当 nginx 收到一个请求时,是如何进行响应的?包括:
- 如何选择 server 进行响应
- 如何 match location
- 如何进行错误处理
如何选择 server 进行响应
- 用请求 Header 中的 host 字段与 server_name 进行匹配
- 如果能正确匹配,则选择匹配上的 server 进行响应
- 未能正确匹配,则选择配置的 default_server 进行响应
- 如果没有配置 default_server,则选择第一个 server 进行响应
Tips
- 如果需要阻止 Header 中不带 host 的请求,参考这里
- 如果在 listen 中配置了 IP,则选择 server 的时候,会强制要求 IP 和 Host 都 match
- 不同的 IP + port 可以配置不同的 default_server
如何 match location
Syntax 官方定义
location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
A location can either be defined by a prefix string, or by a regular expression. Regular expressions are specified with the preceding “~*” modifier (for case-insensitive matching), or the “~” modifier (for case-sensitive matching).
其中 =
,~
,~*
,^~
被称为 modifier
—— 修饰符。
=
,^~
或者没有修饰符的时候,为前缀匹配,其中前两者会终止搜寻~
,~*
,为正则匹配
Syntax 举例
location /uri
:前缀匹配location = /uri
:前缀匹配 - 精确location ^~ /uri
:前缀匹配 - 终止location ~ /uri
:正则匹配 - 区分大小写location ~* /uri
:正则匹配 - 忽略大小写location ~ ^/uri
:正则匹配 - 注意与^~
区分
匹配规则 官方说明
To find location matching a given request, nginx first checks locations defined using the prefix strings (prefix locations). Among them, the location with the longest matching prefix is selected and remembered.
Then regular expressions are checked, in the order of their appearance in the configuration file. The search of regular expressions terminates on the first match, and the corresponding configuration is used. If no match with a regular expression is found then the configuration of the prefix location remembered earlier is used.
If the longest matching prefix location has the “^~” modifier then regular expressions are not checked.
Also, using the “=” modifier it is possible to define an exact match of URI and location. If an exact match is found, the search terminates. For example, if a “/” request happens frequently, defining “location = /” will speed up the processing of these requests, as search terminates right after the first comparison.
匹配规则 释义
- 先搜寻最长的前缀匹配
- 如果找到,且带有
^~
或=
修饰符,则立即停止匹配,并使用该 location - 否则继续进行搜寻
- 如果找到,且带有
- 按照先后顺序,寻找第一个匹配的正则
- 如果找到,则使用该 location
- 否则,如果 1 中有匹配的 location,则使用该 location
- 否则,进入 404
Special Location
The “@” prefix defines a named location. Such a location is not used for a regular request processing, but instead used for request redirection. They cannot be nested, and cannot contain nested locations.
If a location is defined by a prefix string that ends with the slash character, and requests are processed by one of proxy_pass, fastcgi_pass, uwsgi_pass, scgi_pass, or memcached_pass, then the special processing is performed. In response to a request with URI equal to this string, but without the trailing slash, a permanent redirect with the code 301 will be returned to the requested URI with the slash appended.
To be validated
location /uri {
proxy_pass http://localhost;
}
location /uri/ {
proxy_pass http://localhost;
}
location / {
proxy_pass http://localhost/uri;
}
location / {
proxy_pass http://localhost/uri/;
}
Refs
上一篇《ES6: Proxy, Reflect and Object.defineProperty》 下一篇《忘忧信箱》