方式一:通过线程池或者进程池
导入库futures是python3自带的库,如果是python2,需要pip安装future这个库
备注:进程池和线程池写法相同
 from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor
from tornado.concurrent import run_on_executor def doing(s):
print('xiumian--{}'.format(s))
time.sleep(s)
return s class MyMainHandler(RequestHandler):
executor = ProcessPoolExecutor(2) #新建一个进程池,静态变量,属于类,所以全程只有这个几个进程,不需要关闭,如果放在__init__中,则属于对象,每次请求都会新建pool,当请求增多的时候,会导致今天变得非常多,这个方法不可取 @gen.coroutine
def get(self, *args, **kwargs):
print('开始{}'.format(self.pool_temp))
a = yield self.executor.submit(doing, 20)
print('进程 %s' % self.executor._processes)
self.write(str(a))
print('执行完毕{}'.format(a)) @run_on_executor #tornado 另外一种写法,需要在静态变量中有executor的进程池变量
def post(self, *args, **kwargs):
a = yield doing(20)
方式二:Tornado + Celery + RabbitMQ 实现
使用Celery任务队列,Celery 只是一个任务队列,需要一个broker媒介,将耗时的任务传递给Celery任务队列执行,执行完毕将结果通过broker媒介返回。官方推荐使用RabbitMQ作为消息传递,redis也可以
 
一、Celery 介绍:
1.1、注意:
1、当使用RabbitMQ时,需要按照pika第三方库,pika0.10.0存在bug,无法获得回调信息,需要按照0.9.14版本即可
2、tornado-celery 库比较旧,无法适应Celery的最新版,会导致报无法导入task Producter包错误,只需要将celery版本按照在3.0.25就可以了
 
1.2、关于配置:
单个参数配置:
  app.conf.CELERY_RESULT_BACKEND = 'redis://localhost:6379/0' 
多个参数配置:
 app.conf.update(
CELERY_BROKER_URL = 'amqp://guest@localhost//',
CELERY_RESULT_BACKEND = 'redis://localhost:6379/0'
)
从配置文件中获取:(将配置参数写在文件app.py中)
 BROKER_URL='amqp://guest@localhost//'
CELERY_RESULT_BACKEND='redis://localhost:6379/0'
app.config_from_object('celeryconfig')
 
 
二、案例
2.1、启动一个Celery 任务队列,也就是消费者:
 from celery import Celery
celery = Celery('tasks', broker='amqp://guest:guest@119.29.151.45:5672', backend='amqp') 使用RabbitMQ作为载体, 回调也是使用rabbit作为载体 @celery.task(name='doing') #异步任务,需要命一个独一无二的名字
def doing(s, b):
print('开始任务')
logging.warning('开始任务--{}'.format(s))
time.sleep(s)
return s+b
命令行启动任务队列守护进程,当队列中有任务时,自动执行 (命令行可以放在supervisor中管理)
--loglevel=info --concurrency=5
记录等级,默认是concurrency:指定工作进程数量,默认是CPU核心数
 
2.2、启动任务生产者
 import tcelery
tcelery.setup_nonblocking_producer() #设置为非阻塞生产者,否则无法获取回调信息 class MyMainHandler(RequestHandler): @web.asynchronous
@gen.coroutine
def get(self, *args, **kwargs):
print('begin')
result = yield gen.Task(sleep.apply_async, args=[10]) #使用yield 获取异步返回值,会一直等待但是不阻塞其他请求
print('ok--{}'.format(result.result)) #返回值结果 # sleep.apply_async((10, ), callback=self.on_success)
# print('ok -- {}'.format(result.get(timeout=100)))#使用回调的方式获取返回值,发送任务之后,请求结束,所以不能放在处理tornado的请求任务当中,因为请求已经结束了,与客户端已经断开连接,无法再在获取返回值的回调中继续向客户端返回数据 # result = sleep.delay(10) #delay方法只是对apply_async方法的封装而已
# data = result.get(timeout=100) #使用get方法获取返回值,会导致阻塞,相当于同步执行 def on_success(self, response): #回调函数
print ('Ok-- {}'.format(response))
 
 
 
 
 
 
 
 

