2015年(68)
分类: 系统运维
2015-08-31 19:10:25
当用nginx来做前端的时候,有几个超时的设置是需要留意的:
upstream的 fail_timeout和max_fails
pstream的这2个参数是配合使用的,用来判断负载均衡upstream中的某个server是否失效。在fail_timeout的时间内,nignx与upstream中某个server的连接尝试失败了max_fails次,则nginx会认为该server已经失效。在接下来的 fail_timeout时间内,nginx不再将请求分发给失效的server。
fail_timeout默认为10秒,max_fails默认为1。是指在10秒内nginx与后端server连接失败尝试只有一次,如果在10秒内nginx与后端的连接失败达到一次,nginx认为这个server已失效,在接下来的10秒内,nginx将不会分发请求到这台后端。
如果max_fails=0,即关闭后端服务器健康检查,如果权重一样,那么每次请求都会有机会发到后端不可用的服务器。
另外,fail_timeout设置的时间对响应时间没影响,这个响应时间是用接下来的proxy_connect_timeout和proxy_read_timeout来控制。
proxy_connect_timeout
nginx与后端连接的超时时间,单位为秒,默认为60秒。我们在nginx错误日志里面看到的(110: Connection timed out),就是指nginx与后端连接已经超时。
proxy_read_timeout
建立连接后,nginx等候读取后端服务器响应的时间,默认为60秒。在一些比较繁忙的后端,比如线程数经常达到峰值了的tomcat,这个值注意不要设得太低,虽然线程数已经用光,但请求已经进入待队列之中。
proxy_send_timeout
nginx转发请求到后端的超时时间,默认为60秒,在这段时间内nginx没将请求数据发到后端将关闭连接。
这个在网站有比较多像表单(post)之类的需要留意一下。
可以用测试来对对上面所说的:
用来的测试的系统结构如下
web:8081(172.30.254.32)
/
request--〉nginx:80(172.30.254.33)-
\
web:81(172.30.254.33)
=============================================
测试1:测试fail_timeout、max_fails、proxy_connect_timeout
//nginx配置
----------------------------------
server 172.30.254.32:8081 max_fails=2 fail_timeout=15s weight=3;
server 172.30.254.33:81 max_fails=2 fail_timeout=15s weight=1;
proxy_connect_timeout 3;
在log最后加上 "$upstream_addr" "$upstream_status"
--------------------------------
在172.30.254.32上禁止访问8081口用于测试
[root@ localhos ]# iptables -A INPUT -p tcp --dport 8081 -j DROP
测试开始
//发http请求并记录开始时间,-c 1 --并发为1,即20条请求是一条一条按顺序发
[root@localhos tmp]# date;/usr/local/apache/bin/ab -n 20 -c 1
2012年 06月 30日 星期六 16:11:55CST
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd,
------ 略-------
//看访问日志
[root@server33 tmp]# wc -l access.log
20 access.log ##请求全部到达nginx
[root@server33 tmp]# cat access.log
172.30.254.33 - - [30/Jun/2012:16:11:58 +0800] "GET / HTTP/1.0" 200 7434 "-" "ApacheBench/2.3" "-""172.30.254.32:8081, 172.30.254.33:81" "504, 200"
172.30.254.33 - - [30/Jun/2012:16:12:01 +0800] "GET / HTTP/1.0" 200 7434 "-" "ApacheBench/2.3" "-""172.30.254.32:8081, 172.30.254.33:81" "504, 200"
172.30.254.33 - - [30/Jun/2012:16:12:01 +0800] "GET / HTTP/1.0" 200 7434 "-" "ApacheBench/2.3" "-""172.30.254.33:81" "200"
172.30.254.33 - - [30/Jun/2012:16:12:01 +0800] "GET / HTTP/1.0" 200 7434 "-" "ApacheBench/2.3" "-""172.30.254.33:81" "200"
172.30.254.33 - - [30/Jun/2012:16:12:01 +0800] "GET / HTTP/1.0" 200 7434 "-" "ApacheBench/2.3" "-""172.30.254.33:81 " "200"
172.30.254.33 - - [30/Jun/2012:16:12:01 +0800] "GET / HTTP/1.0" 200 7434 "-" "ApacheBench/2.3" "-""172.30.254.33:81" "200"
172.30.254.33 - - [30/Jun/2012:16:12:01 +0800] "GET / HTTP/1.0" 200 7434 "-" "ApacheBench/2.3" "-""172.30.254.33:81 " "200"
172.30.254.33 - - [30/Jun/2012:16:12:01 +0800] "GET / HTTP/1.0" 200 7434 "-" "ApacheBench/2.3" "-""172.30.254.33:81" "200"
172.30.254.33 - - [30/Jun/2012:16:12:01 +0800] "GET / HTTP/1.0" 200 7434 "-" "ApacheBench/2.3" "-""172.30.254.33:81" "200"
172.30.254.33 - - [30/Jun/2012:16:12:01 +0800] "GET / HTTP/1.0" 200 7434 "-" "ApacheBench/2.3" "-""172.30.254. 33:81" "200"
---- 略 -----
//说明
请求开始的时间为 16:11:55
nginx接到第一个请求的时间为 16:11:58
nginx接到第二个请求的时间为 16:12:01
可以看到隔间为3秒,等于上设置的proxy_connect_timeout 3
从上面可以看到,从11分55秒开始http请求,我设置的8081的weight比较高,nginx会先把请求发到32的8081口,但是32服务器的8081端口iptables挡住了,等了3s到了11分58秒还没建立连接,超时时间到,将请求发到一个服务(即33的81口)并成功响应。access.log记录第一条日志:
172.30.254.33 - - [30/Jun/2012:16:11:58 +0800] "GET / HTTP/1.0" 200 7434 "-" "ApacheBench/2.3" "-""172.30.254.32:8081, 172.30.254.33:81" "504, 200"
第二个请求依然先发到8081口,跟上面的一样,3s超时,发到下一个服务并成功响应,时间为12分01秒。access.log记录第二条日志
172.30.254.33 - - [30/Jun/2012:16:12:01 +0800] "GET / HTTP/1.0" 200 7434 "-" "ApacheBench/2.3" "-""172.30.254.32:8081, 172.30.254.33:81" "504, 200"
第三个请求,在15秒内,8081口的通信失败次数已达到了max_fails设置的2次,nginx认为8081口已经不可用,在接下来的15秒,nginx会把所有的请求都分发到33的81口。从access.log可以看到,从第三条开始nginx连到的后端都是172.30.254.33:81
=============================================
测试2:测试proxy_read_timeout
//测试用cgi脚本
#!/usr/bin/python
# -*- coding: utf-8 -*-
import cgi, cgitb
from time import sleep
sleep(10)
print "Content-type:text/html\r\n\r\n"
print "<html>"
print "<head>"
print "<title>test</title>"
print "</head>"
print "<body>"
print "Just for test"
print "</body>"
print "</html>"
##脚本会在10s后响应,proxy_read_timeout的时间设置少10s,看看测试情况
//nginx配置
----------------------------------
proxy_pass 172.30.254.33:81;
proxy_read_timeout 5;
----------------------------------
//开始测试
[root@localhost ~]# date;curl -I
2012年 06月 30日 星期六 18:28:47CST
HTTP/1.1 504 Gateway Time-out
Server: nginx/0.8.18
Date: Sat, 30 Jun 2012 10:28:52 GMT
Content-Type: text/html
Content-Length: 183
Connection: keep-alive
2012年 06月 30日 星期六 18:28:52CST
##服务器33的81口连接情况
root@server33]# date;netstat -na |grep 172.30.254.33:81 |grep tcp|grep -i estab
2012年 06月 30日 星期六 18:28:43 CST
[root@server33]# date;netstat -na |grep 172.30.254.33:81 |grep tcp|grep -i estab
2012年 06月 30日 星期六 18:28:49 CST
tcp 0 0 172.30.254.33:42731 172.30.254.33:81 ESTABLISHED
tcp 0 0 ::ffff:172.30.254.33:81 ::ffff:172.30.254.33:42731 ESTABLISHED
[root@server33]# date;netstat -na |grep 172.30.254.33:81 |grep tcp|grep -i estab
2012年 06月 30日 星期六 18:28:50 CST
tcp 0 0 172.30.254.33:42731 172.30.254.33:81 ESTABLISHED
tcp 0 0 ::ffff:172.30.254.33:81 ::ffff:172.30.254.33:42731 ESTABLISHED
[root@server33]# date;netstat -na |grep 172.30.254.33:81 |grep tcp|grep -i estab
2012年 06月 30日 星期六 18:28:51 CST
tcp 0 0 172.30.254.33:42731 172.30.254.33:81 ESTABLISHED
tcp 0 0 ::ffff:172.30.254.33:81 ::ffff:172.30.254.33:42731 ESTABLISHED
[root@server33]# date;netstat -na |grep 172.30.254.33:81 |grep tcp|grep -i estab
2012年 06月 30日 星期六 18:28:53 CST
//说明
18:28:47 开始http请求,18:28:52 达到proxy_read_timeout设置的5s时间还没收到后端的响应,超时退出、关闭连接并报504错误。在后端的33上可以看到连接情况,在18:28:47~18:28:52 这段时间内,连接已经建立。
最后说一下proxy_connect_timeout的设置,不要看到nginx的错误日志里面有很多像504这类的超时错误就把proxy_connect_timeout设置的很高,这个个人觉得是不好的,这个值的设置跟tcp的超时时间和后端服务器的个数有很大关系。另外nginx认为这个值不要大于75s,据我查到的说法是--系统调用connect函数时,内核发送一个SYN,若无响应6s后再发送一个,若仍然无响应则等待24s后再发送一个,若等待了75s仍未响应则返回connect timeout错误。