Python Web框架Tornado的异步处理代码演示样例

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?city=xxx
再如果存放hotel具体数据的后端api接口为:http://hotel_backend/getCityHotels?

city=xxx

依据上面的场景,因为我们用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',}@classmethod@gen.coroutinedef get_city_hotel(cls, city):ret = yield cls._parallel_fetch_city_hotel(city)raise gen.Return((200, ret))@classmethod@gen.coroutinedef _parallel_fetch_city_hotel(cls, city):base_url = 'http://%s/v1/getCityHotel' % (cls._cfg_dict['api_host'])## hote type: 1=normal room; 2=deluxe roomhotel_type = {'normal': 1, 'deluxe': 2}urls = []for v in hotel_type.values():api_url = '%s?city=%s&level=%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'] = 'SUCCESS'ret['data']   = city_hotel_infoelse:ret['errno']  = 1ret['errmsg'] = 'Service Not Found at This City'ret['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总体性能无法保证的同步调用代码相比。实现难度就差点儿不存在了。

上面的代码非常多语法细节没有展开,希望实现思路能帮助到有缘人。^_^

參考资料

  1. Tornado Doc: User’s guide
  2. Book: Introduction to tornado chapter 5. asynchronous web services

转载于:https://www.cnblogs.com/llguanli/p/8406251.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/398715.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux基础--MBR/GPT与parted

关于MBR和GPT这两种分区表,wiki上讲的很清楚。不过有些同学可能看不了,你需要先了解科学上网。这里我就只把它们的结构图贴上,简要说明了。https://zh.wikipedia.org/wiki/%E4%B8%BB%E5%BC%95%E5%AF%BC%E8%AE%B0%E5%BD%95https://zh.wikipedi…

MYSQL的空间查询(转帖)

SELECT x(location),y(location) FROM frddata.points; 本文将向各位介绍如何使用MySql5.x中的空间数据库,并展示一下它高效的性能(前提是正确使用)。 本文适合于对SQL和MYSQL熟悉的人员。 步骤1:创建支持空间查询的表 首先来说一…

数据库杂谈(五)——关系数据库语言

文章目录5 关系数据库语言5.1 MySQL简介5.1.1 MySQL的发展历史5.1.2 数据库的用户接口5.1.3 SQL及其概念辨析5.1.4 SQL查询语言的分类5.2 入手5.2.1 回顾——基本和虚表5.2.2 数据准备5.2.3 常用命令5.2.4 导入数据5.2.5 简单的查询5.2.6 条件查询5.2.6.1 条件查询格式5.6.2.1 …

ansible---基础

ansible特点:不需要安装客户端,通过sshd去通信基于模块工作,模块可以由任何语言开发不仅支持命令行使用模块,也支持编写yaml格式的playbook支持sudo安装:yum install -y epel-releaseyum install -y ansible 配置文件&…

Suse 12 安装VMware tool

cd /run/media/root /VMware Tools 查看光盘目录mdkir tool chmod -R 777 /tool 赋予文件夹权限cp -rf /run/media/root /VMware Tools /toolcd /tooltar -zxvf VMwareTools-9.10.0-2476743.tar.gz cd vmware-tools-distrib/ ./vmware-install.pl 执行安装 转载于:https:…

css斜角覆盖阴影

Demo下载 效果如图: css: #box { width: 280px; height: 150px; background: #ff6565; padding: 20px; position: relative; overflow: hidden; } #content { width: 280px; height: 15…

Django 模型与 Mysql 数据类型对应

Django 1.11.9 文件路径:site-packages\django\db\backends\mysql\base.py–class DatabaseWrapper _data_types { ‘AutoField’: ‘integer AUTO_INCREMENT’, ‘BigAutoField’: ‘bigint AUTO_INCREMENT’, ‘BinaryField’: ‘longblob’, ‘BooleanFiel…

王道操作系统考研笔记——2.3.4 信号量机制

文章目录2.3.4 信号量机制2.3.4.1 引入2.3.4.2 整型信号量2.3.4.3 记录型信号量2.3.4.4 小结2.3.4 信号量机制 知识总览 在1965年,荷兰学着Dijkstra提出了一种卓有成效的实现进程互斥、同步的方法——信号量机制。 2.3.4.1 引入 用户进程可以通过使用操作系统提供…

QT分析之WebKit

该文章整理自 网易博客 http://blog.163.com/net_worm/blog/static/12770241920101831312381/ 转载请注明出处 WebKit是QT4新整合的第三方构件。按照惯例动手分析之前,先了解大概 WebKit由三个模块组成:JavaScriptCore、WebCore 和 WebKit WebKit作为了整…

ViewPager循环

android.support.v4.view.ViewPager ViewPager的使用跟AbsListView,AbsSpinner类似,需要用一个adapter填充数据,同时实现了onPagerChangeListener接口。 ViewPager需要的adapter继承自android.support.v4.view.PageAdapter,getCount返回adapt…

angularjs学习笔记—工具方法

1.angular.bind(self, fn, args) 作用:返回一个新的函数,绑定这个函数的this指向self 参数:self:新函数的上下文对象 fn:需要绑定的函数 args:传递给函数的参数 返回值:this指向self的新函数 …

SpringMVC配置项学习笔记

1. <mvc:annotation-driven /> <mvc:annotation-driven />是一种简写形式&#xff0c;默认会注册DefaultAnnotationHandlerMapping和DefaultAnnotationHandlerAdapt两个bean&#xff0c;是spring mvc为Controller分发请求所必须的&#xff0c;它还提供了NumberForm…

MIT算法导论(一)——算法分析和引论

文章目录1 算法分析及引论1.1 算法1.2 排序1.2.1 插入排序1.2.1.1 插入排序原理1.2.1.2 时间复杂度1.2.1.3 渐进时间复杂度1.2.1.4 回到算法1.2.2 归并排序1.2.2.1 归并排序原理1.2.2.2 归并排序时间复杂度1 算法分析及引论 1.1 算法 算法是一门关注性能的学科&#xff0c;也…

使用Apache Tomcat Maven插件部署运行 Web 项目

2019独角兽企业重金招聘Python工程师标准>>> 什么是Apache Tomcat Maven Plugin&#xff1f; Maven Plugin 是Apache Tomcat 提供的一个Maven插件&#xff0c;它可以在你没有tomcat容器时将任何一个war项目文件部署在该插件上提供访问。 为什么要用Apache Tomcat Ma…

POJ2104 (平方分割)二分查找理解。

题意&#xff1a;任意区间求第k大数 思路&#xff1a; 预处理&#xff1a;利用平方分割&#xff08;分桶法&#xff09;把区间切割成B sqrt(n)大小的一块块&#xff0c;然后每个各自排序。 二分第k大数x&#xff0c;接着就需要求[l,r]区间中x的排名&#xff0c;与k比较&#x…

每日一题——leetcode237 删除链表中的结点

1 题目 237. 删除链表中的节点 难度简单 请编写一个函数&#xff0c;用于 删除单链表中某个特定节点 。在设计函数时需要注意&#xff0c;你无法访问链表的头节点 head &#xff0c;只能直接访问 要被删除的节点 。 题目数据保证需要删除的节点 不是末尾节点 。 示例 1&am…

error: stray '\343' in program 问题解决

当我们从网上copy一段代码后&#xff0c;总会出现这个问题。博主在Arduino环境中也出现了&#xff0c;so,这个问题应该是C语言和C编译器中才会出现的。 test_int:19: error: stray \343 in program 銆?銆? char string[25]; ^ test_int:19: error: stray \200 in progr…

wex5中win8或者win10操作系统studio中新建.w向导或其他的编辑窗口显示不全

多数情况都是通过方法2解决的 &#xff08;1&#xff09; 确认是否把操作系统的字体调整为非100%了&#xff08;2&#xff09; 把studio\dropins\studio-app2\plugins\plugin\lib\cef1\chromium.jar这个jar包复制到studio\dropins\studio-app2\plugins\plugin\lib下&#xff0c…

安装CoreOS到磁盘

1 打开翻&&墙软件 2 打开迅雷&#xff0c;启用“使用IE代理”&#xff0c;下载以下两个文件&#xff1a;&#xff08;翻&&墙后用IE下会中断&#xff09; http://stable.release.core-os.net/amd64-usr/494.4.0/coreos_production_image.bin.bz2.sig http://sta…

机器学习的练功心法(一)——机器学习概述

1 机器学习概述 文章目录1 机器学习概述1.1 学习方法1.2 什么是机器学习1.3 监督学习1.4 无监督学习1.5 强化学习1.6 机器学习的开发流程1.1 学习方法 引入&#xff1a;对于机器学习来说&#xff0c;我们需要有一个大局观&#xff0c;什么是大局观&#xff1f;你站的比别人高&…