Python 비동기 요청 처리 시 메모리 누수 해결
문제 상황
재택근무 체제로 전환하면서 사내 대시보드 API를 FastAPI로 마이그레이션했다. 외부 API 호출이 많은 서비스인데, 운영 중 메모리 사용량이 계속 증가하는 현상이 발견됐다.
원인 파악
각 엔드포인트에서 aiohttp.ClientSession을 매번 생성하고 있었지만, 명시적으로 닫지 않고 있었다.
# 문제가 있던 코드
@app.get("/external-data")
async def get_data():
session = aiohttp.ClientSession()
async with session.get("https://api.example.com") as resp:
data = await resp.json()
return data # session이 닫히지 않음
해결 방법
FastAPI의 의존성 주입을 활용해 세션 라이프사이클을 관리하도록 수정했다.
from contextlib import asynccontextmanager
# 전역 세션 관리
class HTTPClient:
session: aiohttp.ClientSession = None
async def start(self):
self.session = aiohttp.ClientSession()
async def stop(self):
await self.session.close()
http_client = HTTPClient()
@app.on_event("startup")
async def startup():
await http_client.start()
@app.on_event("shutdown")
async def shutdown():
await http_client.stop()
@app.get("/external-data")
async def get_data():
async with http_client.session.get("https://api.example.com") as resp:
return await resp.json()
결과
메모리 사용량이 안정화되었고, 세션 재사용으로 인해 커넥션 풀링 효과까지 얻었다. 응답 속도도 평균 30% 개선됐다.
교훈
비동기 리소스는 반드시 명시적으로 정리해야 한다. FastAPI의 라이프사이클 이벤트를 적극 활용하면 이런 문제를 예방할 수 있다.