代理服务
nginx代理服务
正向代理
正向代理:代理的对象是客户端
反向代理
反向代理: 反向代理的代理对象是服务器
。
配置语法
proxy_pass
Syntax: proxy_pass URL;
Default: ---;
Context: location, if in location, limit_expect;
例
:
server {
listen 80;
location ~ /test_proxy.html${
proxy_pass http://127.0.0.1:8080;
}
}
会将
ip:80/test_proxy.html
请求,转发至本机8080
端口上。
缓冲区
proxy_buffering
: ngigx转发请求时, 尽可能的收集一个请求的完整信息,再转发给实际的服务器。proxy_buffering _size
:proxy_buffers
:proxy_busy_buffers _size
:
跳转重定向(proxy_redirect )
当nginx代理的请求,服务端返回301
的地址,需要nginx进行修改时使用。
Syntax: proxy_redirect default | off | redirect replacement;
Default: proxy_redirect default;
Context: http,server,location
当服务端响应
301 Moved Permanently
重定向状态响应代码指示所请求的资源已明确移动到Location
标题给定的URL
头信息修改(proxy_set_header)
Syntax: proxy_set_header field value;
Default: proxy_set_header Host $proxy_host;
proxy_set_header Connection close;
Context: http,server,location
扩展:
proxy_hide_header
: 隐藏头。proxy_set_body
: 敏感词屏蔽等。
超时
nginx代理到后端服务器之间的超时。
建立连接超时(proxy_connection_timeout )`
Syntax: proxy_connection_timeout time;
Default: proxy_connection_timeout 60s;
Context: http,server,location
proxy_read_timeout
: 建立完请求后,真实服务读取+处理请求超时:proxy_send_timeout
: 真实服务处理完请求,响应给nginx服务的超时。
综合实例
location / {
proxy_pass http://127.0.0.1:8080;
proxy_redirect default;
proxy_set_header Host $http_host;
# 记录访问真实ip X-Real-IP
proxy_set_header X-Real-IP $remote_addr;
proxy_connection_timeout 30;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffer_size 32k;
proxy_buffering on;
proxy_buffers 4 128k;
proxy_busy_buffers_size 256k;
proxy_max_temp_file_size 256k;
}
通常会把通用的配置信息,存放在一个单独的配置文件中,然后在主配置文件中include
即可。
location / {
proxy_pass http://127.0.0.1:8080;
## 配置文件 单独存放在哎 proxy_params配置文件中。
include proxy_params
}
反向代理表达式
=
严格匹配。如果这个查询匹配,那么将停止搜索并立即处理此请求。~
为区分大小写匹配(可用正则表达式)!~
为区分大小写不匹配~*
为不区分大小写匹配(可用正则表达式)!~*
为不区分大小写不匹配^~
如果把这个前缀用于一个常规字符串,那么告诉nginx 如果路径匹配那么不测试正则表达式。
location = / {
# 只匹配 / 查询。
}
location / {
}
location ^~ /images/ {
# 匹配任何已 /images/ 开头的任何查询并且停止搜索。任何正则表达式将不会被测试。
}
location~*.(gif|jpg|jpeg)$ {
# 匹配任何已 gif、jpg 或 jpeg 结尾的请求。
}
proxy_pass斜杠问题
Nginx的官网将proxy_pass分为两种类型:
- 一种是只包含IP和端口号的(连端口之后的/也没有,这里要特别注意),比如
proxy_pass http://localhost:8080
,这种方式称为不带URI方式; - 另一种是在端口号之后有其他路径,称之为带URI方式(
下面两种处理方式相同
)- 包含了只有单个
/
的如proxy_pass http://localhost:8080/
- 包含了其他路径,比如
proxy_pass http://localhost:8080/abc
- 包含了只有单个
nginx对于上述两种不同的方式有两种不同的处理方式:
- 对于不带URI方式,nginx将会
保留location中路径
部分,比如:
# http://localhost/api1/xxx -> http://localhost:8080/api1/xxx
location /api1/ {
proxy_pass http://localhost:8080;
}
- 对于带URI方式,nginx将使用诸如alias的替换方式对
URL进行替换
# 当访问http://localhost/api2/xxx时,
# http://localhost/api2/(注意最后的/)被替换成了http://localhost:8080/,
# 然后再加上剩下的xxx,于是变成了http://localhost:8080/xxx。
location /api2/ {
proxy_pass http://localhost:8080/;
}
# 当访问http://localhost/api5/xxx时,
# http://localhost/api5/被替换成了 http://localhost:8080/haha,
# 请注意这里haha后面没有/,然后再加上剩下的xxx,即 http://localhost:8080/hahaxxx
location /api5/ {
proxy_pass http://localhost:8080/haha;
}
location 斜杠问题
location末尾带有/
和无/
的区别,仅是路径的问题。
# 可以拦截 http://localhost/api6/xxx
# 也可拦截 http://localhost/api6xxx
location /api6 {
proxy_pass http://localhost:8080/haha;
}
# 仅拦截 http://localhost/api7/xxx
location /api7/ {
proxy_pass http://localhost:8080/haha;
}
综合示例
server {
listen 80;
server_name www.test.com;
# 情形A
# 访问 http://www.test.com/testa/aaaa
# 后端的request_uri为: /testa/aaaa
location ^~ /testa/ {
proxy_pass http://127.0.0.1:8801;
}
# 情形B
# 访问 http://www.test.com/testb/bbbb
# 后端的request_uri为: /bbbb
location ^~ /testb/ {
proxy_pass http://127.0.0.1:8801/;
}
# 情形C
# 下面这段location是正确的
location ~ /testc {
proxy_pass http://127.0.0.1:8801;
}
# 情形D
# 下面这段location是错误的
#
# nginx -t 时,会报如下错误:
#
# nginx: [emerg] "proxy_pass" cannot have URI part in location given by regular
# expression, or inside named location, or inside "if" statement, or inside
# "limit_except" block in /opt/app/nginx/conf/vhost/test.conf:17
#
# 当location为正则表达式时,proxy_pass 不能包含URI部分。本例中包含了"/"
location ~ /testd {
proxy_pass http://127.0.0.1:8801/; # 记住,location为正则表达式时,不能这样写!!!
}
# 情形E
# 访问 http://www.test.com/ccc/bbbb
# 后端的request_uri为: /aaa/ccc/bbbb
location /ccc/ {
proxy_pass http://127.0.0.1:8801/aaa$request_uri;
}
# 情形F
# 访问 http://www.test.com/namea/ddd
# 后端的request_uri为: /yongfu?namea=ddd
location /namea/ {
rewrite /namea/([^/]+) /yongfu?namea=$1 break;
proxy_pass http://127.0.0.1:8801;
}
# 情形G
# 访问 http://www.test.com/nameb/eee
# 后端的request_uri为: /yongfu?nameb=eee
location /nameb/ {
rewrite /nameb/([^/]+) /yongfu?nameb=$1 break;
proxy_pass http://127.0.0.1:8801/;
}
access_log /data/logs/www/www.test.com.log;
}