I tested the cherry test (using web.py as a framework) and the tornado by extracting web pages from the Internet.
I have three test cases using siege to send requests to the server (-c means the number of users, -t means the time of testing). The 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 synchronously
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:
synchronous tornado <web.py (cherrypy) <tornado asynchronous
Question 1:
I know that using asynchronous architecture can significantly improve web server performance.
I am interested to know the difference between asynchronous tornado architecture and web.py (cherry).
I think the synchronous tornado mode handles requests one by one, but how does the cherry work using multiple threads? But I did not see a large increase in memory. Cherrypy can handle multiple requests at once. How does this allow a program lock?
Question 2:
Can I improve the performance of the tornado synchronous mode without using asynchronous methods? I think tornadoes 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 synchronously:
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()
asynchronous tornado:
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()