Подтвердить что ты не робот

Действительно ли Торнадо не блокирует?

Tornado рекламирует себя как "относительно простую, неблокирующую структуру веб-сервера" и был разработан для решения проблемы 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

Насколько я знаю, вызовы MySQLdb, которые построены поверх libmysqlclient, блокируются .

Правильно ли я думаю, что долговременный запрос сделает весь сервер Tornado безответственным до тех пор, пока он не завершится или не будет волшебным кодом?

4b9b3361

Ответ 1

Да, при отсутствии других мер сервер будет ожидать завершения выполнения запроса. Это не означает, что Tornado не является неблокирующим веб-сервером.

"Неблокирующий веб-сервер" не блокирует сетевые операции ввода-вывода (и может иметь некоторое положение для дискового ввода-вывода, если он выполняет статический файл). Это не означает, что вы получаете мгновенное, нарушающее казуальность выполнение инструкции в своем приложении.

Выполнение вызова базы данных требует времени, так же как чтение файлов, форматирование строк, шаблонов обработки и т.д. требует времени. Выполнение любой из этих вещей в том же потоке, что и основной цикл событий сервера, предотвратит движение цикла до тех пор, пока вы не закончите.

Ответ 2

Торнадо не блокируется, если вы пишете неблокирующий код сверху, если он, например. используя asyncmongo и @tornado.web.asynchronous decorator, Tornado в качестве основы предоставляет инструменты для этого.

Брет Тейлор, один из авторов, пишет:

Мы экспериментировали с различными подходами асинхронного БД, но синхронно в FriendFeed, потому что, как правило, если наши запросы в БД были отставание наших запросов, наши бэкенды не могли масштабироваться до нагрузки так или иначе. Вещи, которые были достаточно медленными, были абстрагированы, чтобы отделить бэкэнд-услуги, которые мы получаем асинхронно через асинхронный HTTP-запрос модуль.

Верно, что Tornado не включает неблокирующий уровень базы данных; на самом деле слой базы данных не является неотъемлемой частью структуры Tornado вообще, в отличие от, например, Django ORM. Да, Tornado поставляется с блокирующей оболочкой MySQL, потому что то, что FriendFeed произошло, но это скорее внешняя библиотека, чем основная функциональность. Я уверен, что большинство людей используют что-то еще для доступа к базе данных.

Ответ 3

Да; это не полностью неблокирующий веб-сервер вообще.

Неблокирующий веб-сервер не блокирует, используя неблокирующие API для ввода-вывода файлов, доступа к базе данных и т.д., чтобы гарантировать, что один запрос, который должен ждать чего-то, чтобы завершить, не мешает другим запросам от обработки. Это относится ко всему, что может блокировать сервер, включая доступ к базе данных.

Нет ничего глупого, как "нарушение причинности" при наличии неблокирующего доступа к базе данных; имеет смысл запускать неблокирующий запрос, связанный с одним запросом, и обрабатывать другие запросы, пока они все еще работают. На практике это обычно означает создание нескольких соединений с базой данных базы данных.

Обратите внимание, что если вы пытаетесь запустить десять тысяч одновременных запросов, будьте осторожны: большинство бэкэндов базы данных не справляются с этим. Если у вас более нескольких десятков запросов на базу данных, которые вы запускаете параллельно, вы, вероятно, хотите получить что-то вроде пула соединений, чтобы веб-сервер мог делать много соединений с базой данных, не опуская бэкэнд. Это вызовет блокировку запросов, ожидающих в очереди, чтобы получить доступ к базе данных, но это означает, что это не блокирует весь сервер - просто запросы, которым нужна база данных.