Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Il pool di connessioni migliora le prestazioni delle applicazioni riutilizzando le connessioni al database invece di crearne di nuove per ogni richiesta. Aprire una connessione comporta diversi passaggi che richiedono molto tempo:
- Il driver instaura una presa di rete.
- Il driver completa la stretta di mano TLS.
- Il driver si autentica con il server.
- Il driver valida i parametri di connessione.
Il pool di connessione mantiene le connessioni aperte e disponibili per il riutilizzo, così la tua app non deve ripetere questi passaggi per ogni richiesta.
Comportamento predefinito
Il pool di connessioni è abilitato di default quando crei la tua prima connessione. Le impostazioni predefinite sono le seguenti:
| Setting | Valore predefinito | Descrizione |
|---|---|---|
max_size |
100 | Connessioni massime per ogni stringa di connessione univoca. |
idle_timeout |
600 secondi (10 minuti) | Numero di secondi prima che le connessioni inattive vengano chiuse. |
import mssql_python
# Pooling is automatically enabled with defaults
conn = mssql_python.connect(connection_string)
Configurare il pool di connessioni
Configura il pooling prima di creare qualsiasi connessione:
import mssql_python
# Configure custom pool settings
mssql_python.pooling(max_size=50, idle_timeout=300)
# Now create connections
conn = mssql_python.connect(connection_string)
Parameters
La pooling() funzione accetta i parametri seguenti:
| Parametro | TIPO | Impostazione predefinita | Descrizione |
|---|---|---|---|
max_size |
int | 100 | Numero massimo di connessioni nel pool per stringa di connessione. |
idle_timeout |
int | 600 | Pochi secondi prima che le connessioni inattive vengano sfrattate dalla piscina. |
enabled |
Bool | True | Abilita o disabilita il pooling. |
Disabilita il pool di connessioni
Per disabilitare il pooling, chiama pooling() con enabled=False prima di creare le connessioni:
import mssql_python
mssql_python.pooling(enabled=False)
# Connections are now created and destroyed per use
conn = mssql_python.connect(connection_string)
Note
Imposta la configurazione del pool prima di stabilire qualsiasi connessione. Chiamare pooling() dopo aver creato connessioni non ha alcun effetto.
Come funziona il pooling
Isolamento della stringa di connessione
Ogni stringa di connessione distinta mantiene un proprio pool separato. I pool non condividono le connessioni tra diverse stringhe di connessione:
# These use separate pools
conn1 = mssql_python.connect("Server=<server1>;Database=<database1>;...")
conn2 = mssql_python.connect("Server=<server2>;Database=<database2>;...")
Ciclo di vita della connessione
Acquisire (ottenere una connessione):
- Il pool rimuove le connessioni obsolete (scadute per inattività).
- Il pool cerca di riutilizzare una connessione esistente:
- Controlla se la connessione è attiva.
- Resetta lo stato della connessione.
- Se entrambi i controlli hanno successo, la connessione viene restituita.
- Se non esiste una connessione riutilizzabile e il pool è sotto
max_size, il driver crea una nuova connessione. - Se il pool ha raggiunto la capacità massima e non sono presenti connessioni valide, il driver restituisce un errore.
Rilascio (restituendo una connessione):
- Se il pool ha capacità disponibile, memorizza la connessione per riutilizzarla.
- Se il pool è a
max_size, il driver chiude immediatamente la connessione.
Controlli di salute della connessione
Il driver effettua controlli di salute della connessione prima di riutilizzare una connessione pooled.
- Controllo in vivo: Assicura che la connessione di rete sia ancora valida.
- Controllo reset: Resetta lo stato della sessione (livello di isolamento, impostazioni) per un riutilizzo pulito.
Se uno dei due controlli fallisce, il pool scarta la connessione e ne crea una nuova.
Pulizia automatica
-
Timeout di inattività: Il driver chiude le connessioni rimaste inattive più a lungo del valore
idle_timeout. -
Uscita del processo: Un
atexithandler chiude tutte le connessioni aggregate quando il processo Python esce.
Procedure consigliate
Dimensiona la piscina in modo appropriato
Adegua la dimensione del tuo pool alla concorrenza della tua applicazione.
# For a web application with 20 concurrent requests
mssql_python.pooling(max_size=25) # Slightly more than expected concurrency
Usa i gestori di contesto
I gestori di contesto garantiscono la corretta restituzione delle connessioni al pool.
with mssql_python.connect(connection_string) as conn:
cursor = conn.cursor()
cursor.execute("SELECT TOP 5 Name, ListPrice FROM Production.Product")
rows = cursor.fetchall()
# Connection returned to pool
Mantieni le stringhe di connessione coerenti
Parametri diversi nelle stringhe di connessione creano pool separati.
# These create THREE separate pools (inefficient)
conn1 = mssql_python.connect("Server=<server>;Database=<database>;Encrypt=yes;")
conn2 = mssql_python.connect("SERVER=<server>;DATABASE=<database>;ENCRYPT=yes;") # Different case
conn3 = mssql_python.connect("Server=<server>;Database=<database>;Encrypt=yes;", timeout=30) # Extra parameter
# Use a constant connection string instead
CONNECTION_STRING = "Server=<server>;Database=<database>;Encrypt=yes;"
conn1 = mssql_python.connect(CONNECTION_STRING)
conn2 = mssql_python.connect(CONNECTION_STRING) # Same pool
Considera i limiti di connessione di Azure SQL
database SQL di Azure applica i limiti di connessione in base al livello di servizio. I seguenti valori sono approssimativi; Controlla la documentazione collegata per i limiti attuali:
| Livello di servizio | Numero massimo di connessioni simultanee |
|---|---|
| Basic | 30 |
| S0-S2 standard | 60-120 |
| Standard S3 e versioni successive | 200 |
| Premium | 500 |
Misura il tuo max_size valore sotto questi limiti.
# For Azure SQL Standard S2 (120 limit)
mssql_python.pooling(max_size=100) # Leave headroom
Regola il timeout di inattività del tuo carico di lavoro
-
Connessioni frequenti: Usa un valore più lungo
idle_timeoutper mantenere le connessioni calde. -
Connessioni sporadiche: Usa un valore più
idle_timeoutbreve per rilasciare risorse.
# High-frequency API: keep connections warm
mssql_python.pooling(idle_timeout=1800) # 30 minutes
# Batch job running every hour: release between runs
mssql_python.pooling(idle_timeout=60) # 1 minute
Limitazioni
L'attuale implementazione presenta alcune limitazioni rispetto ad altri driver:
| Feature | Condizione |
|---|---|
ClearPool() / ClearAllPools() |
Non disponibile. |
| Statistiche/monitoraggio dei pool | Non disponibile. |
| Sovrascrittura del pool per connessione | Non disponibile. |
| Dimensione minima della piscina | Non configurabile. |
Esempio: schema di applicazione web
Il seguente esempio di Flask mostra come le connessioni vengono aggregate in modo trasparente tra le richieste:
import mssql_python
from flask import Flask, g
app = Flask(__name__)
# Configure pooling at startup
mssql_python.pooling(max_size=20, idle_timeout=300)
def get_db():
if 'db' not in g:
g.db = mssql_python.connect(app.config['DATABASE_URL'])
return g.db
@app.teardown_appcontext
def close_db(error):
db = g.pop('db', None)
if db is not None:
db.close() # Returns to pool
@app.route('/products')
def list_products():
conn = get_db()
cursor = conn.cursor()
cursor.execute("SELECT TOP 5 Name, ListPrice FROM Production.Product")
return cursor.fetchall()
Riconosci la stanchezza in piscina
Quando tutte le connessioni nella piscina sono in uso e richiedi una nuova connessione, si vedono sintomi come:
- Le connessioni si bloccano o si interrompono mentre aspettano una connessione gratuita.
- La produttività dell'applicazione cala improvvisamente sotto carico.
- L'uso della memoria aumenta man mano che il driver crea connessioni che non può riutilizzare.
Cause comuni:
- Le connessioni non vengono restituite alla piscina. Chiudi sempre le connessioni quando hai finito, oppure usa i gestori di contesto. Una connessione che non è chiusa resta chiusa.
- La piscina è troppo piccola per il carico di lavoro. Se hai 50 richieste concorrenti ma
max_size=20, 30 richieste aspettano. - Le query di lunga data mantengono connessioni. Interrompi le operazioni lunghe o usa connessioni dedicate per il lavoro a batch.
Come correggere:
# 1. Always use context managers to guarantee return
with mssql_python.connect(connection_string) as conn:
cursor = conn.cursor()
cursor.execute("SELECT ...")
rows = cursor.fetchall()
# Connection returned to pool here, even if an exception occurs
# 2. Size the pool to match your concurrency
mssql_python.pooling(max_size=50) # Match or slightly exceed expected concurrent connections
# 3. Reduce idle timeout if connections go stale
mssql_python.pooling(idle_timeout=120)