使用原因

在一个实时通讯的项目中,由于需要使用Websocket这一协议,便在Python框架中选定了Tornado,也同时使用了Sqlalchemy这一ORM框架。
大家都知道Tornado有异步非阻塞特性,但Sqlalchemy是同步操作,这会大大影响性能,会影响的用户体验。
为了能解决这一问题,我便在网上搜寻资料,发现有使用Celery的,有使用run_on_executor装饰器的,甚至自己封装异步Sqlalchemy的等等方法。
由于缺少实践,我觉定对Celery、run_on_executor进行尝试

Celery

以下是官方文档的介绍:

Celery 是一个简单、灵活且可靠的,处理大量消息的分布式系统,并且提供维护这样一个系统的必需工具。
它是一个专注于实时处理的任务队列,同时也支持任务调度。
Celery 有广泛、多样的用户与贡献者社区,你可以通过 IRC 或是 邮件列表 加入我们。
Celery 是开源的,使用 BSD 许可证 授权。

官网地址:http://docs.jinkan.org/docs/celery/

安装环境

服务器:Ubuntu 12.04.5 LTS (GNU/Linux 3.2.0-67-generic x86_64)

  • 安装RabbitMQ

    • 安装RabbitMQ Server

      • sudo apt-get install rabbitmq-server
      • RabbitMQ提供了一些简单实用的命令用于管理服务器运行状态:
        查看服务器运行状态: enable rabbitmq_management
        启动服务器:rabbitmq-server start
        停止服务器:rabbitmq-server stop
        查看服务器中所有的消息队列信息 :rabbitmqctl list_queues
        查看服务器种所有的路由信息: rabbitmqctl list_exchanges
        查看服务器种所有的路由与消息队列绑定信息 :rabbitmq list_bindings
        * 启用WEB管理台

      1. /usr/lib/rabbitmq/bin
      1. sudo ./rabbitmq-plugins enable rabbitmq_management
      • 添加远程管理账户
        将下面配置写入/etc/rabbitmq/rabbitmq.conf.d/rabbitmq.config文件中
      1. [
      2. {rabbit, [{tcp_listeners, [5672]}, {loopback_users, ["ken"]}]}
      3. ].
      1. cd /usr/lib/rabbitmq/bin/
      1. sudo rabbitmqctl add_user ken 123456
      1. sudo rabbitmqctl set_user_tags ken administrator
      1. sudo rabbitmqctl set_permissions -p / ken ".*" ".*" ".*"
  • 安装Celery
    Celery详情查看官方文档

    • 使用pip安装
    1. pip install Celery

Celery方法示例

  • 新建一个task.py
  1. from celery import Celery
  2. celery = Celery('tasks', broker='amqp://')
  3. celery.conf.CELERY_RESULT_BACKEND = os.environ.get('CELERY_RESULT_BACKEND', 'amqp')
  4. @celery.task(name='task.db_operation')
  5. def db_operation(id):
  6. # 耗时的数据库操作
  7. pass
  • 使用worker参数执行我们的程序的task
  1. celery -A tasks worker --loglevel=info
  • 新建一个handler.py
  1. import tcelery
  2. tcelery.setup_nonblocking_producer()
  3. from tasks import db_operation
  4. calss Resource(RequestHandler):
  5. @asynchronous
  6. def get():
  7. # 参数通过args传递,回调通过callback指定
  8. db_operation.apply_async(args=[id], callback=self.on_success)
  9. def on_success(self, response):
  10. # 获取返回的结果
  11. resource = response.result
  12. self.write(resource)
  13. self.finish()

此时,Resource的Get请求已经变成异步非阻塞了。

run_on_executor方法示例

  • 新建一个handler.py
  1. from concurrent.futures import ThreadPoolExecutor
  2. from tornado.concurrent import run_on_executor
  3. class ChatHandler(web.RequestHandler):
  4. executor = ThreadPoolExecutor(4)
  5. @web.asynchronous
  6. @gen.coroutine
  7. def get(self):
  8. resource = yield self.get_db_operation()
  9. self.write(resource)
  10. self.finish()
  11. @web.asynchronous
  12. @gen.coroutine
  13. def post(self):
  14. yield self.post_db_operation()
  15. self.write('success')
  16. self.finish()
  17. @run_on_executor
  18. def get_db_operation(self):
  19. return resource
  20. @run_on_executor
  21. def post_db_operation(self):
  22. pass

总结

这一整套走下来,个人觉得使用Celery部署麻烦,而且一旦大量使用Celery,极有可能导致队列长度过长,影响处理效率。最后我选择使用了run_on_executor方法。

