8

#Nginx proxy_pass反向代理笔记

 2 years ago
source link: https://xmanyou.com/nginx-proxy_pass-details/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

关于proxy_pass模块

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass

proxy_pass模块通常用来做反向代理,既将客户端发送的请求转发到目标服务器。

Syntax:    proxy_pass URL;
Default:    —
Context:    location, if in location, limit_except

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/;

or as a UNIX-domain socket path specified after the word “unix” and enclosed in colons:

proxy_pass http://unix:/tmp/backend.socket:/uri/;

If a domain name resolves to several addresses, all of them will be used in a round-robin fashion. In addition, an address can be specified as a server group.
Parameter value can contain variables. In this case, if an address is specified as a domain name, the name is searched among the described server groups, and, if not found, is determined using a resolver.

proxy_pass中的域名会被解析,如果解析为一组服务器,则会轮流访问。

关于请求URI如何传递给服务器

A request URI is passed to the server as follows:

1). 如果proxy_pass指令中包含URI

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/;
}

那么,进行以下处理:

  • i). 标准化请求的URI
  • ii). 将标准化后的URI中与location相同的部分移除
  • iii). 剩下的URI片段,拼接到proxy_pass指令中的URI

2). 如果proxy_pass指令中不包含URI

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;
}

那么,按照以下两种情况处理:

  • i). 如果原始请求被处理过(所谓的处理,应该是指对URI进行标准化处理),则原始请求URI被发送给服务器
  • ii). 在处理改变后的URI时,完整的标准化后的请求URI被发送给服务器。

问题
什么叫 processing the changed URI: 处理改变后的URI时?
可能是指在proxy_pass之前有其他指令在处理URI,或者进行标准化?
所以,也就是说,如果proxy_pass中不包含任何URI,则传递标准化后的URI给服务器。

旧版本1.1.12以前

Before version 1.1.12, if proxy_pass is specified without a URI, the original request URI might be passed instead of the changed URI in some cases.

3). 一些特例

在一些特殊情况下,无法判断要如何替换请求URI

In some cases, the part of a request URI to be replaced cannot be determined:

3.1). location中使用了正则表达式,且同时在命名location中

那么,这时候,proxy_pass不应该设置URI。

When location is specified using a regular expression, and also inside named locations.
In these cases, proxy_pass should be specified without a URI.

问题
如果设置了怎么办?

3.2). 如果URI被rewrite指令修改了

那么,在proxy_pass中指定的URI被忽略,改变后的请求URI整个传给服务器。

When the URI is changed inside a proxied location using the rewrite directive, and this same configuration will be used to process a request (break):

location /name/ {
    rewrite    /name/([^/]+) /users?name=$1 break;
    proxy_pass http://127.0.0.1;
}

In this case, the URI specified in the directive is ignored and the full changed request URI is passed to the server.

注意
也就是说,使用了rewrite以后,再设置任何URI是没有意义的,除非是设置变量(参考下一节)。

3.3). 如果proxy_pass中使用了变量

那么,原始请求的URI被忽略,proxy_pass中的URI被传给服务器。

When variables are used in proxy_pass:

location /name/ {
    proxy_pass http://127.0.0.1$request_uri;
}

In this case, if URI is specified in the directive, it is passed to the server as is, replacing the original request URI.

注意
也就是说,如果proxy_pass中使用了变量,则原始请求URI就不再直接传给服务器,通常是对原始请求URI进行修改,并保存到proxy_pass的变量里。

原始请求与标准化请求

  • 原始请求,为客户端发送的请求,未经过任何处理
  • 标准化请求,按照一定规则进行解码和替换得到的标准URI

https://en.wikipedia.org/wiki/URI_normalization


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK