龙卷风异步基本概念

时间:2015-06-06 21:54:10

标签: python tornado

我试图理解龙卷风和异步的一些概念。如果我们有两个会话X和Y连接到Tornado服务器T.

现在假设X执行阻塞10秒的数据库写入。在那个时期,Y从T请求一些东西。在服务之前,T必须等到X完成写入吗?

我认为龙卷风会产生两个实例,并将它们分别从X切换到Y?

2 个答案:

答案 0 :(得分:2)

tornado是否可以异步方式处理数据库连接取决于您正在使用的数据库库。对于要异步执行的数据库查询,他们必须使用Tornado的IOLoop,否则Tornado会在发送数据库查询并收到响应时阻塞。

因此,在您的示例中,如果数据库库不使用底层的Tornado IOLoop,则X将阻塞10秒,并且在X中的数据库写入完成后将执行Y(以及任何其他请求),但是如果数据库库执行使用Tornado IOLoop并将X实现为异步处理程序,在执行数据库写入时产生Y,可以处理Y,而Tornado的IOLoop等待数据库对X的写入db请求的响应。

作为MongoDB的一个例子,我有一些ORM库,我用过Tornado,MotorEngine(https://motorengine.readthedocs.org)和MongoEngine(https://mongoengine-odm.readthedocs.org)。 MongoEngine不使用Tornado IOLoop,因此所有调用都是阻塞的,MotorEngine确实使用IOLoop,因此您可以编写不阻塞的查询。

还有其他方法可以处理长时间运行的任务(过去我已经设置了额外的Web服务,并使用AsyncHTTPClient调用它们,我还使用了Celery之类的任务调度程序来推动处理进入后台,经常到另一台服务器)。根据我的经验,数据库查询很少是瓶颈,一个好的经验法则是尽量确保尽可能快地保存它们,如果你不能希望我的答案是有用的。

<强>重新。我以为龙卷风会产生两个实例并分别处理从X切换到Y?

Tornado不会产生多个实例来处理其他请求,你可以运行Tornado的多个实例(实际上根据我的经验和Tornado文档中的示例 - 这是可取的)。

答案 1 :(得分:1)

Tornado将作为单线程运行,并根据套接字事件在请求之间快速切换。如果写得正确,这是一种非常快速的服务请求方式,也就是Node.js的工作方式。

但是,在处理请求时,您需要确保操作的 none 阻塞,否则您将阻止整个线程,从而阻止整个龙卷风服务器。

您必须仅将Tornado与异步调用一起使用。例如,如果您正在发出http请求,则无法使用传统的阻止HTTP客户端。幸运的是,Tornado为您提供了一个内置的异步库:

http://tornado.readthedocs.org/en/latest/httpclient.html

def handle_request(response):
    if response.error:
        print "Error:", response.error
    else:
        print response.body

http_client = AsyncHTTPClient()

# this line does not block! it immediately returns and you get the result later.
http_client.fetch("http://www.google.com/", handle_request)
  

现在假设X执行阻塞10秒的数据库写入。

与HTTP请求类似,您的数据库查询也不能阻止。在这种情况下,您将需要使用异步MySQL库,该库在您发起请求时立即返回,并在稍后的某个回调中返回结果。

以下是您可以使用的一个潜在库:

https://github.com/PyMySQL/Tornado-MySQL

Node.js非常受这种单线程范式的欢迎,因为最初Node.js最多只支持一个线程,所以所有官方数据库库,http库默认都是异步的。使用Python,您需要挖掘多个(有时是非官方的)库来自己找到异步库。

修改

正如Anthony所提到的,如果您的数据库查询/写入速度很快(小于10毫秒),那么您应该可以进行阻止请求。任何事情都结束了,你的表现开始受到影响。