免费网站建设招商,网站制作与防护费用,Divi wordpress 下载,做网站好看的旅行背景图片1. What is Tornado Tornado是一个轻量级但高性能的Python web框架#xff0c;与还有一个流行的Python web框架Django相比。tornado不提供操作数据库的ORM接口及严格的MVC开发模式#xff0c;但能够提供主要的web server功能。故它是轻量级的#xff1b;它借助non-blocking … 1. What is Tornado Tornado是一个轻量级但高性能的Python web框架与还有一个流行的Python web框架Django相比。tornado不提供操作数据库的ORM接口及严格的MVC开发模式但能够提供主要的web server功能。故它是轻量级的它借助non-blocking and event-driven的I/O模型epoll或kqueue实现了一套异步网络库故它是高性能的。 Tornado的轻量级高性能特性使得它特别适用于提供web api的场合使用合理的话其非堵塞异步能力能够应对C10K问题。 须要特别注意的是因为Python的GIL导致多线程总是单核运行的”特点”tornado处理http请求时若某个请求的后端响应有堵塞现象如从DB或磁盘读数据导致处理时间非常长则会导致其他http请求也被block这会严重拖累tornado在高并发场景下的性能。 幸运的是。tornado提供了异步处理请求的能力在异步模式下我们能够通过传入回调函数或借助tornado提供的tornado.gen.coroutine装饰器使得tornado内部的io loop在等待当前请求响应结果的同一时候仍然能够接受其他的http请求这样就避免了某个耗时操作影响tornado的处理能力。 2. 怎样在tornado框架下编写异步处理代码 Tornado官网文档给出了几个简单的异步代码演示样例只是说实话代码太过简单都是在某个uri的handler类的get或post函数中展现了主要的异步语法没有多大的实战意义。 在实际项目中。复杂的处理逻辑不可能都堆在get或post函数中而是会封装在其他class中供handler类的get或post函数调用。所以本文给出一个稍复杂的实例旨在说明怎样在其他class的函数中实现异步处理逻辑以实现http请求异步化处理的目的。 如果如今的需求是用tornado实现一个web server支持名为cityhotel的uri方法当client通过http GET请求訪问该uri时web server依据query參数指定的城市去请求存放hotel具体数据的还有一个后端api。进行业务处理后返回某个连锁hotel在该城市的全部门店给client。 如果client GET请求的url格式为http://host/api/hotel/cityhotel?cityxxx 再如果存放hotel具体数据的后端api接口为http://hotel_backend/getCityHotels?cityxxx 依据上面的场景因为我们用tornado实现的web server接到client的请求后还要去还有一个API接口请求基础数据而后者在返回前tornado会block所以这样的场景下tornado最好以异步方式请求那个提供基础数据的API。避免不可控的后端拖累tornado的响应性能。 依据上面描写叙述的业务需求。以下的代码示范了怎样通过异步方式处理业务处理。 模块入口文件main.py #!/bin/env pythonimport tornado.ioloop
import tornado.web
import tornado.gen
import hotelcoreclass CityHotelHandler(tornado.web.RequestHandler):tornado.gen.coroutinedef get(self):## parse query paramsparams {}keys [city]for key in keys:value self.get_query_argument(key)params[key] value(status, rsp) yield hotelcore.HotelApiHandler.get_city_hotel(params[city])if 200 status:self.set_header(content-type, application/json)self.finish(rsp)else:self.set_status(404)self.finish()def main():app_inst tornado.web.Application([(r/api/hotel/cityhotel, CityHotelHandler),], compress_response True)app_inst.listen(8218)tornado.ioloop.IOLoop.current().start()if __main__ __name__:main() 处理业务逻辑的module封装在hotelcore.py文件里代码例如以下 #!/bin/env python
#-*- encoding: utf-8 -*-import jsonfrom tornado import gen
from tornado import httpclientclass HotelApiHandler(object):_cfg_dict {api_host : api.hotelbackend.com,}classmethodgen.coroutinedef get_city_hotel(cls, city):ret yield cls._parallel_fetch_city_hotel(city)raise gen.Return((200, ret))classmethodgen.coroutinedef _parallel_fetch_city_hotel(cls, city):base_url http://%s/v1/getCityHotel % (cls._cfg_dict[api_host])## hote type: 1normal room; 2deluxe roomhotel_type {normal: 1, deluxe: 2}urls []for v in hotel_type.values():api_url %s?city%slevel%s % (base_url, city, v)urls.append(api_url)## issue async http requesthttp_clt httpclient.AsyncHTTPClient()rsps_dict yield dict(normal_room http_clt.fetch(urls[0]), deluxe_room http_clt.fetch(urls[1]))city_hotel_info cls._parse_city_hotel(rsps_dict, city)ret { }if len(city_hotel_info):ret[errno] 0ret[errmsg] SUCCESSret[data] city_hotel_infoelse:ret[errno] 1ret[errmsg] Service Not Found at This Cityret[data] raise gen.Return(ret)classmethoddef _parse_city_hotel(cls, rsp_dict, city):city_hotel_info {}for hotel_level, rsp in rsp_dict.items():rsp_json json.loads(rsp.body)datas rsp_json[data]for city_id, city_detail in datas.items():name city_detail[name]if city in name:city_hotel_info[hotel_level] city_detailbreakreturn city_hotel_info 对以上代码的几点补充说明 编写tornado异步处理代码须要对Python的decorator语法和generator/yield语法比較熟悉tornado提供的装饰器gen.coroutine表明被装饰函数是个异步处理函数该函数的调用不会block tornado主线程被gen.coroutine装饰的函数中须要异步运行的耗时函数用yield来调用yield本身返回的是个generator结合gen.coroutine后。它返回一个tornado定义的Future类型的对象yield调用的函数在运行过程中。进程控制权会返给主线程故即使该函数须要较长运行时间tornado的主线程也能够继续处理其他请求在Python 2.x版本号的语法中。generator中不同意用return返回函数的返回值。必须用tornado提供的raise gen.Return(ret)达到返回的目的。这是个比較tricky的方法yield返回的Future对象能够通过调用body属性来获取通过yield调用的函数的返回值仅仅要结合上述几点理解了gen.coroutine和yield在tornado异步编程中的语法意义那么写出复杂的异步调用代码与编写实现同样功能但tornado总体性能无法保证的同步调用代码相比。实现难度就差点儿不存在了。上面的代码非常多语法细节没有展开希望实现思路能帮助到有缘人。^_^ 參考资料 Tornado Doc: User’s guideBook: Introduction to tornado chapter 5. asynchronous web services 转载于:https://www.cnblogs.com/llguanli/p/8406251.html