简体   繁体   English

龙卷风真的没有阻挡吗?

[英]Is Tornado really non-blocking?

Tornado advertises itself as "a relatively simple, non-blocking web server framework" and was designed to solve the C10k problem. Tornado宣称自己是“一个相对简单, 无阻塞的 Web服务器框架”,旨在解决C10k问题。 However, looking at their database wrapper, which wraps MySQLdb, I came across the following piece of code: 但是,看看包装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

As far as I know calls to the MySQLdb, which is built on top of libmysqlclient , are blocking. 据我所知,对libmysqlclient构建的MySQLdb的调用是阻塞的。

Am I right in thinking that a long-running query would render the entire Tornado server unresponsive until it finishes or is there magic on the code? 我是否正确地认为长时间运行的查询会导致整个Tornado服务器无响应直到它完成或代码上有魔力?

Tornado is non-blocking if you write non-blocking code on the top if it, eg. 如果你在顶部编写非阻塞代码,龙卷风是非阻塞的,例如。 using asyncmongo and @tornado.web.asynchronous decorator. 使用asyncmongo@ tornado.web.asynchronous装饰器。 Tornado as a framework provides tools for that. 作为框架的龙卷风为此提供了工具。

Bret Taylor, one of the original authors, writes : 原作者之一布雷特泰勒写道

We experimented with different async DB approaches, but settled on synchronous at FriendFeed because generally if our DB queries were backlogging our requests, our backends couldn't scale to the load anyway. 我们尝试了不同的异步数据库方法,但在FriendFeed上确定了同步,因为通常如果我们的数据库查询正在对请求进行积压,那么我们的后端无论如何都无法扩展到负载。 Things that were slow enough were abstracted to separate backend services which we fetched asynchronously via the async HTTP module. 那些足够慢的东西被抽象为分离后端服务,后端服务是我们通过异步HTTP模块异步获取的。

It's true that Tornado doesn't include a non-blocking database layer; 确实,Tornado不包含非阻塞数据库层; in fact the database layer is not integral part of the Tornado framework at all, as opposed to eg Django's ORM. 事实上,数据库层根本不是Tornado框架的组成部分,而不是像Django的ORM。 Yes, Tornado ships with blocking MySQL wrapper because that's what FriendFeed happened to use, but it's more an external library than core functionality. 是的,Tornado附带阻止MySQL包装器,因为这是FriendFeed碰巧使用的东西,但它更像是一个外部库而不是核心功能。 I'm pretty sure most people are using something else for database access. 我很确定大多数人都在使用其他东西进行数据库访问。

Yes, absent other measures, the server will wait for the query to finish executing. 是的,如果没有其他措施,服务器将等待查询完成执行。 That does not mean Tornado is not a non-blocking web server. 这并不意味着Tornado不是一个非阻塞的Web服务器。

A "non-blocking web server" doesn't block on network I/O (and may have some provision for disk I/O if it does static file serving). “非阻塞Web服务器”不会阻塞网络I / O(如果它执行静态文件服务,则可能有一些磁盘I / O设置)。 That does not mean you get instant, causality-violating instruction execution in your application. 这并不意味着您在应用程序中会立即执行违反因果关系的指令。

Doing a database call takes time, just like reading files, formatting strings, processing templates, etc. takes time. 执行数据库调用需要时间,就像读取文件,格式化字符串,处理模板等需要时间。 Doing any of these things in the same thread as the server's main event loop will prevent the loop from moving on until you're done. 在与服务器的主事件循环相同的线程中执行任何这些操作将阻止循环继续前进,直到完成为止。

Tornado is nonblocking ,but just limited to some IO operation like read or write to a socket file. Tornado是非阻塞的 ,但仅限于某些IO操作,如读取或写入套接字文件。

if you want everything in your code nonblocking,you have to design by yourself.but if your code is computation intensively, then nonblocking is meaningless for you. 如果你希望代码中的所有内容都是非阻塞的,你必须自己设计。但如果你的代码是计算密集的,那么非阻塞对你来说毫无意义。 this situation you might use multi-process. 这种情况你可能会使用多进程。

remember one thing nonblocking just mean the server send/receive date won't blocking. 记住一件事非阻塞只是意味着服务器发送/接收日期不会阻塞。 If you can't make your code nonblocking,then your whole application is someway blocking. 如果你不能使你的代码无阻塞,那么你的整个应用程序就会阻塞。

Yes; 是; this is not a fully non-blocking web server at all. 这根本不是一个完全无阻塞的Web服务器。

A non-blocking webserver doesn't block, using non-blocking APIs for file I/O, database access, and so on, to ensure that one request that has to wait for something to finish doesn't prevent other requests from being processed. 非阻塞Web服务器不阻止,使用非阻塞API进行文件I / O,数据库访问等,以确保一个必须等​​待完成某事的请求不会阻止处理其他请求。 This applies to everything that might block the server, including database access. 这适用于可能阻止服务器的所有内容 ,包括数据库访问。

There's nothing as silly as "causality violation" in having non-blocking database access; 在使用非阻塞数据库访问时,没有像“因果关系违规”那样愚蠢的事情; it makes perfect sense to run a non-blocking query related to one request, and to process other requests while that's still running. 运行与一个请求相关的非阻塞查询,并在仍在运行时处理其他请求,这是完全合理的。 In practice, this will usually mean making multiple connections to the database backend. 实际上,这通常意味着与数据库后端建立多个连接。

Note that if you're trying to run ten thousand concurrent requests, be careful: most database backends can't cope with this. 请注意,如果您尝试运行一万个并发请求,请注意:大多数数据库后端无法应对此问题。 If you have more than a few dozen database requests to run in parallel, you probably want something like a connection pooler, to allow the web server to make lots of database connections without swamping the backend. 如果您有多个数据库请求并行运行,您可能需要类似连接池的东西,以允许Web服务器在不淹没后端的情况下建立大量数据库连接。 This will cause requests to block, waiting in a queue to get database access, but doing it this way means it's not blocking the whole server--just the requests that need the database. 这将导致请求阻塞,在队列中等待获取数据库访问权限,但这样做意味着它不会阻塞整个服务器 - 只需要阻止需要数据库的请求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM