Python 异步编程完整指南:async/await 实战 30 个案例
# Python 异步编程完整指南:async/await 实战(30 个真实案例) > Python 异步编程是 2025 年后端开发必备技能——能 5x 提升 I/O 性能。本文**实战讲解** Python 异步编程 + 30 个真实案例 + 完整代码。 > **读完保证**:能写高性能异步代码 + 处理 5x 并发 + 避免 4 大常见陷阱。
Python 异步编程完整指南:async/await 实战(30 个真实案例)
Python 异步编程是 2025 年后端开发必备技能——能 5x 提升 I/O 性能。本文实战讲解 Python 异步编程 + 30 个真实案例 + 完整代码。
读完保证:能写高性能异步代码 + 处理 5x 并发 + 避免 4 大常见陷阱。
一、为什么 Python 异步编程重要?
1.1 数据
同步 vs 异步性能对比:
场景:100 个 HTTP 请求
同步:
- 总时间:100 × 200ms = 20 秒
异步:
- 总时间:200ms × 5 并发 = 1 秒
→ 5x 性能提升
1.2 真实案例
我们的 AI 服务改造:
- 同步:100 QPS
- 异步:500 QPS(5x)
→ 异步 = 后端性能核心
二、Python 异步基础
1. async/await 基础
import asyncio
async def fetch_data(url):
"""异步获取数据"""
print(f"开始获取 {url}")
await asyncio.sleep(2) # 模拟 I/O
print(f"完成 {url}")
return f"data from {url}"
async def main():
# 串行执行:6 秒
data1 = await fetch_data("url1")
data2 = await fetch_data("url2")
data3 = await fetch_data("url3")
# 并发执行:2 秒
async def main_concurrent():
results = await asyncio.gather(
fetch_data("url1"),
fetch_data("url2"),
fetch_data("url3"),
)
asyncio.run(main_concurrent())
2. asyncio.gather(并发执行)
import asyncio
import aiohttp
async def fetch(session, url):
async with session.get(url) as response:
return await response.json()
async def fetch_all(urls):
async with aiohttp.ClientSession() as session:
tasks = [fetch(session, url) for url in urls]
return await asyncio.gather(*tasks)
# 使用
urls = ["url1", "url2", "url3"]
results = asyncio.run(fetch_all(urls))
三、30 个真实案例
案例 1-5:HTTP 请求
# 1. 并发 HTTP 请求
async def fetch_all_pages(urls):
async with aiohttp.ClientSession() as session:
tasks = [session.get(url) for url in urls]
return await asyncio.gather(*tasks)
# 2. 带超时的请求
async def fetch_with_timeout(url, timeout=5):
async with aiohttp.ClientSession(timeout=aiohttp.ClientTimeout(total=timeout)) as session:
async with session.get(url) as response:
return await response.json()
# 3. 重试机制
async def fetch_with_retry(url, max_retries=3):
for i in range(max_retries):
try:
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.json()
except Exception as e:
if i == max_retries - 1:
raise
await asyncio.sleep(2 ** i) # 指数退避
# 4. 限流(信号量)
sem = asyncio.Semaphore(10) # 最多 10 并发
async def fetch_with_limit(url):
async with sem:
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.json()
# 5. 批量 HTTP 请求
async def batch_request(urls, batch_size=10):
results = []
for i in range(0, len(urls), batch_size):
batch = urls[i:i+batch_size]
results.extend(await fetch_all_pages(batch))
return results
案例 6-10:数据库
# 6. asyncpg(PostgreSQL 异步)
import asyncpg
async def fetch_users():
conn = await asyncpg.connect(
user='user', password='pwd', database='db',
host='localhost'
)
rows = await conn.fetch('SELECT * FROM users')
await conn.close()
return rows
# 7. 异步 ORM(SQLAlchemy 2.0)
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
engine = create_async_engine('postgresql+asyncpg://...')
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession)
async def get_user(user_id):
async with AsyncSessionLocal() as session:
result = await session.execute(
select(User).where(User.id == user_id)
)
return result.scalar_one_or_none()
# 8. 异步事务
async def transfer_money(from_id, to_id, amount):
async with AsyncSessionLocal() as session:
async with session.begin():
from_user = await session.get(User, from_id)
to_user = await session.get(User, to_id)
from_user.balance -= amount
to_user.balance += amount
# 9. 异步批量插入
async def bulk_insert(items):
async with engine.begin() as conn:
await conn.execute(User.__table__.insert(), items)
# 10. 异步连接池
from asyncpg import create_pool
async def setup_pool():
return await create_pool(
user='user', password='pwd', database='db',
min_size=5, max_size=20
)
pool = asyncio.run(setup_pool())
async def query(sql):
async with pool.acquire() as conn:
return await conn.fetch(sql)
案例 11-15:AI / LLM 异步
# 11. 异步 LLM 调用
import openai
async def call_llm(prompt):
client = openai.AsyncClient()
response = await client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}]
)
return response.choices[0].message.content
# 12. 异步并发 LLM
async def call_many_llms(prompts):
client = openai.AsyncClient()
tasks = [
client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": p}]
)
for p in prompts
]
return await asyncio.gather(*tasks)
# 13. 异步 Embedding
async def embed_texts(texts):
client = openai.AsyncClient()
response = await client.embeddings.create(
model="text-embedding-3-small",
input=texts
)
return [d.embedding for d in response.data]
# 14. 异步 RAG
async def async_rag(query, rag_chain):
# 异步 RAG 调用
docs = await rag_chain.retriever.ainvoke(query)
answer = await rag_chain.ainvoke(query)
return answer, docs
# 15. 异步 Agent
async def async_agent(query, agent):
result = await agent.ainvoke({"input": query})
return result["output"]
案例 16-20:文件 I/O
# 16. 异步读文件
import aiofiles
async def read_file(path):
async with aiofiles.open(path, 'r') as f:
return await f.read()
# 17. 异步写文件
async def write_file(path, content):
async with aiofiles.open(path, 'w') as f:
await f.write(content)
# 18. 异步批量处理文件
async def process_files(paths):
tasks = [read_file(p) for p in paths]
contents = await asyncio.gather(*tasks)
return contents
# 19. 异步下载文件
async def download_file(url, save_path):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
content = await response.read()
async with aiofiles.open(save_path, 'wb') as f:
await f.write(content)
# 20. 异步流式读取
async def stream_read(path):
async with aiofiles.open(path, 'rb') as f:
async for line in f:
yield line
案例 21-25:消息队列 / 事件
# 21. 异步 Producer
import aio_pika
async def publish(message):
connection = await aio_pika.connect_robust("amqp://...")
channel = await connection.channel()
await channel.default_exchange.publish(
aio_pika.Message(message.encode()),
routing_key="tasks"
)
await connection.close()
# 22. 异步 Consumer
async def consume():
connection = await aio_pika.connect_robust("amqp://...")
channel = await connection.channel()
queue = await channel.declare_queue("tasks")
async with queue.iterator() as q:
async for msg in q:
async with msg.process():
await process(msg.body)
# 23. 异步任务队列(Redis)
import aioredis
async def worker():
redis = aioredis.from_url("redis://localhost")
while True:
task = await redis.blpop("tasks")
if task:
await process_task(task[1])
# 24. 异步定时任务
async def periodic(interval, func):
while True:
await func()
await asyncio.sleep(interval)
# 25. 异步回调
async def callback(event):
await asyncio.sleep(0.1) # 模拟处理
print(f"处理事件: {event}")
async def main():
events = [1, 2, 3, 4, 5]
await asyncio.gather(*[callback(e) for e in events])
案例 26-30:实战场景
# 26. 异步 Web 爬虫
async def async_crawl(urls, max_concurrent=10):
sem = asyncio.Semaphore(max_concurrent)
async def fetch(url):
async with sem:
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
return await response.text()
return await asyncio.gather(*[fetch(u) for u in urls])
# 27. 异步任务系统
class AsyncTaskQueue:
def __init__(self, max_workers=10):
self.sem = asyncio.Semaphore(max_workers)
self.results = []
async def add_task(self, func, *args):
async with self.sem:
result = await func(*args)
self.results.append(result)
return result
async def run(self, tasks):
return await asyncio.gather(*[self.add_task(*t) for t in tasks])
# 28. 异步缓存
class AsyncCache:
def __init__(self, ttl=300):
self.cache = {}
self.ttl = ttl
async def get(self, key):
if key in self.cache:
value, ts = self.cache[key]
if time.time() - ts < self.ttl:
return value
return None
async def set(self, key, value):
self.cache[key] = (value, time.time())
# 29. 异步限流
class AsyncRateLimiter:
def __init__(self, max_per_second=10):
self.sem = asyncio.Semaphore(max_per_second)
async def acquire(self):
await self.sem.acquire()
# 释放(1 秒后)
asyncio.get_event_loop().call_later(1, self.sem.release)
# 30. 异步超时控制
async def with_timeout(coro, timeout):
try:
return await asyncio.wait_for(coro, timeout=timeout)
except asyncio.TimeoutError:
return None
四、4 大常见错误
错误 1:阻塞调用
# 错
import requests
async def fetch():
return requests.get(url) # 阻塞!
# 对
import aiohttp
async def fetch():
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
return await resp.json()
错误 2:忘记 await
# 错
async def process():
result = async_func() # 忘了 await!
# 对
async def process():
result = await async_func()
错误 3:asyncio.run() 重复
# 错
async def main():
asyncio.run(another_async()) # 错误!嵌套 run
# 对
async def main():
await another_async()
错误 4:CPU 密集用 async
# 错:CPU 密集任务用 async(无效)
async def compute():
return sum(range(10_000_000))
# 对:CPU 密集用 multiprocessing
from multiprocessing import Pool
def compute():
return sum(range(10_000_000))
五、6 个月异步学习路径
Month 1:基础
□ async/await 语法
□ asyncio.gather
□ 异步 HTTP 请求
Month 2:进阶
□ 异步数据库
□ 异步 LLM
□ 异步任务队列
Month 3:实战
□ 重构同步代码为异步
□ 性能对比
□ 监控 + 调试
Month 4-5:高级
□ 异步流
□ 异步上下文管理器
□ 异步测试
Month 6:专家
□ 完整异步架构
□ 异步 + 多线程混合
□ 性能调优
反思:异步 = 后端性能倍增器
不夸张地说:
Python 异步 = 2025 年后端性能倍增器——同步 vs 异步 = 5x 性能差距。
立即开始:今天用 async / await 重写 1 个函数 = 你的异步之旅开始。 未来 5 年,异步 = 后端工程师必会技能——必学。
💬 评论 19 条