nginx的反向代理

反向代理是nginx的主要功能之一,平时我们在使用Nginx的时候一般就是用其性能高效的反向代理功能。
为了线上环境中的降级和服务替换,nginx的upstream模块提供了通用的参数。
通用的参数有(不论是round-robin,还是hash)

  • backup:指定当前server为备份服务,当且仅当所有的非备份服务器不可用的时候,请求才会转发到该server。
  • down:标识某台服务已经下线,不在服务。

round-robin算法

round-robin 轮询是nginx反向代理的默认使用的算法。
指定上游服务地址的upstream模块。
指令。

upstream backend1{
    server 192.168.0.2:80 weight=1 max_fails=3 fail_timeout=30s;
}
  • weight: 服务器的访问权重
  • max_conns: server的最大并发连接数字,仅作用于单worker进程。默认是0,表示没有限制。
  • max_fails: 在fail_timeout 时间段内,最大的失败次数,当达到最大的失败次数时,会在fail_timeout 秒内这台server 不会再次选中。
  • fail_timeout:单位为秒,默认是10s。具有两个功能(配合max_fails 使用)如上所述。
对上游服务使用keepalive长连接

通过复用tcp连接,降低nginx与上游服务器的建立、关闭连接的消耗,提高吞吐量的同时降低时延。
对上游连接设定的http头部(因为http1.0 不支持keepalive)

proxy_http_version 1.1;
proxy_set_header Connection "";
  • keepalive connections:向一组upstream最多保持多少个空闲的tcp连接用来keepalive请求。Nginx 和后端的长连接不够用时 Nginx 会新建连接来处理新的请求(是 Nginx 每个 worker 连接后端的最大长连接数,而不是整个 Nginx 的)
  • keepalive_requests number:1.15.3新增指令。一条keepalive上最多跑多少条请求。
  • keepalive_timeout:1.15.3新增指令。一条tcp连接,超过多长时间没有请求的话,关闭tcp。
  • resolver:当使用域名访问时,指定我们自己的dns服务器。
  • resolver_timeout:dns超时时间。

测试

如下是我nginx的配置。

upstream backend {
        keepalive 32;
        server 192.168.199.214:8081 weight=1 max_fails=2 fail_timeout=5s;
        server 192.168.199.214:8082 weight=1 max_fails=2 fail_timeout=5s;
}

server {
        listen 80;
        server_name app.prometheus.wjx;

        location / {
                proxy_http_version 1.1;
                proxy_set_header Connection "";
                proxy_pass http://backend;
        }

}

一台后端挂了后,nginx如何处理

当我将8081 的这台机器挂掉后。
从tcp层面会有RST,也就是http无法再用这条tcp连接。所以当然http请求是无法发送到8081这台机器,nginx会默认将请求发往下一台server 8082。tcp建立通了,才会有http请求过去,也就是说nginx是有高效的错误处理能力的。当配置的5s后(不一定就5s),nginx会再试8081 端的server,5s后再有请求,会重新尝试与8081建立tcp连接。


抓包得出
keepalive 对nginx和后端的影响
  1. 当keepalive配置只有1,压力测试
ab -n 10 -c 2 http://localhost/
wireshark抓包

从上图可以看出,其实只有一个keepalive连接,其他的还是使用了短连接。

  1. 当keepalive为2048时,压力测试
    只建立了两个tcp连接,分别是两个后端server的。也就是每个server一条连接,传输了所有的数据。


    wireshark抓包
  2. 不开启keepalive。压力测试
    开启keepalive的时候,nginx的timewait达到了 14000+个。而server端的timewait几乎为0。(因为开启时,server会认为这是一个长连接,不会主动关闭,而不开启的话,server会在一次请求结束后主动关闭长连接)
    不开启keepalive的时候,nginx的timewait为1000+个,而server端为900+个。
    而看看抓包情况。。。满屏的tcp syn握手包。


    wireshark握手包

least_conn 算法

这个算法是由upstream_least_conn 模块提供的。功能是从所有的上游服务中找出并发连接数最少的一个,将请求转发到它。
一般很少用到,当所有的server的连接都相同的时候,该算法会退化成round_robin算法。

upstream模块提供的变量

