올려둔 서버가 내려가거나, API요청은 정상인데 database IDE로 접속이 안되거나, IDE들어가서 작성한 쿼리문이 무한로딩되는 상황이 가끔 발생되어서 이때마다 서버를 재실행 해야하는 문제가 생겼습니다.
연결 끊김은 SQLAlchemy engine 설정문제, time out, too many connections 문제는 코드 문제였습니다.
먼저 SQLAlchemy create_async_engine 설정을 수정
# 이전 코드
engine = create_async_engine(settings.DATABASE_URL)
# 수정 코드
engine = create_async_engine(settings.DATABASE_URL,
echo=True,
pool_pre_ping=True,
pool_recycle=1800,
pool_size=30,
max_overflow=20,
pool_timeout=30,
poolclass=AsyncAdaptedQueuePool,
connect_args={
"charset": "utf8mb4",
"connect_timeout": 60
}
)
echo - 쿼리 출력 여부
pool_pre_ping - 커넥션 풀에 있는 커넥션이 유효한지 ping을 보내 검사(끊어졌다면 새 커넥션 연결)
pool_recycle - 커넥션 재활용 30분(장기간 연결 방지)
pool_size - 커넥션 풀 사이즈 설정
max_overflow - 커넥션 풀 사이즈를 초과해서 생성할 수 커넥션 수
pool_timeout - 커넥션 풀에서 커넥션을 가져오는 최대 대기 시간
poolclass - 비동기 커넥션 풀 관리
connect_timeout - 데이터베이스 연결시 최대 대기 시간
이후 연결 끊김 현상은 사라졌지만 time out이나 too many connections 문제는 사라지지 않았습니다.

rds의 최대 커넥션 수는 90

연결 커넥션 수 현재는 25지만 max까지 올라갔었습니다
코드상에 커넥션 관리가 안되고 있다고 판단하게 되었고
여러 사람이 코드를 작성하다 보니 일부분에서 커넥션 연결 관리가 되지 않고 있던 문제 발견후 수정하게 되었습니다.
# 설정 코드
async_session = async_sessionmaker(
engine,
autoflush=False,
autocommit=False,
expire_on_commit=False,
class_=AsyncSession
)
async def get_db():
db = async_session()
try:
yield db
finally:
await db.commit()
await db.close()
# 이전 코드
from fastapi import APIRouter
from app.core.database import async_session
router = APIRouter()
db = async_session()
@router.get("/...")
async def get_something():
stmt = ...
result = await db.execute(stmt)
return result
# 수정 코드
from fastapi import APIRouter, Depend
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.database import get_db
router = APIRouter()
@router.get("/...")
async def get_something(session: AsyncSession = Depends(get_db)):
stmt = ...
result = await session.execute(stmt)
return result
이런식으로 get_db를 의존성 주입해주는 코드로 전부 변경해주었습니다. (이후 계층분리도 해주었습니다)
이후 잘 동작하며 해결!
데이터베이스 문제가 생겼을 때 원인을 잘 파악 할 것.
- 데이터베이스 문제인지
- 코드상의 문제인지
- 인프라 문제인지