`

聊聊 tornado 的异步回调

阅读更多

异步回调程序的原理和写法我不就不介绍了,因为我主要是来吐槽下这种代码风格的。

 

最近因为追求性能所以去看了下tornado,然后发现这货如果你要利用它的高性能 ,那么你就要写回调代码,跟twisted一样,各种callback。

 

我们正常的同步代码一般是这样的

 

 

res = db.query(...)
res2 = dosomething(res)
res3 = db.insert(...)
return res3

 

 

 

上面的代码共四行,2次数据库操作,一次数据处理最后返回想要的结果。逻辑很清晰也很易懂,我想大部分的程序都是这样的。但如如果是异步的写法就会这么写

 

 

db.query(...,callback=fun2)

def fun2(res):
    res2 = dosomething(res,callback=fun3)

def fun3(res):
    db.insert(...,callback=fun4)

 

 

异步的代码就是只要你涉及到阻塞的代码就需要使用回调,呵呵,看到了吧2次阻塞就要求你把一段代码写成3段,代码易读性直线下降,如果你只是做一些简单的功能,代码也不多,我觉得还是能接受的,毕竟性能真的好,但是如果你要做一个很大的项目,一个请求可能要做4,5次阻塞操作,不敢想象,简直就是个灾难。

 

不过好在tornado还给了我们另一条活路,那就是tornado.gen http://www.tornadoweb.org/documentation/gen.html。

 

简单点说就是gen 给了我们用同步代码来做异步实现的可能。

 

我们来看看gen和普通异步代码。

class BaseHandler(tornado.web.RequestHandler):
    @property
    def db(self):
        if not hasattr(self, "_db"):
            self._db = asyncmongo.Client(pool_id='test_pool', **settings.get('mongo_database'))
        return self._db
    
    def api_response(self, data):
        """将数据转成json返回给客户端"""
        self.set_header("Content-Type", "application/json; charset=UTF-8")
        data = dumps(data)
        self.finish(data)

class A(BaseHandler):
    """
    同步代码实现异步
    """
    @tornado.web.asynchronous
    @gen.engine
    def get(self):
        res = self.get_user()
          
    @tornado.web.asynchronous
    @gen.engine
    def get_user(self):
        user_id = 'asdf'+str(random.randrange(1,490000)) #随机产生一个数据库里有的用户
        res = yield gen.Task(self.db.user.find,{'name':user_id},limit=1)
        res=res[0][0][0]
        self.api_response(res)
        
class B(BaseHandler):
    """
    异步代码
    """
    @tornado.web.asynchronous
    def get(self):
        user_id = 'asdf'+str(random.randrange(1,490000))#随机产生一个数据库里有的用户
        self.db.user.find({ 'name': user_id }, callback=self.async_callback(self.finish_save))
    
    def finish_save(self, response, error):
        self.api_response(response[0])

 

最后的最后我分别测试了2中写法最后在性能上的结果,我用ab -n 10000 -c 200  做了测试

 

gen 的代码 用了7秒

普通的异步代码  用了6.3秒

 

我觉得gen 略慢吧,但还是在可接受范围内,毕竟我不用写你妹的回调了。。。。怨念

 

 

当然 如果大家不是写web 就直接用gevent 吧,连这些gen的装饰器都可以省了。

 

分享到:
评论

相关推荐

    trequests, python 请求的Tornado 异步 http/https客户端适配器.zip

    trequests, python 请求的Tornado 异步 http/https客户端适配器 trequests 用于python请求的Tornado 异步 http/https客户端适配器。问题enjoy 使用来构建快速阻止网络应用程序,希望使用库中库,并希望使用库中库,...

    tornado-redis:简单的异步 Tornado-redis 连接器

    2. **IOLoop(事件循环)**:Tornado的IOLoop是事件驱动的,负责监听各种事件(如读写事件),并在事件发生时调用相应的回调函数。Tornado-Redis利用IOLoop来处理与Redis服务器的连接,确保在等待响应时不会阻塞其他...

    Tornado上传和下载文件(以CSV文件为例).7z

    在Python的Web开发框架中,Tornado是一个轻量级且高性能的选择,尤其在处理异步I/O和长连接方面表现出色。本主题将探讨如何在Tornado中实现文件的上传和下载功能,以CSV文件为例。我们将从以下几个方面展开讨论: 1...

    tornado_apns, 在PyAPNS上,基于 Tornado的异步 APNS.zip

    tornado_apns, 在PyAPNS上,基于 Tornado的异步 APNS tornado_apns用于与苹果推送通知服务( APNs ) 进行 Tornado 异步编程的python 库示例用法import timefrom apns import APNs, Payloadfrom

    tornado官方翻译文档

    15. 异步回调异常处理:tornado.stack_context模块提供了在异步回调中处理异常的方法。 16. 异步代码单元测试:tornado.testing模块提供了进行异步代码单元测试的工具。 Tornado的安装方式非常简单,可以通过pip或...

    tornado-asyntool:一个简单的工具让 tornadoweb 异步运行代码

    在传统的编程模式中,编写异步代码往往需要处理回调函数或者使用协程等高级特性,这可能会增加代码的复杂性。而 Asyntool 通过提供简洁的接口,降低了异步编程的门槛。 在 Tornado Asyntool 中,你可以轻松创建和...

    tornado 框架 -python web 异步

    Tornado 是一个强大的 Python Web 开发框架,以其高性能和异步网络I/O闻名。它最初由 FriendFeed 团队开发,后来被 Facebook 收购并开源。Tornado 的设计目标是处理大量的并发连接,尤其适合长连接和实时Web应用,如...

    tornado 4.0.1 python framework guide

    **5.7 tornado.stack_context — 跨异步回调的异常处理** `tornado.stack_context` 模块提供了一种机制,用于在异步环境中正确处理异常,避免了异常传播过程中可能出现的问题。 **5.8 tornado.testing — 异步代码...

    AsyncTorndb, 用于 Tornado的异步mysql客户端.zip

    AsyncTorndb, 用于 Tornado的异步mysql客户端 AsyncTorndb ( 非活动)面向 Tornado的异步mysql客户端,基于 PyMySQL 。文档AsyncTorndb行为几乎与torndb行为相似,但异步。 请参考 torndb 并尝试。要求使用最新版本的...

    tornado-asyc-requests:使用 PostgreSQL 进行 Tornado 异步数据库请求的小演示

    Tornado 异步请求演示Tornado 和 PostgreSQL 异步请求的演示应用程序。要求龙卷风桃子psycopg2跑步$ python app.py设置要使用数据设置测试表,请将浏览器定位到用法只需打开浏览器并将浏览器定位到 ,其中 1 是用于...

    python基于Tornado实现,系统核心调度,可分布式扩展

    通过这种方式,我们可以编写出复杂的异步逻辑,而无需嵌套回调,使代码更易于理解和维护。 分布式扩展通常涉及将任务拆分到多个节点上,以处理更大规模的工作负载。在Python和Tornado中,可以使用如RabbitMQ、Kafka...

    Tornado教程.pdf

    Tornado 的异步模型基于 Python 的回调函数,利用 `IOLoop`(事件循环)进行调度。开发者可以定义回调函数,当特定的网络事件发生时,这些回调会被调用。例如: ```python import tornado.ioloop import tornado....

    tornado中文

    Tornado 支持异步编程模型,开发者可以利用回调函数、协程等机制来编写非阻塞的代码。这种方式不仅可以提高程序的执行效率,还能简化复杂的异步逻辑处理。 #### 三、Tornado 的核心概念 ##### 3.1 应用对象 ...

    tornado实战之一

    通过使用`asyncio`或`tornado.gen`模块,你可以编写非阻塞的回调函数,以处理I/O密集型任务,如数据库查询或网络调用。例如: ```python from tornado import gen from tornado.web import asynchronous class ...

    tornado docs.pdf

    Tornado是一个Python编写的开源网络框架和异步网络库,最初由FriendFeed开发。Tornado以其非阻塞网络I/O和可扩展性而闻名,能够支持数以万计的开放连接,非常适合需要与每个用户维持长期连接的应用程序,比如长轮询...

    rechat:RethinkDB + Tornado 异步聊天

    RethinkDB + Tornado 聊天演示 使用 Async RethinDB Driver ,带有更改提要和 Longpolling。 更改提要使 #这个怎么运作 当新的聊天消息到达时,它会被插入到events表中,RethinkDB 会自动通知 changfeed 监听器。 ...

    在tornado2.2.1下可以工作的sqlite3.7.17

    为了在Tornado中正确使用SQLite,需要使用非阻塞I/O,如通过异步回调、协程(如使用`asyncio`库)或Tornado的`Future`对象来实现。 3. **连接管理**:在高并发环境中,应谨慎管理SQLite连接,避免过多打开和关闭...

    Tornado使用指南(中文版)

    Tornado是一款高性能、异步网络库,最初由FriendFeed开发,后被Facebook收购并开源。它以其非阻塞I/O模型和Web服务器能力在Python社区中广受欢迎,尤其适用于高并发场景。Tornado不仅是一个Web框架,还包含了一个...

    Tornado实战Demo全集

    在IT行业中,Python是一种广泛应用的编程语言,而Tornado是一个基于Python的Web服务器框架和异步网络库。这个“Tornado实战Demo全集”显然是一份面向初学者的资源,旨在帮助他们深入理解和掌握Tornado框架,特别是其...

    Python的Tornado框架实现异步非阻塞访问数据库的示例

    Python的Tornado框架是一款强大的Web服务框架,以其异步非阻塞I/O模型而闻名,这使得它在处理高并发请求时表现出色。Tornado框架结合了Web服务器、模板渲染和HTTP客户端等功能,并且可以与多种数据库进行交互,如本...

Global site tag (gtag.js) - Google Analytics