我正在尝试了解 gevent 获得的性能优势,并希望对其进行定量测量。基于这个 SO answer,我创建了一个简单的 django 应用程序,它在一个简单的视图中休眠了 3 秒。
当我使用 1 个同步工作者运行 gunicorn 时,当我使用 firefox 检查时,我每秒收到约 3 秒的可预测请求。当我再打开一个浏览器时,我可以看到它需要更长的时间(~ 3 * 我打开的浏览器数量)。前端服务器是 nginx。
我的观点:
def home(request,epoch):
sleeptime = 3
time.sleep(sleeptime);
html = "<html><body>%s </body></html>" % str(float(time.time()) - float(epoch) / 1000)
return HttpResponse(html)
但是,当我运行以下ab
命令 ab -r -n 100 -c 100 http://ec2-compute-1.amazonaws.com/
使用以下 gunicorn 命令,
gunicorn --pythonpath=/home/ubuntu/webapps/testt -c /home/ubuntu/webapps/testt/gunicorn.conf.py testt.wsgi
我得到以下结果:
Concurrency Level: 100
Time taken for tests: 7.012 seconds
Complete requests: 100
Requests per second: 14.26 [#/sec] (mean)
Time per request: 7011.750 [ms] (mean)
Time per request: 70.118 [ms] (mean, across all concurrent requests)
Transfer rate: 40.53 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 37 837 1487.4 98 3869
Processing: 0 3475 913.2 3777 3890
Waiting: 0 3467 911.2 3777 3889
Total: 3141 4312 1150.1 3870 7011
我应该如何从上述结果中理解 (3 * browser connections) 的行为?
因此,如果只有一名工作人员和 100 个客户端正在连接,那么第 100 个连接实际上应该需要大约 100 * 3 = 300 秒(因为第 100 个连接必须等待所有其他连接完成)顺便说一句,如果我打开 3 个浏览器并连接,我需要大约 9 秒最坏的情况,我认为这是有道理的 :)。所以,我的第一个问题是,在上面的结果中,为什么每次请求的 Time 大约为 7 秒ab
?我希望它会更多,因为只有前 2 个连接需要大约 6 秒,所有第 n 个并发连接都需要 n*3 秒才能返回。
当我不更改程序时,只需执行以下操作:
gunicorn -k gevent --pythonpath=/home/ubuntu/webapps/testt -c /home/ubuntu/webapps/testt/gunicorn.conf.py testt.wsgi
并运行相同的ab
命令,我得到以下(!):
Concurrency Level: 100
Time taken for tests: 0.558 seconds
Complete requests: 100
Failed requests: 0
Write errors: 0
Total transferred: 255300 bytes
HTML transferred: 241600 bytes
Requests per second: 179.32 [#/sec] (mean)
Time per request: 557.675 [ms] (mean)
Time per request: 5.577 [ms] (mean, across all concurrent requests)
Transfer rate: 447.06 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 33 44 6.2 47 58
Processing: 47 133 74.0 122 506
Waiting: 46 132 74.2 122 506
Total: 80 177 76.2 162 555
所以你完成一个请求的最短时间是 3 秒,但是上面的结果表明它不到 1 秒,这是没有意义的。
我错过了什么?
我已经附加了正在 ping 视图的客户端(它与上面链接的 SO 问题中列出的类似,但不完全相同:
<html>
<head>
<title>BargePoller</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css" media="screen">
body{ background:#000;color:#fff;font-size:.9em; }
.msg{ background:#aaa;padding:.2em; border-bottom:1px #000 solid}
.old{ background-color:#246499;}
.new{ background-color:#3B9957;}
.error{ background-color:#992E36;}
</style>
<script type="text/javascript" charset="utf-8">
function addmsg(type, msg){
/* Simple helper to add a div.
type is the name of a CSS class (old/new/error).
msg is the contents of the div */
$("#messages").append(
"<div class='msg "+ type +"'>"+ msg +"</div>"
);
}
function waitForMsg(){
/* This requests the url "msgsrv.php"
When it complete (or errors)*/
var currentdate = new Date();
$.ajax({
type: "GET",
url: "server/" + currentdate.getTime() + "/",
async: true, /* If set to non-async, browser shows page as "Loading.."*/
cache: false,
timeout:50000, /* Timeout in ms */
success: function(data){ /* called when request to barge.php completes */
addmsg("new", data); /* Add response to a .msg div (with the "new" class)*/
setTimeout(
waitForMsg, /* Request next message */
1000 /* ..after 1 seconds */
);
},
error: function(XMLHttpRequest, textStatus, errorThrown){
var currentdate = new Date();
addmsg("error", currentdate.getTime() + textStatus + " (" + errorThrown + " " + currentdate.getTime() + ")");
setTimeout(
waitForMsg, /* Try again after.. */
1000); /* milliseconds (15seconds) */
},
beforeSend: function(){
var currentdate = new Date();
addmsg("body", currentdate + " <- sent request");
}
});
};
$(document).ready(function(){
waitForMsg(); /* Start the inital request */
});
</script>
</head>
<body>
<div id="messages">
<div class="msg old">
BargePoll message requester!
</div>
</div>
</body>
</html>