通常,RDBMS驱动程序是阻塞的,而Tornado是非阻塞服务器。这导致在执行CRUD操作时不合理地使用异步,因为IOLoop将被阻塞,直到该SQL查询完成。
我正在做一个项目,它使用RDBMS作为DB (因为ACID),但它也需要Websockets来编排一些奇特的功能(即推送通知),经过一些谷歌搜索后,我正在考虑使用Tornado,因为通常的REST和Websockets都可以在一个应用程序中实现。
浏览网页时,我发现了以下代码片段(此处:https://gist.github.com/methane/2185380):
import time
from tornado.concurrent import run_on_executor
from concurrent.futures import ThreadPoolExecutor # `pip install futures` for python2
MAX_WORKERS = 4
class Handler(tornado.web.RequestHandler):
executor = ThreadPoolExecutor(max_workers=MAX_WORKERS)
@run_on_executor
def background_task(self, i):
""" This will be executed in `executor` pool. """
time.sleep(10)
return i
@tornado.gen.coroutine
def get(self, idx):
""" Request that asynchronously calls background task. """
res = yield self.background_task(idx)
self.write(res)它基本上所做的是将CRUD任务推送到一个单独的线程。我的问题是:当使用异步HTTP服务器时,这是处理阻塞RDBMS驱动程序的默认方法吗?有没有其他方法可以最小化这些阻塞瓶颈?在异步服务器上使用阻塞RDBMS驱动程序是否合理?
发布于 2016-07-14 11:08:02
在Tornado中有多种处理RDBMS的方法。
在Tornado中有一些用于各种数据库的库,用于异步执行它们。https://github.com/tornadoweb/tornado/wiki/Links
您还可以使用GEvent在Tornado中获得异步数据库访问权限。
另一种选择是将Python3异步io库与Tornado一起使用,例如:https://aiopg.readthedocs.io/en/stable/
正如您所提到的,另一种选择是将DB工作负载转移到其他地方。你可以使用像ZeroMQ或RabbitMQ这样的消息队列,多线程,多进程,到另一个机器上的应用编程接口。
你也可以使用标准的阻塞数据库访问机制,它们在Tornado中仍然有效,它们只是阻塞直到它们返回,这可能是一个问题,也可能不是问题。
去年我在PyOhio上做了一次关于Momoko,Aiopg和GEvent的演讲:http://pyvideo.org/video/3698/from-synchronous-to-asynchronous-postgres-with-to
https://stackoverflow.com/questions/38353805
复制相似问题