标签:
Tornado的代名词就是异步非阻塞I/O,与其说tornado是一个web框架,我更喜欢把它理解成一个服务器,一个支持多并发的服务器。
Tornado的设计初衷就是为了解决“C10K”的问题,就是一万的并发,Django自带服务器也就支持一百多并发,可见Tornado性能优异。
其实Django和Tornado可以在一起使用,Django和Tornado的结合使得python在web方向具有很强的竞争力。
我用一个实例来解释Tornado的多并发,我自制一个在线翻译,借助有道API,我将需要翻译的数据发送过去之后,有道API会返回给我json数据。
首先,先写一个同步的服务器,我假设我发送数据之后有道会过5秒钟才会把数据返回给我。
#coding=utf-8
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient
import urllib
import json
import datetime
import time
from tornado.options import define,options
define("port",default=8000,help="run on the given port",type=int)
class Index(tornado.web.RequestHandler):
def get(self):
query = self.get_argument(‘q‘)
baseurl =r‘http://fanyi.youdao.com/openapi.do?keyfrom=pyworm&key=973100900&type=data&doctype=json&version=1.1&q=‘
url = baseurl+query
client = tornado.httpclient.HTTPClient()
response = client.fetch(url)
time.sleep(5)
fanyi = json.loads(response.body)
trans = u‘%s:\n%s\n%s\n%s\n%s\n%s‘%(fanyi[‘query‘],‘‘.join(‘-‘ * 3 + u‘翻译‘ + ‘-‘ * 3),‘‘.join(fanyi[‘translation‘]),‘‘.join(‘-‘ * 3 + u‘词典‘ + ‘-‘ * 3),‘‘.join(fanyi[‘basic‘][‘phonetic‘]),‘‘.join(‘-‘ * 3 + u‘网络释义‘ + ‘-‘ * 3),)
self.write(trans)
if __name__ == ‘__main__‘:
tornado.options.parse_command_line()
app = tornado.web.Application(handlers = [(r"/",Index)])
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
运行上面代码之后,访问http://localhost:8000/?q=hello就会看到翻译信息:hello: ---翻译--- 你好 ---词典--- h?‘l??; he- ---网络释义---。然后我就以这台电脑做服务器,另外一台电脑访问这台服务器http://192.168.0.101:8000/?q=hello同样得到翻译信息:hello: ---翻译--- 你好 ---词典--- h?‘l??; he- ---网络释义---。但是如果两台电脑同时进行翻译,会出现5秒之后一台电脑翻译成功,再过5秒另外一台翻译成功,这就是同步,第二台电脑要等第一台翻译完才会去翻译。
现在我要这服务器支持多并发,两台电脑同时翻译,会同时翻译成功。
Tornado包含一个AsyncHTTPClient类,可以执行异步HTTP请求。
#coding=utf-8
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient
import urllib
import json
import datetime
import time
from tornado.options import define,options
define("port",default=8000,help="run on the given port",type=int)
class Index(tornado.web.RequestHandler):
@tornado.web.asynchronous
@tornado.gen.engine
def get(self):
query = self.get_argument(‘q‘)
baseurl =r‘http://fanyi.youdao.com/openapi.do?keyfrom=pyworm&key=973100900&type=data&doctype=json&version=1.1&q=‘
url = baseurl+query
client = tornado.httpclient.AsyncHTTPClient()
response = yield tornado.gen.Task(client.fetch,url)
fanyi = json.loads(response.body)
trans = u‘%s:\n%s\n%s\n%s\n%s\n%s‘%(fanyi[‘query‘],‘‘.join(‘-‘ * 3 + u‘翻译‘ + ‘-‘ * 3),‘‘.join(fanyi[‘translation‘]),‘‘.join(‘-‘ * 3 + u‘词典‘ + ‘-‘ * 3),‘‘.join(fanyi[‘basic‘][‘phonetic‘]),‘‘.join(‘-‘ * 3 + u‘网络释义‘ + ‘-‘ * 3),)
self.write(trans)
self.finish()
if __name__ == ‘__main__‘:
tornado.options.parse_command_line()
app = tornado.web.Application(handlers = [(r"/",Index)])
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
关于上面代码用到的装饰器,yield等请参考Tornado文档http://demo.pythoner.com/itt2zh/ch5.html
标签:
原文地址:http://www.cnblogs.com/pylab/p/4693534.html