Tornado 高并发源码分析之六---异步编程的几种实现方式的更多相关文章

  1. Tornado 高并发源码分析之四--- HTTPServer 与 TCPServer 对象

    主要工作: 服务器启动的时候做的事: 1.把包含了各种配置信息的 application 对象封装到了 HttpServer 对象的 request_callback 字段中,等待被调用 2.TCPS ...

  2. Tornado 高并发源码分析之五--- IOLoop 对象

    IOLoop主要工作 1.将TCPServer 注册到 IOLoop 的事件记到 _handlers 字段,同时注册 READ 和 ERROR 事件到 epoll 2.IOLoop 启动一个大循环,负 ...

  3. Tornado 高并发源码分析之三--- Application 对象

    Application 对象主要工作: 服务器启动时: 1.在新建一个app的时候,根据设置好的 URL 和回调函数 Handler 封装成URLSpec 对象   服务器运行时: 2.在请求到来,将 ...

  4. Tornado 高并发源码分析之二---Tornado启动和请求处理流程

    Tornado 服务器启动流程 因为Tornado 里使用了很多传类的方式,也就是delegate,之所以要这么做,其实和 iOS 开发那样,也很多的 delegate, 如此来实现高度解耦,但是比较 ...

  5. Tornado 高并发源码分析之一---启动一个web服务

    前言: 启动一个tornado 服务器基本代码 class HomeHandler(tornado.web.RequestHandler): #创建 RequesHandler 对象,处理接收到的 h ...

  6. ViewGroup事件分发源码分析

    1.AndroidStudio源码调试方式 AndroidStudio默认是支持一部分源码调试的,但是build.gradle(app) 中的sdk版本要保持一致, 最好是编译版本.运行版本以及手机的 ...

  7. v76.01 鸿蒙内核源码分析(共享内存) | 进程间最快通讯方式 | 百篇博客分析OpenHarmony源码

    百篇博客分析|本篇为:(共享内存篇) | 进程间最快通讯方式 进程通讯相关篇为: v26.08 鸿蒙内核源码分析(自旋锁) | 当立贞节牌坊的好同志 v27.05 鸿蒙内核源码分析(互斥锁) | 同样 ...

  8. 鸿蒙内核源码分析(内存分配篇) | 内存有哪些分配方式  | 百篇博客分析OpenHarmony源码 | v11.02

    百篇博客系列篇.本篇为: v11.xx 鸿蒙内核源码分析(内存分配篇) | 内存有哪些分配方式 | 51.c.h .o 内存管理相关篇为: v11.xx 鸿蒙内核源码分析(内存分配篇) | 内存有哪些 ...

  9. Java 异步编程的几种方式

    前言 异步编程是让程序并发运行的一种手段.它允许多个事情同时发生,当程序调用需要长时间运行的方法时,它不会阻塞当前的执行流程,程序可以继续运行,当方法执行完成时通知给主线程根据需要获取其执行结果或者失 ...

随机推荐

  1. LeetCode OJ:Remove Element(移除元素)

    Given an array and a value, remove all instances of that value in place and return the new length. T ...

  2. DRF 的 版本,解析器,与序列化

    DRF 的 版本,解析器,与序列化 补充 配置文件中的 类的调用: (字符串) v1 = ["view.xx.apth.Role","view.xx.apth.Role& ...

  3. 高性能高并发服务器架构设计探究——以flamigo服务器代码为例

    这篇文章我们将介绍服务器的开发,并从多个方面探究如何开发一款高性能高并发的服务器程序. 所谓高性能就是服务器能流畅地处理各个客户端的连接并尽量低延迟地应答客户端的请求:所谓高并发,指的是服务器可以同时 ...

  4. 从零开始编写深度学习库(五)Eigen Tensor学习笔记2.0

    1.extract_image_patches函数的使用: 假设Eigen::Tensor形状为(3,8,8,9),现在要对第二维.第三维根据size大小为(2,2),stride=(2,2),那么如 ...

  5. JFinal自定义FreeMarker标签

    为什么采用freemarker? 1.模板技术,不依附于语言和框架,前端和后端解耦,便于分工协作,更好的协同. 2.页面相应速度快 3.前端非常的灵活,采用自定义标签可以在不更改后端的基础上很容易的构 ...

  6. 分布式缓冲之memcache

    1. memcache简介 memcache是danga.com的一个项目,它是一款开源的高性能的分布式内存对象缓存系统,,最早是给LiveJournal提供服务的,后来逐渐被越来越多的大型网站所采用 ...

  7. Java Config 注解

    java config是指基于java配置的spring.传统的Spring一般都是基本xml配置的,后来spring3.0新增了许多java config的注解,特别是spring boot,基本都 ...

  8. JsQuick--个人封装的Js库

    JsQuick 该库为本人封装的Js库,尚未进行浏览器兼容 /** * 快速框架 版本:1.0.0 * 日期:2015.02.26 * 作者:简楚恩 */ /** * 快速获取控件类 */ var $ ...

  9. Pod Installing openssl-ios-bitcode报错

    pod update --no-repo-update 问题:执行上面的操作之后,pod在安装ssl的时候会报错.部分报错信息如下: localhost:OpenSSLTest Later$ pod ...

  10. ASM概述

    ASM的全称是 Automatic Storage Management,ASM 是为存放oracle 数据文件而设计的一个volume manager 和 文件系统 管理的技术. ASM 支持ora ...