Tornado 執行緒池應用
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
版權宣告:本文為博主原創文章,轉載請附上博文連結!