Вопрос

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

У меня есть обработчик запросов, который в основном принимает зашифрованную строку RSA и расшифровывает ее.Расшифрованный текст представляет собой строку XML, которая обрабатывается обработчиком документов SAX, который я написал.Все работает отлично, и время выполнения (на HTTP-запрос) составило примерно 100 миллисекунд (с расшифровкой и синтаксическим анализом).

XML содержит имя пользователя и хэш пароля пользователя.Я хочу подключиться к серверу MySQL, чтобы убедиться, что имя пользователя соответствует хэшу пароля, предоставленному приложением.

Когда я добавляю в основном следующий код:

conn = MySQLdb.connect (host = "192.168.1.12",
                user = "<useraccount>",
                passwd = "<Password>",
                db = "<dbname>")
    cursor = conn.cursor()

    safe_username = MySQLdb.escape_string(XMLLoginMessage.username)
    safe_pass_hash = MySQLdb.escape_string(XMLLoginMessage.pass_hash)

    sql = "SELECT * FROM `mrad`.`users` WHERE `username` = '" + safe_username + "' AND `password` = '" + safe_pass_hash + "' LIMIT 1;"

    cursor.execute(sql)

            cursor.close()
    conn.close()

Время, необходимое для выполнения HTTP-запроса, увеличивается до 4-5 секунд!Я полагаю, что это связано со временем, необходимым для подключения к самому серверу базы данных MySQL.

Мой вопрос в том, как я могу ускорить это?Могу ли я объявить соединение MySQL в глобальной области видимости и получить к нему доступ в обработчиках запросов, создав новый курсор, или это приведет к проблемам с параллелизмом из-за асинхронного дизайна Tornado?

В принципе, как мне не нужно устанавливать новое соединение с сервером MySQL при КАЖДОМ Http-запросе, поэтому для реализации требуется всего лишь доля секунды вместо нескольких секунд.

Также, пожалуйста, обратите внимание, что SQL server фактически находится на том же физическом компьютере, что и экземпляр веб-сервера Tornado

Обновить

Я только что запустил простой запрос MySQL через профилировщик, тот же код ниже.

Вызов "соединения.py" инициализация одно выполнение функции заняло 4,944 секунды.Это кажется неправильным, не так ли?

Обновление 2

Я думаю, что запуск с одним подключением (или даже несколькими с очень простым пулом соединений с БД) будет достаточно быстрым, чтобы справиться с пропускной способностью, которую я ожидаю для каждого экземпляра веб-сервера tornado.

Если 1000 клиентам необходимо получить доступ к запросу, а типичное время запроса исчисляется тысячами секунд, самому невезучему клиенту придется подождать всего одну секунду, чтобы получить данные.

Это было полезно?

Решение

Рассмотреть Sql - алхимия, который обеспечивает более приятную абстракцию по сравнению с DBAPI , а также обеспечивает объединение пулов соединений и т.д.(Вы можете с радостью игнорировать его ORM и просто использовать SQL-toolkit)

(Кроме того, вы не блокируете вызовы базы данных в обработчиках асинхронных запросов?)

Другие советы

Подключение к SQL не должно занимать 5 секунд.Попробуйте не выдавать запрос и посмотрите, улучшит ли это вашу производительность - а так и должно быть.

Модуль Mysqldb имеет значение threadsafety "1", что означает, что модуль потокобезопасен, но соединения не могут быть разделены между потоками.В качестве альтернативы вы можете реализовать пул подключений.

Наконец, DB-API имеет форму замены параметров для запросов, которая не требует ручного объединения запроса и экранирования параметров:

cur.execute("SELECT * FROM blach WHERE x = ? AND y = ?", (x,y))

Объявите его в базовом обработчике, он будет вызываться один раз для каждого приложения.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top