变量 作用
upstream_addr 上游服务的ip地址+port
upstream_connect_time 与上游服务建立连接消耗的时间
upstream_header_time 接收上游服务发回响应的头部消耗的时间
upstream_response_time 接收上游服务响应消耗的时间
upstream_bytes_received 从上游服务接收到的响应长度
upstream_response_length 从上游服务返回的响应包体的长度
upstream_status 上游服务的返回的状态码未连接上是502

proxy 模块

proxy_pass 是反向代理中最重要的一个模块。
其大体流程如图所示。


proxy_pass.png

proxy_request_buffering 和 proxy_buffering 为 off 时才会边读包体边发送

根据指令生成发往上游的请求行
  • proxy_method method : 将请求方法
  • proxy_http_version 1.0|1.1 : 更改http的version(keepalive就需要1.1)
  • proxy_set_header :添加头部
  • proxy_pass_request_headers on|off :是否将用户请求的包头发给上游(默认当然是发的)。
  • proxy_pass_request_body on|off:是否将用户请求包体发给上游(默认当然是发的)。
  • proxy_set_body value:添加包体
接收客户端请求的包体
  • proxy_request_buffering on|off 上面已经说了off的话会边收包体边发。
    • on:1.客户端网速慢。2.上游服务并发处理能力低。3.适应高吞吐场景。
    • off:1.更及时的响应。2.降低nginx读写磁盘的消耗。 3.一旦开始发送 proxy_next_upstream 功能失败。
  • client_body_buffer_size size:接收请求的header时,为接收到包体分配内存。默认8k或16k。
    • 若接收头部时已经接收完全部包体,则不分配。
    • 若剩余待接收包体长度小于client_body_buffer_size, 则分配所需大小
  • client_max_body_size size :允许请求包体最大长度的限制,默认是1M
  • client_body_temp_path path:临时文件的路径(放请求body的)
  • client_body_in_file_only on | clean | off:默认是off 的。一般是请求body写到文件中,on的话是永久保存的,一般用于定位问题。
  • client_body_timeout time:读取包体时超时,则返回408错误。
nginx与上游服务建立连接
  • proxy_connect_timeout time :与上游服务建立tcp连接的超时时间。超时后会生成502。(默认60s)
  • proxy_socket_keepalive on|off:当设置为on时,会使用操作系统的tcp去操作tcp keepalive。
  • keepalive:有几个keepalive。
  • keepalive_requests:连接最多执行多少个http请求。
  • proxy_ignore_client_abort on|off:当client关闭连接,是否关闭与upstream关闭(默认是off的,on的话对上游压力很大)
  • proxy_send_timeout:向upstream发送请求的超时时间。
nginx接收upstream的响应
  • proxy_buffer_size size
  • proxy_buffering on|off:off为边发边收。
  • proxy_buffers number size:当不是边发边收的情况下就需要将包体写到磁盘中,但是磁盘还是比较慢的。如果这里指定了buffer,小文件(buffer能存放下)就不会写文件了。
  • proxy_max_temp_file_size size:限制upstream回返的包体写入磁盘的最大值。默认是1G。
  • proxy_temp_file_write_size size:限制每一次向临时磁盘文件写入的字节数。
  • proxy_temp_path path [level1 [level2 [level3]]]:临时文件写入的文件目录。
  • proxy_busy_buffers_size size:及时转发包体,先向客户端转发接收到的size字节。
  • proxy_read_timeout time:读取超时时间。
  • proxy_limit_rate rate :限速读取上游的响应。
上游出现失败时的容错方案

当upstream的上游服务返回失败时的处理方法。

  • proxy_next_upstream
    当出现错误,超时,错误头部,指定的返回码。
  • proxy_next_upstream_timeout 超时时间
  • proxy_next_upstream-tries 重试次数
location / {
                proxy_http_version 1.1;
                proxy_set_header Connection "";
                proxy_connect_timeout 1s;
                proxy_next_upstream off;
                proxy_pass http://backend;
        }

proxy_next_upsteam

  • off :错误了还是返回。
  • error:屏蔽错误,502。
  • http_500:500 错误会被屏蔽

你可能感兴趣的:(nginx的反向代理)