tornado 异步web
若想学会异步,必先学同步。
1.同步web开发代码,就是单向进行的,服务器必须先响应前一个请求,才能处理后一个请求。
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient
import datetime
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):
query = self.get_argument('q')
client = tornado.httpclient.HTTPClient()
response = client.fetch("http://www.baidu.com?wd={}".format(query))
body = response.body
result_count = len(body)
now = datetime.datetime.utcnow()#输出的是代表世界时间
self.write("""
<div style="text-align: center">
<div style="font-size: 72px">%s</div>
<div style="font-size: 144px">%s</div>
<div style="font-size: 144px">%s</div>
<div style="font-size: 24px">tweets per second</div>
</div>""" % (query,result_count, now))
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()
在linux终端运行优秀的Siege utility工具进行测试。它可以这样使用:
siege http://localhost:8000/?q=pants -c10 -t10s
运行结果是:
2 异步web代码如下:
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient
import datetime
from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)
class IndexHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
def get(self):
query = self.get_argument('q')
client = tornado.httpclient.AsyncHTTPClient()
client.fetch("http://www.baidu.com?wd={}".format(query), callback=self.on_response)
def on_response(self, response):
body = response.body
result_count = len(body)
now = datetime.datetime.utcnow()
self.write("""
<div style="text-align: center">
<div style="font-size: 72px">%s</div>
<div style="font-size: 144px">%s</div>
<div style="font-size: 24px">%s</div>
<div style="font-size: 24px">tweets per second</div>
</div>""" % (self.get_argument('q'), result_count, now))
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()
在linux终端运行优秀的Siege utility工具进行测试。它可以这样使用:
siege http://localhost:8000/?q=pants -c10 -t10s
运行结果是:
明显发现,在异步web 的response time的响应时间短,且successful transaction 次数多。因此异步的优势明显强于同步。记住当你使用@tornado.web.asynchonous装饰器时,Tornado永远不会自己关闭连接。你必须在你的RequestHandler对象中调用finish方法来显式地告诉Tornado关闭连接。异步相比较同步使用了callback回调函数,创建了client实例。callback函可不用等待上个任务结束,也可以运行。
3 异步web 简化版
mport tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient
import tornado.gen
import datetime
from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)
class IndexHandler(tornado.web.RequestHandler):
@tornado.web.asynchronous
@tornado.gen.engine
def get(self):
query = self.get_argument('q')
client = tornado.httpclient.AsyncHTTPClient()
response = yield tornado.gen.Task(client.fetch, "http://www.baidu.com?wd={}".format(query))
body = response.body
result_count = len(body)
now = datetime.datetime.utcnow()
self.write("""
<div style="text-align: center">
<div style="font-size: 24px">%s</div>
<div style="font-size: 24px">%s</div>
<div style="font-size: 24px">%s</div>
<div style="font-size: 24px">tweets per second</div>
</div>""" % (query, result_count, now))
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()
在linux终端运行优秀的Siege utility工具进行测试。它可以这样使用:
siege http://localhost:8000/?q=pants -c10 -t10s
运行结果如下图:
Python的yield关键字以及tornado.gen.Task对象的一个实例,将我们想要的调用和传给该调用函数的参数传递给那个函数。这里,yield的使用返回程序对Tornado的控制,允许在HTTP请求进行中执行其他任务。此种异步没有调用callback函数。 程序相对第二种web异步简单。