Frage

Ich habe kürzlich das Tornado -Web -Framework erkundet, um viele konsistente Verbindungen von vielen verschiedenen Kunden herzustellen.

Ich habe einen Anfrage -Handler, der im Grunde genommen eine RSA verschlüsselt und entschlüsselt und entschlüsselt. Der entschlüsselte Text ist eine XML -Zeichenfolge, die von einem SAX -Dokumenthandler, den ich geschrieben habe, analysiert wird. Alles funktioniert vollkommen in Ordnung und die Ausführungszeit (pro HTTP -Anfrage) betrug ungefähr 100 Millisekunden (mit Entschlüsselung und Parsen).

Der XML enthält den Benutzernamen und den Passwort des Benutzers. Ich möchte eine Verbindung zu einem MySQL -Server herstellen, um zu überprüfen, ob der Benutzername mit dem von der Anwendung bereitgestellten Passwort -Hash übereinstimmt.

Wenn ich im Grunde den folgenden Code hinzufüge:

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()

Die Zeit, die für die Ausführung der HTTP -Anfrage benötigt wird, schießt bis zu 4 - 5 Sekunden! Ich glaube, dies ist in der Zeit anfallen, die es benötigt, um eine Verbindung zum MySQL -Datenbankserver selbst herzustellen.

Meine Frage ist, wie kann ich das beschleunigen? Kann ich die MySQL -Verbindung im globalen Bereich deklarieren und in den Anforderungshandlern darauf zugreifen, indem ich einen neuen Cursor erstellt, oder wird dies aufgrund des asynchronen Designs von Tornado auf Parallelitätsprobleme stoßen?

Wie kann ich im Grunde keine neue Verbindung zu einem MySQL -Server bei jeder HTTP -Anforderung herstellen, sodass nur mehrere Sekunden anstelle von mehreren Sekunden erforderlich sind.

Bitte beachten Sie auch, dass der SQL -Server tatsächlich auf derselben physischen Maschine wie die Tornado -Webserverinstanz steht

Aktualisieren

Ich habe gerade eine einfache MySQL -Abfrage über einen Profiler durchgeführt, denselben Code unten.

Der Anruf von 'Connections.Py' ' drin Die Funktion dauerte 4,944 Sekunden, um allein auszuführen. Das scheint nicht richtig zu sein, oder?

Update 2

Ich denke, dass das Laufen mit einer Verbindung (oder sogar wenigen mit einem sehr einfachen DB -Conn -Pool) schnell genug ist, um den Durchsatz zu verarbeiten, den ich pro Tornado -Webserverinstanz erwarte.

Wenn 1.000 Kunden auf eine Abfrage zugreifen müssen, müsste der unglücklichste Kunde nur eine Sekunde warten, um die Daten abzurufen.

War es hilfreich?

Lösung

In Betracht ziehen Sqlalchemy, die eine schönere Abstraktion über DBAPI und auch Verbindungsbeamten usw. liefert (Sie können seine ORM gerne ignorieren und einfach den SQL-Toolkit verwenden)

(Außerdem führen Sie in den asynchronen Anforderungshandlern keine Datenbankanrufe durch?)

Andere Tipps

Eine SQL -Verbindung sollte nicht 5 Sekunden dauern. Versuchen Sie, keine Abfrage auszugeben und zu prüfen, ob dies Ihre Leistung verbessert - was sie sollte.

Das MySQLDB -Modul verfügt über eine Threadsafety von "1", was bedeutet, dass das Modul fadensicher ist, aber Verbindungen können nicht unter Threads geteilt werden. Sie können einen Verbindungspool als Alternative implementieren.

Schließlich verfügt das DB-API über ein Parameter-Ersatzformular für Abfragen, für die keine Abfrage und Entweichenparameter manuell verkettet werden müssen:

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

Erklären Sie es im Basishandler, es wird einmal pro Anwendung aufgerufen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top