Wzorce asynchronicznego wejścia-wyjścia w środowisku produkcyjnym
Proszę stosować asyncio do klientów HTTP, kolejek i rzeczywistych potoków przetwarzania.
Wzorce asynchronicznego wejścia-wyjścia w środowisku produkcyjnym to bezpłatna lekcja Python Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Python Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Python Academy zawiera 4 lekcji w sumie.
Najlepsze praktyki dotyczące pętli zdarzeń
Proszę zawsze używać asyncio.run() jako jedynego punktu wejścia. Należy unikać nieprzemyślanego mieszania kodu synchronicznego i asynchronicznego oraz nigdy nie blokować pętli zdarzeń długotrwałymi operacjami obliczeniowymi.
import asyncio
async def main():
# Never: time.sleep() — blocks the event loop
# Always: await asyncio.sleep()
await asyncio.sleep(1)
asyncio.run(main())Pula połączeń
Proszę ponownie wykorzystywać połączenia zamiast otwierać nowe dla każdego żądania. Biblioteki takie jak asyncpg i aiohttp udostępniają wbudowane pule połączeń.
# pip install asyncpg
import asyncpg, asyncio
async def main():
pool = await asyncpg.create_pool(
dsn="postgresql://user:pass@host/db",
min_size=5, max_size=20
)
async with pool.acquire() as conn:
row = await conn.fetchrow("SELECT 1")
await pool.close()Wzorzec producent-konsument z asyncio.Queue
asyncio.Queue rozdziela producentów i konsumentów działających jako współbieżne zadania.
import asyncio
async def producer(q):
for i in range(5):
await q.put(i)
await asyncio.sleep(0.5)
await q.put(None) # sentinel
async def consumer(q):
while (item := await q.get()) is not None:
print(f"processing {item}")
q.task_done()
async def main():
q = asyncio.Queue()
await asyncio.gather(producer(q), consumer(q))
asyncio.run(main())Ograniczanie liczby żądań za pomocą semafora
Proszę ograniczać liczbę współbieżnych żądań wychodzących, aby nie przeciążać zewnętrznych interfejsów API ani nie przekraczać ich limitów.
import asyncio, aiohttp
SEM = asyncio.Semaphore(10) # 10 concurrent requests max
async def fetch(session, url):
async with SEM:
async with session.get(url) as r:
return await r.json()
async def main(urls):
async with aiohttp.ClientSession() as s:
return await asyncio.gather(*[fetch(s, u) for u in urls])Ponawianie z wykładniczym opóźnieniem
Proszę opakować operacje, które można ponawiać, w logikę opóźnień między próbami, aby prawidłowo obsługiwać przejściowe błędy.
import asyncio
async def retry(coro_fn, retries=3, base=1):
for attempt in range(retries):
try:
return await coro_fn()
except Exception as e:
if attempt == retries - 1: raise
delay = base * 2 ** attempt
await asyncio.sleep(delay)Kontrolowane zamykanie
Proszę przechwytywać asyncio.CancelledError w długo działających zadaniach i obsługiwać sygnały systemu operacyjnego, aby zamykanie przebiegało prawidłowo.
import asyncio, signal
async def server():
stop = asyncio.Event()
loop = asyncio.get_running_loop()
loop.add_signal_handler(signal.SIGINT, stop.set)
await stop.wait()
print("Shutting down gracefully")Strumieniowanie odpowiedzi
Proszę używać generatorów asynchronicznych do strumieniowania dużych odpowiedzi bez ładowania ich w całości do pamięci.
import asyncio, aiohttp
async def stream(url):
async with aiohttp.ClientSession() as s:
async with s.get(url) as r:
async for chunk in r.content.iter_chunked(4096):
process(chunk)
async def process(chunk):
await asyncio.sleep(0)
print(len(chunk), "bytes")Zadania w tle w FastAPI
BackgroundTasks w FastAPI umieszcza zadania w kolejce, aby uruchomić je po wysłaniu odpowiedzi, dzięki czemu punkty końcowe działają szybko.
from fastapi import FastAPI, BackgroundTasks
app = FastAPI()
def send_email(to: str, body: str):
# heavy synchronous work
pass
@app.post("/register")
async def register(email: str, bg: BackgroundTasks):
bg.add_task(send_email, email, "Welcome!")
return {"status": "registered"}Wzorzec sygnału kontrolnego
Proszę uruchamiać okresowe zadanie w tle równolegle z główną pętlą serwera, używając create_task.
import asyncio
async def heartbeat():
while True:
print("alive")
await asyncio.sleep(30)
async def main():
asyncio.create_task(heartbeat())
await serve_forever()Profilowanie kodu asynchronicznego
Proszę używać yappi lub py-spy do profilowania uwzględniającego kod asynchroniczny. Proszę włączyć tryb debugowania asyncio, aby otrzymywać ostrzeżenia o powolnych wywołaniach zwrotnych.
# Enable debug to catch slow callbacks:
# asyncio.run(main(), debug=True)
# PYTHONASYNCIODEBUG=1 python server.py
# logs: Executing <Task coroutine=...> took 0.150 secondsUnikanie typowych pułapek
Najważniejsze zasady: nie należy nigdy wywoływać blokującego kodu w pętli zdarzeń; zawsze należy oczekiwać na korutyny; podczas zamykania należy anulować zadania; należy używać pul połączeń i ograniczać współbieżność za pomocą semaforów.
import asyncio
async def bad():
import time
time.sleep(2) # blocks the entire event loop!
async def good():
await asyncio.sleep(2) # yields controlSzybki test
Jaki mechanizm asyncio rozdziela producentów i konsumentów działających jako współbieżne zadania?
Podsumowanie
Wzorce asynchroniczne stosowane w środowisku produkcyjnym obejmują używanie pul połączeń, kontrolowanie współbieżności za pomocą semafora, implementowanie ponawiania z opóźnieniami, strumieniowanie dużych ilości danych, kontrolowane zamykanie po otrzymaniu sygnałów oraz uruchamianie zadań okresowych za pomocą create_task.
Często zadawane pytania
Czy lekcja „Wzorce asynchronicznego wejścia-wyjścia w środowisku produkcyjnym” jest bezpłatna?
Tak — pełny tekst „Wzorce asynchronicznego wejścia-wyjścia w środowisku produkcyjnym” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Python Academy, przejdź na CoddyKit PRO. Kurs Python Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Wzorce asynchronicznego wejścia-wyjścia w środowisku produkcyjnym”?
Proszę stosować asyncio do klientów HTTP, kolejek i rzeczywistych potoków przetwarzania. Ćwiczysz Python Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Python Academy?
Nie wymagamy żadnego doświadczenia. Python Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Wzorce asynchronicznego wejścia-wyjścia w środowisku produkcyjnym”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Python Academy?
Tak. Każda lekcja Python Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Korutyny i pętla zdarzeń
- await, zadania i grupowanie
- Asynchroniczne menedżery kontekstu i iteratory
- Wzorce asynchronicznego wejścia-wyjścia w środowisku produkcyjnym