Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Pula połączeń poprawia wydajność aplikacji, ponownie używając połączeń z bazą zamiast tworzyć nowe połączenia dla każdego żądania. Otwarcie połączenia wymaga wielu czasochłonnych kroków:
- Sterownik ustanawia gniazdo sieciowe.
- Sterownik kończy utrzask dłoni TLS.
- Sterownik uwierzytelnia się z serwerem.
- Sterownik weryfikuje parametry połączenia.
Pula połączeń utrzymuje połączenia otwarte i dostępne do ponownego użycia, więc Twoja aplikacja nie musi powtarzać tych kroków dla każdego żądania.
Domyślne zachowanie
Buforowanie połączeń jest domyślnie włączone podczas tworzenia pierwszego połączenia. Ustawienia domyślne to:
| Setting | Wartość domyślna | Opis |
|---|---|---|
max_size |
100 | Maksymalna liczba połączeń na unikalny parametry połączenia. |
idle_timeout |
600 sekund (10 minut) | Liczba sekund przed zamknięciem bezczynnych połączeń. |
import mssql_python
# Pooling is automatically enabled with defaults
conn = mssql_python.connect(connection_string)
Konfigurowanie puli połączeń
Skonfiguruj pulowanie połączeń przed utworzeniem jakichkolwiek połączeń:
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
Funkcja pooling() akceptuje następujące parametry:
| Parameter | Typ | Domyślnie | Opis |
|---|---|---|---|
max_size |
int | 100 | Maksymalna liczba połączonych połączeń w puli na jeden parametry połączenia. |
idle_timeout |
int | 600 | Liczba sekund, po upływie których bezczynne połączenia są usuwane z puli. |
enabled |
bool | True | Włącz lub wyłącz pulowanie. |
Wyłącz pulowanie połączeń
Aby wyłączyć pulowanie, wywołaj pooling() za pomocą enabled=False przed utworzeniem połączeń:
import mssql_python
mssql_python.pooling(enabled=False)
# Connections are now created and destroyed per use
conn = mssql_python.connect(connection_string)
Note
Ustaw konfigurację puli przed nawiązaniem jakichkolwiek połączeń. Dzwonienie pooling() po nawiązaniu połączeń nie ma żadnego wpływu.
Jak działa pooling
Izolacja ciągu połączeń
Każdy unikalny zestaw parametrów połączenia ma własną, niezależną pulę. Pule nie współużytkują połączeń między różnymi łańcuchami połączeń:
# These use separate pools
conn1 = mssql_python.connect("Server=<server1>;Database=<database1>;...")
conn2 = mssql_python.connect("Server=<server2>;Database=<database2>;...")
Cykl życia połączenia
Uzyskiwanie (nawiązywanie połączenia):
- Pula usuwa przestarzałe (bezczynne) połączenia.
- Pula próbuje ponownie wykorzystać istniejące połączenie:
- Sprawdza, czy połączenie jest aktywne.
- Resetuje stan połączenia.
- Jeśli oba testy zakończą się sukcesem, połączenie przywraca się.
- Jeśli nie ma dostępnego połączenia do ponownego użycia, a liczba połączeń w puli jest mniejsza niż
max_size, sterownik tworzy nowe połączenie. - Jeśli pula osiągnęła maksymalną pojemność i nie ma żadnych prawidłowych połączeń, sterownik zgłasza błąd.
Zwolnienie (zwrócenie połączenia):
- Jeśli pula ma pojemność, przechowuje połączenie do ponownego wykorzystania.
- Jeśli pula połączeń jest na poziomie
max_size, sterownik natychmiast zamyka połączenie.
Sprawdzenie stanu połączenia
Sterownik przeprowadza sprawdzenie stanu połączenia przed ponownym użyciem połączenia w grupie.
- Alive check: Sprawdza, czy połączenie sieciowe jest nadal ważne.
- Reset check: Resetuje stan sesji (poziom izolacji, ustawienia) dla czystego ponownego użycia.
Jeśli którekolwiek ze sprawdzeń zakończy się niepowodzeniem, pula odrzuca połączenie i tworzy nowe.
Automatyczne oczyszczanie
-
Limit czasu bezczynności: Sterownik zamyka połączenia, które nie są używane dłużej niż wynosi wartość
idle_timeout. -
Wyjście z procesu: Handler
atexitzamyka wszystkie połączenia w grupie, gdy proces Python się kończy.
Najlepsze rozwiązania
Odpowiednio dopasuj swój basen
Dopasuj wielkość puli do poziomu współbieżności aplikacji.
# For a web application with 20 concurrent requests
mssql_python.pooling(max_size=25) # Slightly more than expected concurrency
Użyj menedżerów kontekstu
Menedżerowie kontekstu dbają o prawidłowe przywracanie połączeń do puli.
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
Utrzymuj spójność ciągów połączeń
Różne parametry w łańcuchach połączeń tworzą oddzielne pule.
# 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
Rozważ ograniczenia połączeń Azure SQL
Azure SQL Database egzekwuje limity połączeń w zależności od poziomu usług. Następujące wartości są przybliżone; Sprawdź powiązaną dokumentację dotyczącą aktualnych limitów:
| Poziom usługi | maksymalna liczba współbieżnych połączeń |
|---|---|
| Basic | 30 |
| Standard S0-S2 | 60-120 |
| Standardowe wersje S3 i późniejsze | 200 |
| Premium | 500 |
Ustaw rozmiar wartości max_size poniżej poniższych limitów.
# For Azure SQL Standard S2 (120 limit)
mssql_python.pooling(max_size=100) # Leave headroom
Dostrojcie czas na bezczynność dla swojego obciążenia pracą
-
Częste połączenia: Użyj dłuższej wartości
idle_timeout, aby utrzymać połączenia aktywne. -
Połączenia sporadyczne: Użyj krótszej wartości
idle_timeout, aby zwolnić zasoby.
# 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
Limitations
Obecna implementacja ma pewne ograniczenia w porównaniu do innych sterowników:
| Funkcja | Status |
|---|---|
ClearPool() / ClearAllPools() |
Niedostępne. |
| Statystyki i monitorowanie puli | Niedostępne. |
| Nadpisywanie puli per-połączeń | Niedostępne. |
| Minimalny rozmiar puli | Nie można skonfigurować. |
Przykład: Wzorzec aplikacji webowej
Poniższy przykład Flask pokazuje, jak połączenia są przezroczysto pulowane między żądaniami:
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()
Rozpoznaj wyczerpanie basenu
Gdy wszystkie połączenia w puli są zajęte i próbujesz uzyskać nowe połączenie, występują następujące symptomy:
- Połączenia zawieszają się lub przepadają podczas oczekiwania na wolne połączenie.
- Przepustowość aplikacji nagle spada pod obciążeniem.
- Zużycie pamięci rośnie, gdy sterownik tworzy połączenia, których nie może ponownie wykorzystać.
Typowe przyczyny:
- Połączenia nie wracają do puli. Zawsze zamykaj kontakty, gdy skończysz, albo używaj menedżerów kontekstu. Połączenie, które nie jest zamknięte, pozostaje w zasięgu kontroli.
- Zasób jest zbyt mały dla tego obciążenia. Jeśli masz 50 jednoczesnych żądań, ale
max_size=20, 30 żądań czeka. - Długotrwałe zapytania utrzymują powiązania. Podziel długie operacje lub użyj dedykowanych połączeń do pracy wsadowej.
Jak to naprawić:
# 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)