Nginx系列之反向代理过程

nginx通过proxy模块对上游服务使用http/https协议进行反向代理,下图是反向代理处理过程

Nginx系列之反向代理过程_第1张图片

在读取客户端发送的请求时,如果proxy_request_bufferring=on,那么读取完整的包体后再发送给后端服务,如果 proxy_request_bufferring=off,则是边读取包体,边发送。在服务端返回请求响应的包体时,通过proxy_bufferring=on/off来控制接收完整响应包体或是边发送边读取。下面的内容将围绕反向代理的过程来展开,介绍处理过程中涉及的指令、配置项等。

proxy_pass配置规则

在使用proxy模块时有个地方容器犯错,即proxy_pass后面的url是否带URI,对发送的的URI的影响
1.url必须以http://或者https://开头,然后是域名或者IP地址或者upstream名字,域名和IP地址后可加端口,最后是可选的URI
2.1当URL参数中携带了URI,nginx会修改URL,将location参数中匹配上的一段值替换成proxy_pass中配置的URI
2.2当URL参数中不携带URI,nginx将客户端转发的URI直接转发给上游。实验结果如下图所示,proxy_pass中无“/addurl”时,原样转发客户端发送的URI,当proxy_pass中有"/addurl"时,用curl命令"curl taoli.test.pub:8040/a/b/c"时,/a被替换成了/addurl

Nginx系列之反向代理过程_第2张图片

反向代理处理过程中涉及的配置项说明

proxy模块提供了很多配置项来控制读取客户端发送的请求的行为,具体的配置项与作用如下所示
proxy_method: 指定发往后端服务的方法(GET/POST等)
proxy_http_version:设置http的版本,默认是1.0,有些特性在1.1才支持。
proxy_set_header field value:添加发往后端服务的header,如果value为空字符串,则整个header都不会发往后端服务
proxy_set_body value:设置发往后端服务的请求body(如果要发送body还需把proxy_pass_request_body设置为on)
proxy_request_buffering on | off: 控制接收完整个请求body后再发送,或边接收边转发。通常情况下建议设置为on,因为nginx作为反向代理服务器,吞吐量高于后端服务处理速率和客户端发送速率,如果边接收边转发,可能存在Nginx等待的情况,所以,如果是高吞吐量的场景,设置为on。设置为on后,如果内容很小会直接写在内存中进行转发,如果内容很大,会写入磁盘,这里就存在时间消耗,如果对响应要求非常及时的场景,可以设置为off。
client_body_buffer_size size: 若接收头部时已经完全接收了完整包体,则不分配,若剩余待接收包体长度小于client_body_buffer_size,则仅分配所需大小,如果剩余待接收包体大于client_body_buffer_size,关闭包体缓存时,该内存上的内容会及时发送给上游,打开包体缓存时,该段大小内存用完时,写入临时文件,释放内存。
client_max_body_size size: 控制最大包体大小,该配置如果要生效,请求头部中需要包含Content-Length,如果超出最大限制,返回413错误。
client_body_temp_path path: 设置临时存放文件路径
client_body_timeout: 设置读取包体的超时时间,超时后返回408错误

下图是proxy的一些配置,使用proxy_set_body设置转发请求的body值,当用curl命令访问nginx时,可以使用tcpdump命令查看发送的body内容,可以看到和设置的内容(hello world)一致。

Nginx系列之反向代理过程_第3张图片

上面是读取客户端请求时的一些配置,nginx与后端服务交互,建立连接,获取后端服务返回的响应内容时,也有一些配置项来控制处理返回响应的行为,配置项及作用说明如下所示

proxy_connect_timeout time: 默认值60s,向上游服务建立连接的超时时间,超时后返回502错误
proxy_socket_keepalive on|off: 上游连接启用TCP keepalive,TCP的keepalive是为了把不可用的TCP连接提前关闭,释放系统资源
keepalive connections: 上游连接启动HTTP keepalive,HTTP的keepalive是为了多个HTTP请求复用TCP连接,减少握手、慢启动带来的性能消耗。开启keepalive的好处是性能更高,坏处是问题定位更困难些
keepalive_requests numbers: 设置最多可并发处理的请求数
proxy_send_timeout time: 向后端服务发送http请求的超时时间设置,默认是60s
proxy_buffer_size size: 接收后端服务HTTP响应头部的内存大小,如果超出内存,在error.log中会记录upstream sent too big header
proxy_buffers number size: 接收后端服务返回的HTTP包体所需的内存大小
proxy_buffering on | off: 接收后端服务返回的包体时,设置为on,接收完整个包体后再转发给客户端,设置为off,边接收边转发。默认设置为on
proxy_temp_path path: 接收返回的响应包体时,如果超出内存则需要存储在磁盘上,这里设置存放内容的路径
proxy_max_temp_file_size size: 磁盘中临时存放的文件的最大值
proxy_store_access users:permissions: 对持久化的读写权限设置
proxy_store on|off:是否把后端服务返回的响应包体写入磁盘,进行持久化存储

