一、写作背景

和之前一上来就要写大而全,甚至要写成一个完整的说明书的想法不同,我从这篇文章开始,尝试着从当前正在使用的小点入手,只讲解该小点和其深度相关的内容,然后快速发布、迭代文章。目前对我来说,积累 100 篇文章的内容来回斟酌修改,不如连续快速发布成功 100 篇文章。

二、概要

本文作为 NGINX 使用的一个系列,主要讲解在反向代理后端服务时,NGINX 的配置。

三、反向代理

proxy_pass 指令

在使用 NGINX 的反向代理功能中,最重要的一条指令就是 proxy_pass。以下为官方文档对于该指令的说明:

Sets the protocol and address of a proxied server and an optional URI to which a location should be mapped. As a protocol, “http” or “https” can be specified. The address can be specified as a domain name or IP address, and an optional port:

proxy_pass http://localhost:8000/uri/;

翻译过来就是设置一个代理的服务器和一个可选 URI 的协议和地址到一个需要映射的路径上。

当收到的请求符合设置的路径时,NGINX 会把请求转发到代理的服务器上,由该代理服务器负责处理该请求,并将响应再转发出去。

proxy_pass 路径规则

proxy_pass 这条指令一共涉及到两个路径,一个是要映射的路径,即跟在 location 后面的;一个是代理的服务器的地址,即跟在 proxy_pass 指令后面的。本节重点放在说明跟在 proxy_pass 指令后面的路径规则。

  • If the proxy_pass directive is specified with a URI, then when a request is passed to the server, the part of a normalized request URI matching the location is replaced by a URI specified in the directive:
location /name/ {
   proxy_pass http://127.0.0.1/remote/;
}
  • If proxy_pass is specified without a URI, the request URI is passed to the server in the same form as sent by a client when the original request is processed, or the full normalized request URI is passed when processing the changed URI:
location /some/path/ {
  proxy_pass http://127.0.0.1;
}

翻译过来是说如果 proxy_pass 指令指定了一个 URI,当请求被传到服务器时,匹配路径的那部分 URI 会被 proxy_pass 指令指定的 URI 替换掉;反之匹配的的 URI 会原封不动又传递给服务器。这里的 URI 指的是从 IP 或者端口以后第一个 / 及之后的路径。

例如要匹配的 location/api/proxy_pass 指定的服务器是 http://127.0.0.1:8080/,则实际访问的服务器地址是 http://127.0.0.1:8080/;而如果服务器地址是 http://127.0.0.1:8080,则实际转发过去的请求地址是 http://127.0.0.1:8080/api/

更完整的例子可以参考下面。

# 访问:   /api/                           后端:   /api/
# 访问:   /api/xx                         后端:   /api/xx
# 访问:   /api/xx?aa                      后端:   /api/xx?aa
# 访问:   /api-xx?aa                      未匹配
location /api/ {
    proxy_pass http://node:8080;
}

# 访问:   /api/                           后端:   /
# 访问:   /api/xx                         后端:   /xx
# 访问:   /api/xx?aa                      后端:   /xx?aa
# 访问:   /api-xx?aa                      未匹配
location /api/ {
    proxy_pass http://node:8080/;
}

参考资料