阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Tornado异步

536次阅读
没有评论

共计 3259 个字符,预计需要花费 9 分钟才能阅读完成。

一、说明

因为 epoll 主要是用来解决网络 IO 的并发问题,所以 Tornado 的异步编程也主要体现在网络 IO 的异步上,即异步 Web 请求

二、Tornado 异步处理方法与类

  • tornado.httpclient.AsyncHTTPClient

    Tornado 提供了一个异步 Web 请求客户端 tornado.httpclient.AsyncHTTPClient 用来进行异步 Web 请求

  • fetch(request, callback=None)

    用于执行一个 web 请求 request,并异步返回一个 tornado.httpclient.HTTPResponse 响应

    request 可以是一个 url,也可以是一个 tornado.httpclient.HTTPRequest 对象。如果是 url,fetch 会自己构造一个 HTTPRequest 对象

  • HTTPRequest

    HTTP 请求类,HTTPRequest 的构造函数可以接收众多构造参数,最常用的如下

    • url(string) – 要访问的 url,此参数必传,除此之外均为可选参数
    • method (string) – HTTP 访问方式,如“GET”或“POST”,默认为 GET 方式
    • headers (HTTPHeaders or dict) – 附加的 HTTP 协议头
    • body – HTTP 请求的请求体
  • HTTPResponse

    HTTP 响应类,其常用属性如下:

    • code: HTTP 状态码,如 200 或 404
    • reason: 状态码描述信息
    • body: 响应体字符串
    • error: 异常(可有可无)

三、tornado.web.asynchronous 回调异步

  • 说明

    此装饰器用于回调形式的异步方法,并且应该仅用于 HTTP 的方法上(如 get、post 等)

    此装饰器不会让被装饰的方法变为异步,而只是告诉框架被装饰的方法是异步的,当方法返回时响应尚未完成。只有在 request handler 调用了 finish 方法后,才会结束本次请求处理,发送响应

    不带此装饰器的请求在 get、post 等方法返回时自动完成结束请求处理

  • 协程异步

    import tornado.web import tornado.httpclient class IndexHandler(tornado.web.RequestHandler): @tornado.gen.coroutine def get(self): http = tornado.httpclient.AsyncHTTPClient() response = yield http.fetch("http://www.baidu.com") if response.error: self.send_error(500) else: print(response.body.decode('utf-8')) f = open('baidu.html', 'wb') f.write(response.body) f.close() self.write("操作成功")

    也可以将异步 Web 请求单独出来

    import tornado.web import tornado.httpclient class IndexHandler(tornado.web.RequestHandler): @tornado.gen.coroutine def get(self): rep = yield self.get_body_info("http://www.baidu.com") if rep['ret'] == 1: print(rep['body']) self.write("成功") @tornado.gen.coroutine def get_body_info(self, url): rep = {"ret":1} http = tornado.httpclient.AsyncHTTPClient() response = yield http.fetch(url) if response.error: rep = {"ret":0} else: rep['body'] = response.body.decode('utf-8') f = open('baidu.html', 'wb') f.write(response.body) f.close() self.write("操作成功") raise tornado.gen.Return(rep) # 此处需要注意

    代码中我们需要注意的地方是 get_body_info 返回值的方式,在 python 2 中,使用了 yield 的生成器可以使用不返回任何值的 return,但不能 return value,因此 Tornado 为我们封装了用于在生成器中返回值的特殊异常 tornado.gen.Return,并用 raise 来返回此返回值

  • 并行协程

    Tornado 可以同时执行多个异步,并发的异步可以使用列表或字典

    import tornado.web import tornado.httpclient class IndexHandler(tornado.web.RequestHandler): @tornado.gen.coroutine def get(self): self.urls = ["http://www.baidu.com","http://www.webometrics.info/en/Asia"] rep1, rep2 = yield [self.get_url_info(self.urls[0]), self.get_url_info(self.urls[1])] self.write_response(self.urls[0], rep1, 'baidu.html') self.write_response(self.urls[1], rep2, 'Asia.html') def write_response(self, url, response, name): self.write(url) self.write(":<br/>") if 1 == response["ret"]: f = open(name, 'wb') f.write(response['body']) f.close() self.write("操作成功") else: self.write("获取数据失败 <br/>") @tornado.gen.coroutine def get_url_info(self, url): rep = {"ret": 1} http = tornado.httpclient.AsyncHTTPClient() response = yield http.fetch(url) if response.error: rep = {"ret": 0} else: rep['body'] = response.body raise tornado.gen.Return(rep) # 此处需要注意

