รูปแบบอะซิงก์ I/O ในระบบจริง
ประยุกต์ใช้ asyncio กับไคลเอ็นต์ HTTP คิว และไปป์ไลน์ในโลกจริง
รูปแบบอะซิงก์ I/O ในระบบจริง เป็นบทเรียน Python Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Python Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน
แนวทางปฏิบัติที่ดีสำหรับลูปเหตุการณ์
ใช้ asyncio.run() เป็นจุดเข้าสู่โปรแกรมเพียงจุดเดียวเสมอ หลีกเลี่ยงการผสมโค้ดแบบซิงโครนัสและแบบอะซิงโครนัสอย่างไม่ระมัดระวัง และอย่าบล็อกลูปเหตุการณ์ด้วยงานประมวลผล CPU ที่ใช้เวลานาน
import asyncio
async def main():
# Never: time.sleep() — blocks the event loop
# Always: await asyncio.sleep()
await asyncio.sleep(1)
asyncio.run(main())การใช้กลุ่มการเชื่อมต่อ
ใช้การเชื่อมต่อเดิมซ้ำแทนการเปิดการเชื่อมต่อใหม่สำหรับแต่ละคำขอ ไลบรารีอย่าง asyncpg และ aiohttp มีกลุ่มการเชื่อมต่อในตัว
# 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()ผู้ผลิตและผู้บริโภคด้วย asyncio.Queue
asyncio.Queue แยกผู้ผลิตและผู้บริโภคที่ทำงานเป็นงานพร้อมกันออกจากกัน
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())การจำกัดอัตราด้วยเซมาฟอร์
จำกัดจำนวนคำขอขาออกที่ทำพร้อมกัน เพื่อไม่ให้ส่วนเชื่อมต่อโปรแกรมประยุกต์ภายนอกทำงานหนักเกินไปหรือทำให้เกินขีดจำกัดอัตรา
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])ลองใหม่ด้วยการหน่วงเวลาแบบทวีคูณ
ครอบการดำเนินการที่สามารถลองใหม่ได้ด้วยตรรกะการหน่วงเวลา เพื่อจัดการความล้มเหลวชั่วคราวอย่างเหมาะสม
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)การปิดระบบอย่างราบรื่น
ดักจับ asyncio.CancelledError ในงานที่ทำงานเป็นเวลานาน และจัดการสัญญาณของระบบปฏิบัติการเพื่อปิดระบบอย่างเรียบร้อย
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")การตอบกลับแบบสตรีม
ใช้ตัวสร้างแบบอะซิงโครนัสเพื่อส่งการตอบกลับขนาดใหญ่เป็นสตรีม โดยไม่ต้องโหลดทั้งหมดไว้ในหน่วยความจำ
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")งานเบื้องหลังใน FastAPI
BackgroundTasks ของ FastAPI จัดคิวงานให้ทำหลังจากส่งการตอบกลับแล้ว ทำให้จุดปลายทางตอบสนองได้รวดเร็ว
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"}รูปแบบสัญญาณชีพ
เรียกใช้งานเบื้องหลังเป็นระยะควบคู่ไปกับลูปเซิร์ฟเวอร์หลักโดยใช้ 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()การทำโปรไฟล์โค้ดแบบอะซิงโครนัส
ใช้ yappi หรือ py-spy สำหรับการทำโปรไฟล์ที่รองรับโค้ดแบบอะซิงโครนัส เปิดโหมดดีบักของ asyncio เพื่อรับคำเตือนเกี่ยวกับการเรียกกลับที่ทำงานช้า
# Enable debug to catch slow callbacks:
# asyncio.run(main(), debug=True)
# PYTHONASYNCIODEBUG=1 python server.py
# logs: Executing <Task coroutine=...> took 0.150 secondsการหลีกเลี่ยงข้อผิดพลาดที่พบบ่อย
กฎสำคัญมีดังนี้ อย่าเรียกโค้ดแบบบล็อกบนลูปเหตุการณ์ รอคอยโครูทีนเสมอ ยกเลิกงานเมื่อปิดระบบ ใช้กลุ่มการเชื่อมต่อ และจำกัดการทำงานพร้อมกันด้วยเซมาฟอร์
import asyncio
async def bad():
import time
time.sleep(2) # blocks the entire event loop!
async def good():
await asyncio.sleep(2) # yields controlตรวจสอบความเข้าใจอย่างรวดเร็ว
โครงสร้างพื้นฐานใดของ asyncio ที่แยกผู้ผลิตและผู้บริโภคซึ่งทำงานเป็นงานพร้อมกันออกจากกัน
สรุปทบทวน
รูปแบบโค้ดแบบอะซิงโครนัสสำหรับใช้งานจริง ได้แก่ ใช้กลุ่มการเชื่อมต่อ ควบคุมการทำงานพร้อมกันด้วย Semaphore ใช้การลองใหม่และการหน่วงเวลา ส่งข้อมูลขนาดใหญ่เป็นสตรีม ปิดระบบอย่างราบรื่นเมื่อได้รับสัญญาณ และเรียกงานเป็นระยะด้วย create_task
คำถามที่พบบ่อย
บทเรียน “รูปแบบอะซิงก์ I/O ในระบบจริง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “รูปแบบอะซิงก์ I/O ในระบบจริง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Python Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Python Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “รูปแบบอะซิงก์ I/O ในระบบจริง”
ประยุกต์ใช้ asyncio กับไคลเอ็นต์ HTTP คิว และไปป์ไลน์ในโลกจริง คุณปฏิบัติ Python Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Python Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Python Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “รูปแบบอะซิงก์ I/O ในระบบจริง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Python Academy นี้ได้ไหม
ได้ บทเรียน Python Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- โครูทีนและลูปเหตุการณ์
- await งาน และการรวบรวมงาน
- ตัวจัดการบริบทและตัววนซ้ำแบบอะซิงก์
- รูปแบบอะซิงก์ I/O ในระบบจริง