作者:KenHan
链接:https://www.jianshu.com/p/9eb901ad735b
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

对Tornado异步操作Sqlalchemy方法的选定 不错的更多相关文章

  1. 将Flask应用程序部署在nginx,tornado的简单方法

    来自:http://www.xuebuyuan.com/618750.html 在网上搜索了一下部署flask应用的方法,大部分是用wsgi部署在nginx上面,部署了很久,都没有成功,可能是我领悟能 ...

  2. Tornado—options.define()方法与options.options解读

    tornado为我们提供了一个便捷的工具,tornado.options模块——全局参数定义.存储.转换. tornado是facebook开源的非阻塞web容器,类似java的netty,torna ...

  3. 【Python】部署上手App后端服务器 - Linux环境搭建安装Python、Tornado、SQLAlchemy

    基于阿里云服务器端环境搭建 文章目录 基于阿里云服务器端环境搭建 配置开发环境 安装 Python 3.8.2 安装 Tornado 安装 MySQL 安装 mysqlclient 安装 SQLAlc ...

  4. 【转】Android下编译jni库的二种方法(含示例) -- 不错

    原文网址:http://blog.sina.com.cn/s/blog_3e3fcadd01011384.html 总结如下:两种方法是:1)使用Android源码中的Make系统2)使用NDK(从N ...

  5. jQuery on() 方法 为选定已存在元素和未来元素绑定标准事件和自定义事件

    很有必要说说jQuery的on方法,这个方法存在大乾坤大奥秘,主要注意两点: 1.为已存在元素和未来元素(动态添加元素)绑定处理函数. 2.自定义一个非标准的事件并绑定处理函数. 定义和用法 on() ...

  6. tornado 非阻塞方法

    http://sebastiandahlgren.se/2014/06/27/running-a-method-as-a-background-thread-in-python/

  7. 定义 iOS 方法名等不错的规范

    1.配置视图不应命名为 setxxxx, 而应叫做 showxxxx 2.让按钮高亮不应叫做 showxxx, 而应叫做 highlightedxxx. 3,弹出 toastView 可以用 show ...

  8. 回退(pop&present)到根页面(根控制器)的方法,很不错~

    http://blog.csdn.net/assholeu/article/details/45897035

  9. 《Introduction to Tornado》中文翻译计划——第五章:异步Web服务

    http://www.pythoner.com/294.html 本文为<Introduction to Tornado>中文翻译,将在https://github.com/alioth3 ...

随机推荐

  1. python3爬虫全国地址信息

    PHP方式写的一团糟所以就用python3重写了一遍,所以因为第二次写了,思路也更清晰了些. 提醒:可能会有502的错误,所以做了异常以及数据库事务处理,暂时没有想到更好的优化方法,所以就先这样吧.待 ...

  2. jQuery多功能日历插件 带事件记录功能

    在线演示 本地下载

  3. CSS3自定义发光radiobox单选框

    在线演示 本地下载

  4. BigDecimal相关整理

    bigdecimal类型四则运算: BigDecimal s = new Bigdecimal(5); BigDecimal x = new Bigdecimal(15); 依次为最基础的加减乘除: ...

  5. Hibernate的一级缓存、二级缓存和查询缓存。

    Hibernate的Session提供了一级缓存的功能,默认总是有效的,当应用程序保存持久化实体.修改持久化实体时,Session并不会立即把这种改变提交到数据库,而是缓存在当前的Session中,除 ...

  6. HTML中a标签的锚点

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. Mine_hibernate

    1. __z知识点\整理_归纳 ==> "ZC_归纳.txt" 和 "ZC_归纳__12_用Eclipse开发hibernate.txt" 2.

  8. IIS注册.NET

    IIS中ASP.NET的版本号此时可选的有1.1.2.0和4.0三个,如果想让IIS把3个版本都集成上,那NET Framework 3种都要安装,默认安装到的是C 盘. IIS注册方式如下:1.1: ...

  9. uva-11020-平衡树

    题目链接https://vjudge.net/problem/UVA-11020 白书例题,依次给出n个点的坐标,定义一个点为优势点当且仅当这个点的左下方区域不包含任何点(但可以与之完全重合):求每加 ...

  10. spring 多数据源动态切换

    理解spring动态切换数据源,需要对spring具有一定的了解 工作中经常遇到读写分离,数据源切换的问题,那么以下是本作者实际工作中编写的代码  与大家分享一下! 1.定义注解 DataSource ...