四、关于数据库的异步说明

网站基本都会有数据库操作,而 Tornado 是单线程的,这意味着如果数据库查询返回过慢,整个服务器响应会被堵塞

数据库查询,实质上也是远程的网络调用;理想情况下,是将这些操作也封装成为异步的;但 Tornado 对此并 没有 提供任何支持

这是 Tornado 的 设计,而不是缺陷

一个系统,要满足高流量;是必须解决数据库查询速度问题的!

数据库若存在查询性能问题,整个系统无论如何优化,数据库都会是瓶颈,拖慢整个系统!

异步并 不能 从本质上提到系统的性能;它仅仅是避免多余的网络响应等待,以及切换线程的 CPU 耗费。

如果数据库查询响应太慢,需要解决的是数据库的性能问题;而不是调用数据库的前端 Web 应用

对于实时返回的数据查询,理想情况下需要确保所有数据都在内存中,数据库硬盘 IO 应该为 0;这样的查询才能足够快;而如果数据库查询足够快,那么前端 web 应用也就无将数据查询封装为异步的必要

就算是使用协程,异步程序对于同步程序始终还是会提高复杂性;需要衡量的是处理这些额外复杂性是否值得

如果后端有查询实在是太慢,无法绕过,Tornaod 的建议是将这些查询在后端封装独立封装成为 HTTP 接口,然后使用 Tornado 内置的异步 HTTP 客户端进行调用

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-05-26发表,共计3259字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19351
评论数
4
阅读量
7997266
文章搜索
热门文章
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
自己手撸一个AI智能体—跟创业大佬对话

自己手撸一个AI智能体—跟创业大佬对话

自己手撸一个 AI 智能体 — 跟创业大佬对话 前言 智能体(Agent)已经成为创业者和技术人绕...
开发者福利:免费 .frii.site 子域名,一分钟申请即用

开发者福利:免费 .frii.site 子域名,一分钟申请即用

  开发者福利:免费 .frii.site 子域名,一分钟申请即用 前言 在学习 Web 开发、部署...
还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手!

还在找免费服务器?无广告免费主机,新手也能轻松上手! 前言 对于个人开发者、建站新手或是想搭建测试站点的从业者...
星哥带你玩飞牛NAS-11:咪咕视频订阅部署全攻略

星哥带你玩飞牛NAS-11:咪咕视频订阅部署全攻略

星哥带你玩飞牛 NAS-11:咪咕视频订阅部署全攻略 前言 在家庭影音系统里,NAS 不仅是存储中心,更是内容...
开源MoneyPrinterTurbo 利用AI大模型,一键生成高清短视频!

开源MoneyPrinterTurbo 利用AI大模型,一键生成高清短视频!

  开源 MoneyPrinterTurbo 利用 AI 大模型,一键生成高清短视频! 在短视频内容...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
自己手撸一个AI智能体—跟创业大佬对话

自己手撸一个AI智能体—跟创业大佬对话

自己手撸一个 AI 智能体 — 跟创业大佬对话 前言 智能体(Agent)已经成为创业者和技术人绕...
一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸

一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸

一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸 前言 作为天天跟架构图、拓扑图死磕的...
星哥带你玩飞牛NAS硬件 01:捡垃圾的最爱双盘,暴风二期矿渣为何成不老神话?

星哥带你玩飞牛NAS硬件 01:捡垃圾的最爱双盘,暴风二期矿渣为何成不老神话?

星哥带你玩飞牛 NAS 硬件 01:捡垃圾的最爱双盘,暴风二期矿渣为何成不老神话? 前言 在选择 NAS 用预...
恶意团伙利用 PHP-FPM 未授权访问漏洞发起大规模攻击

恶意团伙利用 PHP-FPM 未授权访问漏洞发起大规模攻击

恶意团伙利用 PHP-FPM 未授权访问漏洞发起大规模攻击 PHP-FPM(FastCGl Process M...
4盘位、4K输出、J3455、遥控,NAS硬件入门性价比之王

4盘位、4K输出、J3455、遥控,NAS硬件入门性价比之王

  4 盘位、4K 输出、J3455、遥控,NAS 硬件入门性价比之王 开篇 在 NAS 市场中,威...