Domanda

Di recente ho esplorato il framework web Tornado per servire un sacco di connessioni coerenti da un sacco di clienti diversi.

Ho un gestore di richieste che richiede fondamentalmente una stringa crittografata RSA e decifra. Il testo decifrato è una stringa XML che viene analizzato da un gestore di documento SAX che ho scritto. Tutto funziona perfettamente bene e il tempo di esecuzione (per richiesta HTTP) è stato di circa 100 millisecondi (con la decrittazione e l'analisi).

L'XML contiene il nome utente e password hash dell'utente. Voglio connettersi a un server MySQL per verificare che il nome utente corrisponda l'hash della password fornita con l'applicazione.

Quando aggiungo sostanzialmente il seguente codice:

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

Il tempo necessario per eseguire la richiesta HTTP spara fino a 4 - 5 secondi! Credo che questo è sostenuta per il tempo necessario per la connessione al server di database MySQL per sé.

La mia domanda è come posso accelerare questo? Posso dichiarare la connessione MySQL in ambito globale e accedervi nei gestori di richiesta con la creazione di un nuovo cursore, o volontà che incorrere in problemi di concorrenza a causa della progettazione asincrona di Tornado?

In sostanza, come faccio a non dover sostenere una nuova connessione ad un server MySQL OGNI Http richiesta, in modo che richiede solo una frazione di secondo, invece di più secondi da implementare.

Inoltre, si prega di notare, il server SQL è in realtà sulla stessa macchina fisica come l'istanza di Tornado Web Server

Aggiornamento

Ho appena eseguito una semplice query MySQL attraverso un profiler, lo stesso codice qui sotto.

La chiamata a 'connections.py' init la funzione ha avuto 4.944 secondi da eseguire da solo. Non mi sembra giusto, vero?

Update 2

Credo che in esecuzione con un collegamento (o anche un paio con un semplice piscina conn DB) sarà abbastanza veloce per gestire il throughput mi aspetto per tornado istanza del server web.

Se 1.000 clienti hanno bisogno di accedere a una query, tipici tempi di query che sono nelle migliaia di secondi, il cliente sfortunato avrebbe solo dovuto aspettare un secondo per recuperare i dati.

È stato utile?

Soluzione

SQLAlchemy , che fornisce un'astrazione più bello sopra DBAPI e fornisce anche il pool di connessioni, ecc (Si può tranquillamente ignorare la sua ORM e basta usare la SQL-toolkit)

(Inoltre, non stai facendo il blocco chiamate al database nei gestori richiesta asincrona?)

Altri suggerimenti

Una connessione SQL non dovrebbe prendere 5 secondi. Cercate di non emettere una query e vedere se questo migliora le prestazioni -. Che dovrebbe

Il modulo Mysqldb ha un thread pari a "1", che significa che il modulo è thread-safe, ma le connessioni non può essere condivisa tra thread. È possibile implementare un pool di connessioni come alternativa.

Infine, il DB-API ha una forma di sostituzione parametro per le query che non richiederebbero manualmente concatenare una query e sfuggire parametri:

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

dichiararla nel gestore di base, che sarà chiamato una volta per ogni applicazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top