Tornado是一个异步框架,在异步操作的时候能提升程序的处理性能。但是如果在程序中碰到同步的逻辑,由于GIL的关系,会直接卡死,导致性能急剧下降。
目前对于mongodb以及redis都有比较不错的异步框架,但是对于Mysql,目前的异步框架都不是很成熟。
在实际应用中,由于一开始不是特别了解,在用了Tornado框架的同时,采用了Sqlalchemy来处理Mysql数据。但是由于这部分Mysql操作是同步的,在并发量上去的时候,不能及时返回,大量请求被拒绝。
由于替换Sqlalchemy会造成很大的工作量,经过研究之后发现Tornado有run_on_executor,可以利用线程池达到异步化的目的。
Decorator to run a synchronous method asynchronously on an executor.
The decorated method may be called with a callback keyword argument and returns a future.
The IOLoop and executor to be used are determined by the io_loop and executor attributes of self. To use different attributes, pass keyword arguments to the decorator
#!/bin/env python
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.httpclient
import tornado.gen
from tornado.concurrent import run_on_executor
# 这个并发库在python3自带;在python2需要安装sudo pip install futures
from concurrent.futures import ThreadPoolExecutor
import time
from tornado.options import define, options
define("port", default=8002, help="run on the given port", type=int)
class SleepHandler(tornado.web.RequestHandler):
executor = ThreadPoolExecutor(2)
def get(self):
tornado.ioloop.IOLoop.instance().add_callback(self.sleep) # 这样将在下一轮事件循环执行self.sleep
self.write("when i sleep")
@run_on_executor
def sleep(self):
time.sleep(5)
print("yes")
return 5
if __name__ == "__main__":
tornado.options.parse_command_line()
app = tornado.web.Application(handlers=[
(r"/sleep", SleepHandler), ])
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
当然也可以用celery来达到异步的效果,但是不如run_on_executor来的方便
---------------------
作者:harleylau
来源:CSDN
原文:https://blog.csdn.net/harleylau/article/details/77899148
版权声明:本文为博主原创文章,转载请附上博文链接!