模块是 HttpUpstreamModule,配置的一个例子:nginx
[shell]upstream http_backend {
server 127.0.0.1:8080;shell
keepalive 16;
}
server {
…后端
location /http/ {
proxy_pass http://http_backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
…
}
}[/shell]tomcat
有几点要说明:服务器
1. 默认状况下 Nginx 访问后端都是用的短链接(HTTP1.0),一个请求来了,Nginx 新开一个端口和后端创建链接,请求结束链接回收。若是像上面的配置同样设置了长链接,Nginx 会接受客户端的请求,处理完成以后 Nginx 会「继续保持和后端的长链接」,若是并发请求超过了 keepalive 指定的最大链接数,Nginx 会启动新的链接 来转发请求,新链接在请求完毕后关闭,并且新创建的链接是长链接,这可能会形成额外的问题,最后再说。并发
2. keepalive 指定的 数值 是 Nginx 每一个 worker 链接后端的最大长链接数,而不是整个 Nginx 的。 并且这里的后端指的是「全部的后端」,而不是每个后端(已验证)。负载均衡
3. 在官网上 能够看到 还有一个 single 参数,说实话我没懂什么意思,可是它已经被废弃了,看这里tcp
4. HttpUpstreamModule 模块里面还有一共指令:least_conn,解释以下:tornado
Specifies that a group should use a load balancing method where a request is passed to the server with the least number of active connections, taking into account weights of servers. If there are several such servers, they are tried in turn using a weighted round-robin balancing method.测试
翻译:
指定服务器组的负载均衡方法,根据其权重值,将请求发送到「活跃链接数最少」的那台服务器。 若是这样的服务器有多台,那就采起有权重的轮转法进行尝试。
使用这个指令的时候后端服务器的链接数好像会变的很是少,很奇怪,我还没亲自测过,待确认。
最后再说一下第 1 点,先说一个现象,我发现当 keepalive 设置小的时候,好比1,那么并发请求上去以后 Nginx 会出现大量的 TIME_WAIT,而若是把 keepalive 关掉(proxy_http_version 1.1 和 proxy_set_header Connection “” 指令也去掉),那么 TIME_WAIT 就会出如今后端服务器了,后端用的是 tornado,相信 jetty 和 tomcat 也是同样。
这个现象是怎么产生的呢,作一个测试。
命令:ab -n 100 -c 5 http://pxe1.hy01/
pxe1.hy01 (Nginx,上面配置了长链接,ip: 10.0.31.84) ,它会转到 pxe0.hy01 的 8888 端口(tornado,ip: 10.0.11.12)
测试的时候在 pxe1.hy01 执行抓包命令:
# tcpdump -i em2 -A host 10.0.11.12 -n
看到:
00:22:53.252039 IP 10.0.31.84.53915 > 10.0.11.12.ddi-tcp-1: Flags [P.], seq 81:161, ack 275, win 123, length 80
@.@.].
..T
…..”…p%8|..P..{>…GET / HTTP/1.1
Host: http_backend
User-Agent: ApacheBench/2.3
Accept: */*
可是若是把 pxe1.hy01 的长链接设置都去掉的话,抓包以下:
00:23:58.111974 IP 10.0.31.84.54051 > 10.0.11.12.ddi-tcp-1: Flags [P.], seq 1:100, ack 1, win 115, length 99
E…..@.@.Z=
..T
….#”…O…SUP..s>…GET / HTTP/1.0
Host: http_backend
Connection: close
User-Agent: ApacheBench/2.3
Accept: */*
那么上面出现的现象就好解释了,是这样:
Nginx 和后端的长链接不够用时 Nginx 会新建链接来处理新的请求,而咱们的配置已经配置死了 HTTP1.1,创建链接后,后端认为是「长链接」而不会主动关闭链接(通常有个空闲超时),关闭链接由 Nginx 来作了,因此 Nginx 会出现大量的 TIME_WAIT。
而默认状况下,Nginx 用 HTTP1.0 请求后端,后端处理完成后就主动关闭链接,因此 TIME_WAIT 在后端。
那么如今有新的问题了,若是开启了长链接,而长链接又大量不够用,此时 Nginx 存在的 TIME_WAIT 可能会大量占用端口,致使端口用尽,若是用尽,后果很严重。
因此,「慎用 Nginx 的 长链接」。