代理服务

nginx代理服务

nginx proxy 支持 post nginx的proxy_nginx proxy 支持 post

正向代理

正向代理:代理的对象是客户端

nginx proxy 支持 post nginx的proxy_正则表达式_02

反向代理

反向代理: 反向代理的代理对象是服务器

nginx proxy 支持 post nginx的proxy_配置文件_03

配置语法

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

https://www.jianshu.com/p/c751250a5112

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