龙卷风真的没有阻挡吗?

时间:2010-09-03 19:16:01

标签: python mysql tornado nonblocking

Tornado将自己宣传为“一个相对简单,非阻塞 Web服务器框架”,旨在解决C10k问题。但是,查看包装MySQLdb的数据库包装器,我遇到了以下代码:

def _execute(self, cursor, query, parameters):
    try:
        return cursor.execute(query, parameters)
    except OperationalError:
        logging.error("Error connecting to MySQL on %s", self.host)
        self.close()
        raise

据我所知,调用建立在libmysqlclient之上的MySQLdb,正在阻止。

我是否正确地认为长时间运行的查询会导致整个Tornado服务器无法响应,直到它完成或代码上有魔力?

4 个答案:

答案 0 :(得分:33)

如果您在顶部编写非阻塞代码,则Tornado是非阻塞的,例如。使用asyncmongo@tornado.web.asynchronous装饰器。作为框架的龙卷风为此提供了工具。

布雷特·泰勒,原作者之一,writes

  

我们尝试了不同的异步数据库方法,但已经确定了   在FriendFeed同步,因为通常我们的数据库查询是   积压我们的请求,我们的后端无法扩展到负载   无论如何。足够缓慢的东西被抽象化以分开   我们通过异步HTTP异步获取的后端服务   模块。

Tornado确实不包含非阻塞数据库层;事实上,数据库层根本不是Tornado框架的组成部分,而不是例如Django的ORM。是的,Tornado附带阻止MySQL包装器,因为这是FriendFeed碰巧使用的东西,但它更像是一个外部库而不是核心功能。我很确定大多数人都在使用其他东西进行数据库访问。

答案 1 :(得分:15)

是的,如果没有其他措施,服务器将等待查询完成执行。这并不意味着Tornado不是一个非阻塞的Web服务器。

“非阻塞Web服务器”不会阻塞网络I / O(如果它执行静态文件服务,则可能有一些磁盘I / O配置)。这并不意味着您在应用程序中会立即执行违反因果关系的指令。

执行数据库调用需要时间,就像读取文件,格式化字符串,处理模板等需要时间。在与服务器的主事件循环相同的线程中执行任何这些操作将阻止循环继续前进,直到完成为止。

答案 2 :(得分:1)

Tornado是非阻塞的,但仅限于某些IO操作,例如读取或写入套接字文件。

如果您希望代码中的所有内容都是非阻塞的,那么您必须自己设计。但如果您的代码是计算密集型的,那么非阻塞对您来说毫无意义。这种情况你可能会使用多进程。

记住一件事非阻塞只是意味着服务器发送/接收日期不会阻塞。如果你不能使代码无阻塞,那么你的整个应用程序就会阻塞。

答案 3 :(得分:0)

是;这根本不是一个完全无阻塞的Web服务器。

非阻塞Web服务器不阻止,使用非阻塞API进行文件I / O,数据库访问等,以确保一个必须等​​待某些事情完成的请求不会阻止其他请求从被处理。这适用于可能阻止服务器的所有,包括数据库访问。

在使用非阻塞数据库访问时,没有像“因果关系违规”那样愚蠢的事情;运行与一个请求相关的非阻塞查询,并在仍在运行时处理其他请求,这是完全合理的。实际上,这通常意味着与数据库后端建立多个连接。

请注意,如果您尝试运行一万个并发请求,请注意:大多数数据库后端都无法应对此问题。如果您有多个数据库请求并行运行,您可能需要类似连接池的东西,以允许Web服务器在不淹没后端的情况下建立大量数据库连接。这将导致请求阻塞,在队列中等待获取数据库访问权限,但这样做意味着它不会阻塞整个服务器 - 只需要数据库的请求。