除了设置某个字段以及值,Nginx还提供禁止某些字段生效的功能。语法格式 proxy_ignore_header filed.例如下面的头部字段是nginx提供给后端服务来控制的。也可以通过proxy_ignore_headers来禁止这些字段生效
X-Accel-Redirect: 由后端服务(upstream服务)指定在nginx内部重定向,控制请求的执行
X-Accel-Limit-Rate: 由后端服务设置发送客户端的响应的速度限制,和limit_rate作用相同,区别是limit_rate是在nginx中配置,该字段是nginx留给后端服务来控制的
X-Accel-Buffering: 由后端服务控制是否缓存后端服务返回的响应
X-Accel-Charset: 由后端服务控制Content-Type中的Charset
除了上面的字段,还有一些与缓存相关的字段,也可以通过proxy_ingore_header field来禁止这些字段生效。
X-Accel-Expires: 设置响应在nginx中缓存时间,单位秒
Expires: 控制nginx缓存时间,优先级低于X-Accel-Expires
Cache-Control: 响应中出现Set-Cookie则不缓存
Vary: 响应中出现Vary:*则不缓存
上面是禁止返回的响应header中某些字段生效,除此之外,nginx还提供了proxy_hide_header field指令来控制某些头部的字段不返回给客户端,也提供了proxy_pass_header来控制头部字段会被转发,即便是已经配置在proxy_hide_header的字段,配置了proxy_pass_header后,也会转发这个头部字段。还有一些头部字段,Nginx默认是不转发的,如果要转发也需要通过proxy_pass_header进行设置,例如下面的头部字段:
Date: 由ngx_http_header_filter_module过滤模块填写,值为nginx发送响应头部的时间
Server:由ngx_http_header_filter_module过滤模块填写,值为nginx版本
X-Accel-: 用户控制nginx响应行为的字段,默认不会发给客户端

下面是一个演示demo,在后端服务上设置新的header字段和值(authHeader:headerValue),当访问nginx后,返回了后端服务新增的头部字段,另外,通过proxy_pass_header field设置,返回的请求中也显示了Server这个默认不返回的头部字段。

Nginx系列之反向代理过程_第4张图片Nginx系列之反向代理过程_第5张图片

后端服务出现异常后的容错处理方案

通过proxy_next_upstream模块,可以对后端服务返回的错误进行容错处理,语法格式:proxy_next_upstream  error|timeout|invalid_header|http_500 |http_xx|off;不同参数的含义如下

error                   表示和后端服务器建立连接时,或者向后端服务器发送请求时,或者从后端服务器接收响应头时,出现错误
timeout                 表示和后端服务器建立连接时,或者向后端服务器发送请求时,或者从后端服务器接收响应头时,出现超时
invalid_header          表示后端服务器返回空响应或者非法响应头
http_500                表示后端服务器返回的响应状态码为500
http_502                表示后端服务器返回的响应状态码为502
http_503                表示后端服务器返回的响应状态码为503
http_504                表示后端服务器返回的响应状态码为504
http_404                表示后端服务器返回的响应状态码为404
off                     表示停止将请求发送给下一台后端服务器
proxy_intercept_errors on|off 当后端服务响应码大于等于300时,设置为on,按error_page处理,设置为off,将响应返回给客户端

下面是proxy_next_upstream的配置。

 访问/error这个url,此关闭8013端口的监听,即模拟的8013端口的服务无法连接上,左边是proxy_next_upstream=off的实验结果,当轮询访问到8013端口的服务时,返回了502错误,右边是proxy_next_upstream=on的实验结果,服务把请求都转发到了8011端口这个正常服务上,不会返回502的异常信息。

Nginx系列之反向代理过程_第6张图片Nginx系列之反向代理过程_第7张图片

下面的左边是访问/httperror的结果,刷新配置后,首次访问会返回502,后面都会把请求转发到正常的服务上,即8011端口的服务上。右边是访问/intercept的结果,当8013端口的服务处于完全无法连接的情况时,访问返回502的错误码,但是当8013端口的服务能连接,但是服务返回300以上的状态码时,按error_page进行处理,这里error_page是显示nginx/html/test.txt文件内容。

 Nginx系列之反向代理过程_第8张图片Nginx系列之反向代理过程_第9张图片

以上就是Nginx作为反向代理处理请求过程中涉及的常用配置介绍。

你可能感兴趣的:(微服务,nginx)