我试图了解gevent获得的性能优势,并希望定量测量。基于this 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 *浏览器连接)的行为?
因此,如果只有一个工作者和100个客户端正在连接,那么对于第100个连接它应该花费大约100 * 3 = 300秒(因为第100个连接将不得不等待所有其他连接完成)BTW ,如果我打开3个浏览器并连接,我需要大约9秒的最坏情况,这是有道理的我认为:)。所以,我的第一个问题是,为什么在上述ab
结果中每次请求的时间约为7秒?我希望它会更多,因为只有前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秒,但上述结果表明它只需不到一秒钟,这是没有意义的。
我错过了什么?
我已经附加了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>