cherrypy和tornado性能分析

how is cherrypy working? it handls requests well compared with tornado when concurrence is low

tornado是单线程的。特点是异步服务很快。短小精悍。

web.py以cherrypy作为httpserver。

I have three test cases using siege to send requests to server (-c means number of users; -t is testing time). Code is below the test results.

1. web.py (cherrpy)

  siege ip -c20 -t100s             server can handle 2747requests  
  siege ip -c200 -t30s             server can handle 1361requests
  siege ip -c500 -t30s             server can handle 170requests

2. tornado synchronous

  siege ip -c20 -t100s             server can handle 600requests  
  siege ip -c200 -t30s             server can handle 200requests
  siege ip -c500 -t30s             server can handle 116requests

3. tornado asynchronous

  siege ip -c20 -t100s             server can handle 3022requests  
  siege ip -c200 -t30s             server can handle 2259requests
  siege ip -c500 -t30s             server can handle 471requests

performance analysis:

tornado synchronous < web.py (cherrypy) < tornado asynchronous

Question 1:

I know, using an asynchronous architecture can improve the performance of a web server dramatically.

I'm curious about the difference between tornado asynchronous architecture and web.py (cherry).

I think tornado synchronous mode handles requests one by one, but how is cherrypy working, using multiple threads? But I didn't see a large increase of memory. Cherrypy might handle multiple requests concurrently. How does it solve the blocking of a program?

Question 2:

Can I improve the performance of tornado synchronous mode without using asynchronous techniques? I think tornado can do better.

Web.py code:

import web
import tornado.httpclient
urls = (
    '/(.*)', 'hello'
)
app = web.application(urls, globals())

class hello:
    def GET(self, name):
        client = tornado.httpclient.HTTPClient()
        response=client.fetch("http://www.baidu.com/")
        return response.body

if __name__ == "__main__":
    app.run()

Tornado synchronous:

import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient
from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)
class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        client = tornado.httpclient.HTTPClient()
        response = client.fetch("http://www.baidu.com/" )
        self.write(response.body)


if __name__=='__main__':
    tornado.options.parse_command_line()
    app=tornado.web.Application(handlers=[(r'/',IndexHandler)])
    http_server=tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

Tornado asynchronous:

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient
from tornado.options import define, options
define("port", default=8001, help="run on the given port", type=int)
class IndexHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def get(self):
        client = tornado.httpclient.AsyncHTTPClient()
        response = client.fetch("http://www.baidu.com/" ,callback=self.on_response)

    def on_response(self,response):
        self.write(response.body)
        self.finish()

if __name__=='__main__':
    tornado.options.parse_command_line()
    app=tornado.web.Application(handlers=[(r'/',IndexHandler)])
    http_server=tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()
share | improve this question
 
1 
I very much suspect that your performance may be limited by fetch('http://www.baidu.com/') much more than by the web frameworks you use. Try comparing things when you serve static content, or, at least, the same locally-generated content. –  9000 Nov 23 '12 at 2:53
1 
it doesn't matter. I'm comparing the performance of different web server."fetch('baidu.com/')"; is just a blocking code. –  user1749075 Nov 23 '12 at 3:14
1 
Where does cherrypy come into this? –  Martijn Pieters Nov 27 '12 at 20:50
 
web.py uses cherrypy as built-in httpserver –  user1749075 Dec 4 '12 at 11:50

To answer question 1...

Tornado is single threaded. If you block the main thread, as you do in your synchronous example, then that single thread cannot do anything until the blocking call returns. This limits the synchronous example to one request at a time.

I am not particularly familiar with web.py, but looking at the source for its HTTP server it appears to be using a threading mixin, which suggests that it is not limited to handling one request at a time. When the first request comes in, it is handled by a single thread. That thread will block until the HTTP client call returns, but other threads are free to handle further incoming requests. This allows for more requests to be processed at once.

I suspect if you emulated this with Tornado, eg, by handing off HTTP client requests to a thread pool, then you'd see similar throughput.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值