ChsHttpProxyModule
概要
此模块能代理请求到其它服务器.
这是 HTTP/1.0 版本的代理,暂时无法保持 keep-alive 的请求.(因此,到后端的链接每次请求都会创建和关闭)
Nginx 和浏览器使用 HTTP/1.1 进行对话,而跟后台服务器使用 HTTP/1.0,所以它能处理浏览器keep-alive的请求
Example:
location / { proxy_pass http://localhost:8000; proxy_set_header X-Real-IP $remote_addr; }
注意一点,当使用HTTP PROXY 模块时(或者甚至是使用FastCGI时),用户的整个请求会在nginx中缓冲直至传送给后端被代理的服务器.因此,上传进度的测算就会运作得不正确,如果它们通过测算后端服务器收到的数据来工作的话
指令
proxy_buffer_size
syntax: proxy_buffer_size the_size
default: proxy_buffer_size 4k/8k
context: http, server, location
该指令设置缓冲区大小,从代理后端服务器取得的第一部分的响应内容,会放到这里.
小的响应header通常位于这部分响应内容里边.
默认来说,该缓冲区大小等于指令 proxy_buffers
所设置的;但是,你可以把它设置得更小.
proxy_buffering
syntax: proxy_buffering on|off
default: proxy_buffering on
context: http, server, location
该指令开启从后端被代理服务器的响应内容缓冲.
如果缓冲区开启,nginx假定被代理的后端服务器会以最快速度响应,并把内容保存在由指令proxy_buffer_size
和 proxy_buffers
指定的缓冲区里边.
如果响应内容无法放在内存里边,那么部分内容会被写到磁盘上.
如果缓冲区被关闭了,那么响应内容会按照获取内容的多少立刻同步传送到客户端
nginx不尝试计算被代理服务器整个响应内容的大小,nginx能从服务器接受的最大数据,是由指令proxy_buffer_size
指定的.
对于基于长轮询(long-polling)的Comet 应用来说,关闭 proxy_buffering 是重要的,不然异步响应将被缓存导致Comet无法工作
proxy_buffers
语法: proxy_buffers the_number is_size;
默认值: proxy_buffers 8 4k/8k;
上下文: http, server, location
该指令设置缓冲区的大小和数量,从被代理的后端服务器取得的响应内容,会放置到这里. 默认情况下,一个缓冲区的大小等于内存页面大小,可能是4K也可能是8K,这取决于平台
proxy_busy_buffers_size
语法: proxy_busy_buffers_size size;
默认值: proxy_busy_buffers_size proxy_buffer_size * 2;
上下文: http, server, location, if
TODO: Description.
proxy_cache
syntax: proxy_cache zone_name;
default: None
context: http, server, location 该指令设置缓存区的名字,一个缓存区能用在不同的位置.
0.7.48版本开始遵从后端服务器的 "Expires", "Cache-Control: no-cache", and "Cache-Control: max-age=XXX" 响应header 0.7.66版本开始遵从"private" 和 "no-store" 响应header nginx 缓存不处理 "Vary" headers.
为保证私人信息不会无意中被缓存并发给所有用户,后端服务器可以设置 "no-cache" 或者 "max-age=0",或者proxy_cache_key中必须包含用户识别信息(比如$cookie_xxx).但是,在proxy_cache_key中使用cookie会降低公共缓存对象的命中率,所以不同的location使用不同的 proxy_cache_key值,在区分私人和公共缓存对象时是必要的
缓存取决于 proxy buffers,如果proxy_buffers 设为off,将无法使用proxy_cache.
proxy_cache_key
syntax: proxy_cache_key line;
default: $scheme$proxy_host$request_uri;
context: http, server, location 该指令指定了将包含缓存的哪些信息,比如
proxy_cache_key "$host$request_uri$cookie_user";
注意在默认的情况下,hostname将不包含在cache key里边,如果你的站点使用不同的location服务子域名,你需要包含hostname 比如,修改cache key形如:
proxy_cache_key "$scheme$host$request_uri";
proxy_cache_path
syntax: proxy_cache_path path [levels=number] keys_zone=zone_name:zone_size [inactive=time] [max_size=size];
default: None
context: http 该指令设置缓存的路径和其他缓存参数.缓存的数据保存在文件里边.缓冲中的key 是代理 URL的MD5值,它与文件名对应 Levels 设置了子目录的个数,比如:
proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=one:10m;
文件名行如: /data/nginx/cache/c/29/b7f54b2df7773722d382f4809d65029c
你能使用1和2的任何组合来表示level的格式:X, X:X, or X:X:X e.g.: "2", "2:2", "1:1:2".最多3层
所有active的key和元数据都保存在共享内存中-缓存区域(zone),在keys_zone中定义该缓存区域的名字和大小.
注意:每个定义的ZONE都需要有唯一的路径,比如:
proxy_cache_path /data/nginx/cache/one levels=1 keys_zone=one:10m; proxy_cache_path /data/nginx/cache/two levels=2:2 keys_zone=two:100m; proxy_cache_path /data/nginx/cache/three levels=1:1:2 keys_zone=three:1000m;
如果缓存中的数据在inactive中定义的时间内没有被访问,将被删除.默认设置inactive是10分钟
特殊进程"cache manager"控制了磁盘缓存的大小,该参数在max_size定义,当超出大小后最少使用的数据将被删除
ZONE必须根据页面的多少来设置合适的大小.一个页面(文件)的元数据大小取决于操作系统,当前 FreeBSD/i386 是64 bytes, FreeBSD/amd64是128 bytes 当ZONE满了以后,key将按照LRU算法来替换
proxy_cache_path 和 proxy_temp_path 位于相同的文件系统(same filesyetem,not mount piont).
proxy_cache_methods
syntax: proxy_cache_methods [GET HEAD POST];
default: proxy_cache_methods GET HEAD;
context: http, server, location
GET/HEAD is syntax sugar,你无法通过如下设置来禁用GET/HEAD请求
proxy_cache_methods POST;
proxy_cache_min_uses
syntax: proxy_cache_min_uses the_number;
default: proxy_cache_min_uses 1;
context: http, server, location
请求的最小次数,超过这个次数后端响应才将被缓存起来
proxy_cache_valid
syntax: proxy_cache_valid reply_code [reply_code ...] time;
default: None
context: http, server, location 该指令设置不同响应的缓存时间,例如:
proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m;
为200和302响应设置10分钟的缓存时间,404为1分钟
如果仅设置有效时间
那么只有200 301 302响应会被缓存
当然,你能使用参数"any"来设置缓存所有的响应
proxy_cache_valid 200 302 10m; proxy_cache_valid 301 1h; proxy_cache_valid any 1m;
Note: you must set this option for any persistent caching to occur.
proxy_cache_use_stale
syntax: proxy_cache_use_stale [error|timeout|updating|invalid_header|http_500|http_502|http_503|http_504|http_404|off] [...];
default: proxy_cache_use_stale off;
context: http, server, location
该指令告诉nginx什么时候提供旧的缓存.该指令的参数类似于proxy_next_upstream和'updating结合'的情况
你能设置'updating'参数来防止cache stampedes (当多个进程尝试同时更新同一个缓存)的情况.这将使同一个缓存只有一个进程能更新.
proxy_connect_timeout
语法: proxy_connect_timeout timeout_in_seconds
上下文: http, server, location 该参数定义了跟代理服务器连接的超时时间,必须留意这个time out时间不能超过75秒. 这并不是服务器开始返回页面的时间(这是proxy_read_timeout的定义).如果upstream服务器在线,但是挂死(比如,它暂时没有足够的进程去处理你的请求,先放在连接池里边等待处理),这时这个参数无法帮助你,因为跟服务器的连接已经建立了.
proxy_headers_hash_bucket_size
语法: proxy_headers_hash_bucket_size size;
默认值: proxy_headers_hash_bucket_size 64;
上下文: http, server, location, if
This directive sets the bucket size of the hashtable.
这取决于你header名称的长度,如果你的header名称超过64个字符,请增加该参数
proxy_headers_hash_max_size
语法: proxy_headers_hash_max_size size;
默认值: proxy_headers_hash_max_size 512;
上下文: http, server, location, if
This directive sets the maximum size of the hashtable.
它不能比你后端服务器的header总数小.
proxy_hide_header
语法: proxy_hide_header the_header
上下文: http, server, location
nginx does not transfer the "Date", "Server", "X-Pad" and "X-Accel-..." header lines from the proxied server response.
The proxy_hide_header
directive allows to hide some additional header lines.
But if on the contrary the header lines must be passed, then the proxy_pass_header
should be used.
For example if you want to hide the MS-OfficeWebserver and the AspNet-Version:
location / { : proxy_hide_header X-AspNet-Version; : proxy_hide_header MicrosoftOfficeWebServer; }
This directive can also be very helpful when using X-Accel-Redirect. For example, you may have one set of backend servers which return the headers for a file download, which includes X-Accel-Redirect to the actual file, as well as the correct Content-Type. However, the Redirect URL points to a filleserver which hosts the actual file you wish to serve, and that server sends its own Content-Type header, which might be incorrect, and overrides the header sent by the original backend servers. You can avoid this by adding the proxy_hide_header directive to the fileserver. Example:
location / { : proxy_pass http://backend_servers; } location /files/ { : proxy_pass http://fileserver; : proxy_hide_header Content-Type; }
proxy_ignore_client_abort
语法: proxy_ignore_client_abort [ on|off ]
默认值: proxy_ignore_client_abort off
上下文: http, server, location
Available since: 0.3.36
如果客户端断开请求,也保持后端的下载
proxy_intercept_errors
语法: proxy_intercept_errors [ on|off ]
默认值: proxy_intercept_errors off
上下文: http, server, location
This directive decides if nginx will intercept responses with HTTP status codes of 400 and higher.
By default all responses will be sent as-is from the proxied server.
If you set this to on
then nginx will intercept status codes that are explicitly handled by an error_page
directive. Responses with status codes that do not match an error_page
directive will be sent as-is from the proxied server.
proxy_max_temp_file_size
语法: proxy_max_temp_file_size size;
默认值: proxy_max_temp_file_size 1G;
上下文: http, server, location, if
Available since: 0.1.8
TODO: Description.
proxy_method
语法: proxy_method [method]
默认值: None
上下文: http, server, location
Used to allow the proxying of additional HTTP methods.
Note: at this time, Nginx only appears to allow a single instance of this directive and it only accepts a single argument (method) so it's not clear how useful this might be for proxying to things like Subversion.
Example:
: proxy_method PROPFIND;
proxy_next_upstream
语法: proxy_next_upstream [error|timeout|invalid_header|http_500|http_503|http_404|off]
默认值: proxy_next_upstream error timeout
上下文: http, server, location
Directive determines, in what cases the request will be transmitted to the next server:
- error — an error has occurred while connecting to the server, sending a request to it, or reading its response;
- timeout — occurred timeout during the connection with the server, transfer the requst or while reading response from the server;
- invalid_header — server returned a empty or incorrect answer;
- http_500 — server returned answer with code 500
- http_503 — server returned answer with code 503
- http_404 — server returned answer with code 404
- off — it forbids the request transfer to the next server
Transferring the request to the next server is only possible when nothing has been transferred to the client -- that is, if an error or timeout arises in the middle of the transfer of the request, then it is not possible to retry the current request on a different server.
proxy_pass
语法: proxy_pass URL
默认值: no
上下文: location, if in location
This directive sets the port or socket, on which listens to the proxied server, and the URI, to which will be reflected location.
Port can be indicated in the form of the name of hostname or address and port, for example,
proxy_pass http://localhost:8000/uri /;
and socket -- in the form of unix of socket:
proxy_pass http://unix:/tmp/backend.socket:/uri /;
Path is indicated after the word unix
and is concluded between two colons.
With the transfer of request to server part URI, which corresponds to location, is substituted to URI, indicated in directive proxy_pass.
But there are two exceptions to this rule, when it is not possible to determine that replaced location:
- if the location is assigned by regular expression;
- if inside proxied location with the help of directive rewrite changes URI and with this configuration will be precisely processed request (break):
location /name/ { : rewrite /name/([^/] +) /users?name=$1 break; : proxy_pass http://127.0.0.1; }
For these cases of URI it is transferred without the mapping.
Furthermore, it is possible to indicate so that URI demand it would be transferred in the same form, as it sent client, but not v in the processed form.
During the working:
- two or by more slashes are converted into one slash: "//" -- "/";
- references to the current directory are removed: "/./" -- "/";
- references to the previous catalog are removed: "/dir /../" -- "/".
If on server it is necessary to transmit URI in the unprocessed form, then for this in directive proxy_pass it is necessary to indicate URL server without URI:
location /some/path/ { : proxy_pass http://127.0.0.1; }
proxy_pass_header
语法: proxy_pass_header the_name
上下文: http, server, location
This directive allows transferring header-lines forbidden for response.
For example:
location / { : proxy_pass_header Server; : proxy_pass_header X-MyHeader; }
proxy_pass_request_body
语法: proxy_pass_request_body [ on | off ] ;
默认值: proxy_pass_request_body on;
上下文: http, server, location
Available since: 0.1.29
TODO: Description.
proxy_pass_request_headers
语法: proxy_pass_request_headers [ on | off ] ;
默认值: proxy_pass_request_headers on;
上下文: http, server, location
Available since: 0.1.29
TODO: Description.
proxy_redirect
语法: proxy_redirect [ default|off|redirect replacement ]
默认值: proxy_redirect default
上下文: http, server, location
This directive sets the text, which must be changed in response-header "Location" and "Refresh" in the response of the proxied server.
Let us suppose the proxied server returned line Location: http://localhost:8000/two/some/uri/
.
The directive
proxy_redirect http://localhost:8000/two/ http://frontend/one/;
will rewrite this line in the form Location: http://frontend/one/some/uri/
.
In the replaceable line it is possible not to indicate the name of the server:
proxy_redirect http://localhost:8000/two/ /;
then the basic name of server and port is set, if it is different from 80.
The change by default, given by the parameter "default", uses the parameters of directives location and proxy_pass.
Therefore two following configurations are equivalent:
location /one/ { : proxy_pass http://upstream:port/two/; : proxy_redirect default; } location /one/ { : proxy_pass http://upstream:port/two/; : proxy_redirect http://upstream:port/two/ /one/; }
In the replace line, it is possible to use some variables:
proxy_redirect http://localhost:8000/ http://$host:$server_port/;
This directive repeated some times:
: proxy_redirect default; : proxy_redirect http://localhost:8000/ /; : proxy_redirect http://www.example.com/ /;
The parameter off
forbids all proxy_redirect
directives at this level:
: proxy_redirect off; : proxy_redirect default; : proxy_redirect http://localhost:8000/ /; : proxy_redirect http://www.example.com/ /;
With the help of this directive it is possible to add the name of host for relative redirect, issued by the proxied server:
proxy_redirect / /;
proxy_read_timeout
语法: proxy_read_timeout the_time
默认值: proxy_read_timeout 60
上下文: http, server, location
This directive sets the read timeout for the response of the proxied server. It determines how long NGINX will wait to get the response to a request. The timeout is established not for entire response, but only between two operations of reading.
In contrast to [#proxy_connect_timeout proxy_connect_timeout] , this timeout will catch a server that puts you in it's connection pool but does not respond to you with anything beyond that. Be careful though not to set this too low, as your proxyserver might take a longer time to respond to requests on purpose (e.g. when serving you a report page that takes some time to compute). You are able though to have a different setting per location, which enables you to have a higher proxy_read_timeout for the report page's location.
If the proxied server nothing will communicate after this time, then nginx is shut connection.
proxy_redirect_errors
Deprecated. Use proxy_intercept_errors
.
proxy_send_lowat
语法: proxy_send_lowat [ on | off ]
默认值: proxy_send_lowat off;
上下文: http, server, location, if
This directive set SO_SNDLOWAT.
This directive is only available on FreeBSD
proxy_send_timeout
语法: proxy_send_timeout time_in_seconds
默认值: proxy_send_timeout 60
上下文: http, server, location
This directive assigns timeout with the transfer of request to the proxy server. Time out is established not on entire transfer of request, but only between two operations of record. If after this time the proxy server will not take new data, then nginx is shut the connection
proxy_send_lowat
语法: proxy_set_body [ on | off ]
默认值: proxy_set_body off;
上下文: http, server, location, if
Available since: 0.3.10
TODO: Description.
proxy_set_header
语法: proxy_set_header header value
默认值: Host and Connection
上下文: http, server, location
This directive allows to redefine and to add some request header lines which will be transferred to the proxied server.
As the value it is possible to use a text, variables and their combination.
This directive is inherited from the previous level when at this level
are not described their directives proxy_set_header
.
By default only two lines will be redefined:
proxy_set_header Host $proxy_host; proxy_set_header Connection Close;
The unchanged request-header "Host" can be transmitted like this:
proxy_set_header Host $http_host;
However, if this line is absent from the client request, then nothing will be transferred.
In this case it is better to use variable $host, it's value is equal to the name of server in the request-header "Host" or to the basic name of server, if there is no line:
proxy_set_header Host $host;
Furthermore, it is possible to transmit the name of server together with the port of the proxied server:
proxy_set_header Host $host:$proxy_port;
proxy_store
语法: proxy_store [on | off | path]
默认值: proxy_store off
上下文: http, server, location
This directive sets the path in which upstream files are stored. The parameter "on" preserves files in accordance with path specified in directives alias or root. The parameter "off" forbids storing. Furthermore, the name of the path can be clearly assigned with the aid of the line with the variables:
proxy_store /data/www$original_uri;
The time of modification for the file will be set to the date of "Last-Modified" header in the response. To be able to safe files in this directory it is necessary that the path is under the directory with temporary files, given by directive proxy_temp_path for the data location.
This directive can be used for creating the local copies for dynamic output of the backend which is not very often changed, for example:
location /images/ { : root /data/www; : error_page 404 = /fetch$uri; } location /fetch { : internal; : proxy_pass http://backend; : proxy_store on; : proxy_store_access user:rw group:rw all:r; : proxy_temp_path /data/temp; : alias /data/www; }
To be clear proxy_store is not a cache, it's rather mirror on demand.
proxy_store_access
语法: proxy_store_access users:permissions [users:permission ...]
默认值: proxy_store_access user:rw
上下文: http, server, location
This directive assigns the permissions for the created files and directories, for example:
proxy_store_access user:rw group:rw all:r;
If any rights for groups or all are assigned, then it is not necessary to assign rights for user:
proxy_store_access group:rw all:r;
proxy_temp_file_write_size
语法: proxy_temp_file_write_size size;
默认值: proxy_temp_file_write_size proxy_buffer_size * 2;
上下文: http, server, location, if
TODO: Description.
proxy_temp_path
语法: proxy_temp_path dir-path [ level1 [ level2 [ level3 ] ;
默认值: $NGX_PREFIX/proxy_temp controlled by --http-proxy-temp-path at ./configure stage
上下文: http, server, location
This directive works like client_body_temp_path to specify a location to buffer large proxied requests to the filesystem.
proxy_upstream_fail_timeout
Changed in 0.5.0 to deprecated.
Please use the fail_timeout parameter of server Directive from the upstream module.
proxy_upstream_max_fails
Changed in 0.5.0 to deprecated.
Please use the max_fails parameter of server Directive from the upstream module.
Variables
In module ngx_http_proxy_module there are some built-in variables, which can be used for the creation of headers with the help of the proxy_set_header
directive:
Template:Anchor $proxy_host:: the name of proxied host and port;
Template:Anchor $proxy_port:: the port of proxied host;
Template:Anchor $proxy_add_x_forwarded_for:: equivalent to client request-header "X-Forwarded-For" and to variable added to it through the comma
Template:Anchor
$remote_addr:: But if there is no line "X-Forwarded-For" in the client request, then variable $proxy_add_x_forwarded_for
is equal to variable $remote_addr
.
References
Questions
- Is it possible to have the proxy use a client SSL certificate to communicate with the server being proxied? I am in the situation where I want to secure the proxy <-> application server connection. Another solution could be to use SSL only with a custom header checked at each connection in the application server, but doing it at the protocol level would be nicer.
- NginxHttpProxyModule#preview 原文