我想了解一些龙卷风和异步的概念。如果我们有两个连接到Tornado服务器T的会话X和Y.龙卷风异步基本概念
现在假设X执行阻塞10秒的数据库写入。在那个时期,Y从T请求一些东西。T在服务之前是否必须等待X完成写操作?
我以为龙卷风会产生两个实例并分别将它们从X切换到Y?
我想了解一些龙卷风和异步的概念。如果我们有两个连接到Tornado服务器T的会话X和Y.龙卷风异步基本概念
现在假设X执行阻塞10秒的数据库写入。在那个时期,Y从T请求一些东西。T在服务之前是否必须等待X完成写操作?
我以为龙卷风会产生两个实例并分别将它们从X切换到Y?
龙卷风是否可以以异步方式处理数据库连接取决于您正在使用的数据库库。对于异步执行的数据库查询,他们必须使用Tornado的IOLoop,如果他们不这样做,则在发送数据库查询并收到响应时,Tornado将会阻塞。
因此,在您的示例中,如果数据库库不使用底层Tornado IOLoop,那么X会阻塞10秒,并且在数据库写入X后完成Y(和任何其他请求),但是如果数据库库使用Tornado IOLoop并将X实现为执行数据库写入时产生的异步处理程序,则可以在Tornado的IOLoop等待来自数据库的X写入数据库请求响应时处理Y.
作为MongoDB的一个例子,我已经使用了两个ORM库与Tornado,MotorEngine(https://motorengine.readthedocs.org)和MongoEngine(https://mongoengine-odm.readthedocs.org)。 MongoEngine不使用Tornado IOLoop,因此所有调用都被阻止,MotorEngine使用IOLoop,因此您可以编写不会阻止的查询。
还有其他方法可以处理长时间运行的任务(在过去,我已经设置了其他Web服务并使用AsyncHTTPClient
来调用它们,我还使用了Celery等任务调度程序将处理推入后台,通常在另一台服务器上)。然而,根据我的经验,数据库查询几乎不是瓶颈,而一个好的经验法则是尽可能快地确保它们尽可能快,如果你不能希望我的答案有用。
Re。我认为龙卷风会产生两个实例并分别将它们从X切换到Y?
龙卷风不产卵多个实例来处理额外的请求,您可以运行龙卷风的多个实例(在我的经验,每个在龙卷风文档的例子 - 事实上,这是明智的)。
Tornado将作为单线程运行,并在基于套接字事件的请求之间快速切换。如果编写正确,这是一种处理请求的非常快速的方式,并且是Node.js的工作原理。
但是,您需要确保无您的操作在处理请求时处于阻塞状态,否则将阻止整个线程,从而阻塞整个龙卷风服务器。
您必须只能与异步调用一起使用Tornado。例如,如果您发出http请求,则不能使用传统的阻止HTTP客户端。幸运的是龙卷风提供了一个内置的异步库为您提供:
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你需要挖掘多个(有时是非官方的)库来自己找到异步的库。
编辑:
正如安东尼所说,如果你的数据库查询/写操作快(小于10ms),你应该和作出禁止请求确定。任何结束,你的表现开始受到影响。
感谢您的马林你的答案充分回答了我的问题。干杯 –
感谢您的回复安东尼,有道理,我会寻找与MongoDB使用电机。我想我会把我的编程问题保存到另一个帖子;)干杯 –