Обработка подключений Mysql веб-фреймворка Tornado
-
20-09-2019 - |
Вопрос
Недавно я изучал веб-фреймворк 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))
Объявите его в базовом обработчике, он будет вызываться один раз для каждого приложения.