NGINX Docs | NGINX Reverse Proxy https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/
NGINX Reverse Proxy
This article describes the basic configuration of a proxy server. You will learn how to pass a request from NGINX to proxied servers over different protocols, modify client request headers that are sent to the proxied server, and configure buffering of responses coming from the proxied servers.
Table of Contents
- Introduction
- Passing a Request to a Proxied Server
- Passing Request Headers
- Configuring Buffers
- Choosing an Outgoing IP Address
Introduction
Proxying is typically used to distribute the load among several servers, seamlessly show content from different websites, or pass requests for processing to application servers over protocols other than HTTP.
Passing a Request to a Proxied Server
When NGINX proxies a request, it sends the request to a specified proxied server, fetches the response, and sends it back to the client. It is possible to proxy requests to an HTTP server (another NGINX server or any other server) or a non-HTTP server (which can run an application developed with a specific framework, such as PHP or Python) using a specified protocol. Supported protocols include FastCGI, uwsgi, SCGI, and memcached.
To pass a request to an HTTP proxied server, the proxy_pass
directive is specified inside a location
. For example:
location /some/path/ { proxy_pass http://www.example.com/link/; }
This example configuration results in passing all requests processed in this location to the proxied server at the specified address. This address can be specified as a domain name or an IP address. The address may also include a port:
location ~ \.php { proxy_pass http://127.0.0.1:8000; }
Note that in the first example above, the address of the proxied server is followed by a URI, /link/
. If the URI is specified along with the address, it replaces the part of the request URI that matches the location parameter. For example, here the request with the /some/path/page.html
URI will be proxied to http://www.example.com/link/page.html
. If the address is specified without a URI, or it is not possible to determine the part of URI to be replaced, the full request URI is passed (possibly, modified).
To pass a request to a non-HTTP proxied server, the appropriate **_pass
directive should be used:
fastcgi_pass
passes a request to a FastCGI serveruwsgi_pass
passes a request to a uwsgi serverscgi_pass
passes a request to an SCGI servermemcached_pass
passes a request to a memcached server
Note that in these cases, the rules for specifying addresses may be different. You may also need to pass additional parameters to the server (see the reference documentation for more detail).
The proxy_pass
directive can also point to a named group of servers. In this case, requests are distributed among the servers in the group according to the specified method.
Passing Request Headers
By default, NGINX redefines two header fields in proxied requests, “Host” and “Connection”, and eliminates the header fields whose values are empty strings. “Host” is set to the $proxy_host
variable, and “Connection” is set to close
.
To change these setting, as well as modify other header fields, use the proxy_set_header
directive. This directive can be specified in a location
or higher. It can also be specified in a particular server
context or in the http
block. For example:
location /some/path/ { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://localhost:8000; }
In this configuration the “Host” field is set to the $host variable.
To prevent a header field from being passed to the proxied server, set it to an empty string as follows:
location /some/path/ { proxy_set_header Accept-Encoding ""; proxy_pass http://localhost:8000; }
Configuring Buffers
By default NGINX buffers responses from proxied servers. A response is stored in the internal buffers and is not sent to the client until the whole response is received. Buffering helps to optimize performance with slow clients, which can waste proxied server time if the response is passed from NGINX to the client synchronously. However, when buffering is enabled NGINX allows the proxied server to process responses quickly, while NGINX stores the responses for as much time as the clients need to download them.
The directive that is responsible for enabling and disabling buffering is proxy_buffering
. By default it is set to on
and buffering is enabled.
The proxy_buffers
directive controls the size and the number of buffers allocated for a request. The first part of the response from a proxied server is stored in a separate buffer, the size of which is set with the proxy_buffer_size
directive. This part usually contains a comparatively small response header and can be made smaller than the buffers for the rest of the response.
In the following example, the default number of buffers is increased and the size of the buffer for the first portion of the response is made smaller than the default.
location /some/path/ { proxy_buffers 16 4k; proxy_buffer_size 2k; proxy_pass http://localhost:8000; }
If buffering is disabled, the response is sent to the client synchronously while it is receiving it from the proxied server. This behavior may be desirable for fast interactive clients that need to start receiving the response as soon as possible.
To disable buffering in a specific location, place the proxy_buffering
directive in the location
with the off
parameter, as follows:
location /some/path/ { proxy_buffering off; proxy_pass http://localhost:8000; }
In this case NGINX uses only the buffer configured by proxy_buffer_size
to store the current part of a response.
A common use of a reverse proxy is to provide load balancing. Learn how to improve power, performance, and focus on your apps with rapid deployment in the free Five Reasons to Choose a Software Load Balancer ebook.
Choosing an Outgoing IP Address
If your proxy server has several network interfaces, sometimes you might need to choose a particular source IP address for connecting to a proxied server or an upstream. This may be useful if a proxied server behind NGINX is configured to accept connections from particular IP networks or IP address ranges.
Specify the proxy_bind
directive and the IP address of the necessary network interface:
location /app1/ { proxy_bind 127.0.0.1; proxy_pass http://example.com/app1/; } location /app2/ { proxy_bind 127.0.0.2; proxy_pass http://example.com/app2/; }
The IP address can be also specified with a variable. For example, the $server_addr
variable passes the IP address of the network interface that accepted the request:
location /app3/ { proxy_bind $server_addr; proxy_pass http://example.com/app3/; }
nginx反向代理(請求轉發-URL匹配規則) - 周XX - 博客園 https://www.cnblogs.com/zhouXX/p/7215316.html
反向代理適用於很多場合,負載均衡是最普遍的用法。
nginx 作為目前最流行的web服務器之一,可以很方便地實現反向代理。
nginx 反向代理官方文檔: NGINX REVERSE PROXY
當在一台主機上部署了多個不同的web服務器,並且需要能在80端口同時訪問這些web服務器時,可以使用 nginx 的反向代理功能: 用 nginx在80端口監聽所有請求,並依據轉發規則(比較常見的是以 URI 來轉發)轉發到對應的web服務器上。
例如有 webmail , webcom 以及 webdefault 三個服務器分別運行在 portmail , portcom , portdefault 端口,要實現從80端口同時訪問這三個web服務器,則可以在80端口運行 nginx, 然后將 /mail
下的請求轉發到 webmail 服務器, 將 /com
下的請求轉發到 webcom 服務器, 將其他所有請求轉發到 webdefault 服務器。
假設服務器域名為example.com,則對應的 nginx http配置如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
http {
server {
server_name example.com;
location /mail/ {
proxy_pass http:
//example.com:protmail/;
}
location /com/ {
proxy_pass http:
//example.com:portcom/main/;
}
location / {
proxy_pass http:
//example.com:portdefault;
}
}
}
|
- 以上的配置會按以下規則轉發請求(
GET
和POST
請求都會轉發):
- 將
http://example.com/mail/
下的請求轉發到http://example.com:portmail/
- 將
http://example.com/com/
下的請求轉發到http://example.com:portcom/main/
- 將其它所有請求轉發到
http://example.com:portdefault/
需要注意的是,在以上的配置中,webdefault 的代理服務器設置是沒有指定URI的,而 webmail 和 webcom 的代理服務器設置是指定了URI的(分別為 /
和 /main/
)。
如果代理服務器地址中是帶有URI的,此URI會替換掉 location
所匹配的URI部分。
而如果代理服務器地址中是不帶有URI的,則會用完整的請求URL來轉發到代理服務器。
官方文檔描述:
If the URI is specified along with the address, it replaces the part of the request URI that matches the location parameter.
If the address is specified without a URI, or it is not possible to determine the part of URI to be replaced, the full request URI is passed (possibly, modified).
以上配置的轉發示例:
http://example.com/mail/index.html
->http://example.com:portmail/index.html
http://example.com/com/index.html
->http://example.com:portcom/main/index.html
http://example.com/mail/static/a.jpg
->http://example.com:portmail/static/a.jpg
http://example.com/com/static/b.css
->http://example.com:portcom/main/static/b.css
http://example.com/other/index.htm
->http://example.com:portdefault/other/index.htm
轉自:http://blog.csdn.net/tobacco5648/article/details/51099426
Nginx應用-Location路由反向代理及重寫策略 – 嗨!大佟! http://www.qmailer.net/archives/249.html
本文由 大佟 發表於 2014年11月25日 , 瀏覽: 11,611次 , 評論: 0條
一、Nginx的反向代理的路由策略
Nginx是著名的高性能Web服務器,應用在很多Web服務領域,同時開發和部署過程中,為了更好的控制接口API(或是WebService),我們需要嚴格的或是謹慎的規划URL的使用,這樣才能為以后的擴張、迭代打下良好的基礎,否則雜亂無章的URL使用,將是以后大規模擴展的噩夢。
Location的配置
語法規則:
1
|
location [=|~|~*|^~] /uri/ {…}
|
語法說明:
1
2
3
4
5
|
= 開頭表示精確匹配,不支持正則。
^~ 開頭表示uri以某個常規字符串開頭,不支持正則,理解為匹配url路徑即可。nginx不對url做編碼,因此請求為/static/20%/aaa,可以被規則^~ /static/ /aaa匹配到(注意是空格)。
~和~* 開頭表示區分大小寫的和不區分大小寫的正則匹配。
!~和!~* 開頭表示區分大小寫不匹配及不區分大小寫不匹配的正則匹配。
/ 通用匹配,任何請求都會匹配,通常放着配置的最后。
|
匹配優先級:
1
2
3
4
5
6
7
|
(1). 優先嘗試 全匹配( 也就是前綴 =)
(2). 嘗試 路徑匹配 ( 也就是前綴 ^~)
(3). 嘗試 正則匹配 ( 也就是前綴 ~* 或者 ~)
(4). 字符串匹配 (也就是前綴為空)
所以,前綴的優先級概括為:
= > ^~ > ~, ~* > 空
全匹配 > 路徑匹配 > 正則匹配 > 字符串匹配
|
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# 字符串匹配
location /static {
alias /home/www/static;
access_log off;
}
# 路徑匹配,此時proxy_pass的結束 / 決定是否帶上匹配的路徑
location ^~ /333/ {
proxy_pass http://106.185.48.229/;
}
# 正則匹配,此時proxy_pass不能帶結束 /
location ~ ^/(xxx|yyy)/ {
proxy_pass http://106.185.48.229;
}
# 字符串匹配,此時proxy_pass的結束 / 決定是否帶上匹配得路徑
location /zzz/ {
proxy_pass http://106.185.48.229/;
}
# 默認匹配
location / {
proxy_pass http://127.0.0.1:8080;
}
|
二、Nginx的Rewrite規則
語法規則:
1
|
rewrite 正則 替換 標志位
|
rewrite指令的最后一項參數為flag標記,flag標記有:
1
2
3
4
|
1.last last是終止當前location的rewrite檢測,但會繼續重試location匹配並處理區塊中的rewrite規則。
2.break break是終止當前location的rewrite檢測,而且不再進行location匹配。
3.redirect 返回302臨時重定向,瀏覽器地址會顯示跳轉后的URL地址。
4.permanent 返回301永久重定向,瀏覽器地址會顯示跳轉后的URL地址。
|
示例:
1
2
3
4
5
|
# 正則匹配
location ~ ^/(a|bb|ccc)/ {
rewrite ^/([a-z]+)/(.*)$ http://106.185.48.229/$2?$1;
}
# 注:用括號括起來的參數為后面的 $1 $2 變量
|
三、Nginx常用設置
1.為了便於日志統計和分析,備注一個日志示例格式,供參考
1
2
3
4
5
|
log_format main '$time_iso8601|$remote_addr|$remote_user|$request_method|$uri|'
'$status|$request_time|$request_length|$body_bytes_sent|$bytes_sent|'
'$connection|$http_x_forwarded_for|$upstream_addr|$upstream_status|'
'$upstream_response_time|$args|$http_referer|$http_user_agent';
access_log logs/access.log main;
|
2. 反向代理透傳客戶端IP設置
1
2
3
|
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
3.常用的Nginx全局變量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
$args #這個變量等於請求行中的參數。
$content_length #請求頭中的Content-length字段。
$content_type #請求頭中的Content-Type字段。
$document_root #當前請求在root指令中指定的值。
$host #請求主機頭字段,否則為服務器名稱。
$http_user_agent #客戶端agent信息
$http_cookie #客戶端cookie信息
$limit_rate #這個變量可以限制連接速率。
$request_body_file #客戶端請求主體信息的臨時文件名。
$request_method #客戶端請求的動作,通常為GET或POST。
$remote_addr #客戶端的IP地址。
$remote_port #客戶端的端口。
$remote_user #已經經過Auth Basic Module驗證的用戶名。
$request_filename #當前請求的文件路徑,由root或alias指令與URI請求生成。
$query_string #與$args相同。
$scheme #HTTP方法(如http,https)。
$server_protocol #請求使用的協議,通常是HTTP/1.0或HTTP/1.1。
$server_addr #服務器地址,在完成一次系統調用后可以確定這個值。
$server_name #服務器名稱。
$server_port #請求到達服務器的端口號。
$request_uri #包含請求參數的原始URI,不包含主機名,如:”/foo/bar.php?arg=baz”。
$uri #不帶請求參數的當前URI,$uri不包含主機名,如”/foo/bar.html”。
$document_uri #與$uri相同。
|
server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location /api/ { proxy_pass http://apiServerHost:8002/api/; } location / { } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }
瀏覽器端訪問網站A的所有的請求均被指向網頁服務器webServer
Request URL: http://webServer/9.js
Request URL: http://webServer/static/fonts/element-icons.2fad952a.woff
Request URL: http://webServer/api/cloud-resource-ecs/describe-instances/
網頁服務器webServer端
/api/cloud-resource-ecs/describe-instances/
/api/cloud-resource-shell/describe-commands/
通過Nginx將瀏覽器/api/請求做url透明轉發,不修改url
Using the URLconf defined in config.urls, Django tried these URL patterns, in this order:
注意
訪問http://webServer/api/,
Using the URLconf defined in config.urls, Django tried these URL patterns, in this order:
^api/ ^^user/modify-user-list/$ [name='user-modify-user-list']
^api/ ^^user/register/$ [name='user-register']
^api/ ^^cloud-resource-ecs/allocate-public-ip-address/$ [name='ecs-allocate-public-ip-address']
^api/ ^^cloud-resource-ecs/create-instance/$ [name='ecs-create-instance']
即瀏覽器端會暴露api接口服務端的調試信息。
nginx反向代理中數據是透明的。
server { listen 9000 default_server; root /usr/share/nginx/mobile; location /api/ { # proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://127.0.0.1:8002/api/; } location /testngx/ { # proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://127.0.0.1:9000/; } }
:9000/testngx/#/about
same
:9000/#/about
api standard
server { listen 9000 default_server; root /usr/share/nginx/mobile; location /api/ { # proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://127.0.0.1:8002/api/; } location /testngx/ { # proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://127.0.0.1:9000/; } location /testapi/ { # proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_pass http://apiServer/; } }