스트리밍 도중 네트워크가 끊겼을 때 자연스럽게 재연결하는 전략은 무엇인가요?
LLM 스트리밍 중 연결이 끊겼을 때 이어받기 위한 재시도·백오프·재개(resume)·상태 보존 전략을 정리합니다.
긴 LLM 스트리밍은 도중에 네트워크가 끊길 수 있습니다. 사용자가 처음부터 다시 하지 않도록, 끊김을 감지 → 안전하게 재시도 → 가능하면 이어받기(resume) 하는 설계가 필요합니다.
핵심 전략
- 끊김 감지 — 스트림 읽기에서 예외/조기
done, 타임아웃(일정 시간 토큰 미수신),navigator.onLine·online/offline이벤트로 감지. - 지수 백오프 + 지터 — 즉시 반복 재시도하지 말고 대기 시간을 점점 늘리고(예: 1s→2s→4s) 무작위 지터를 더해 서버 폭주를 방지. 최대 재시도 횟수 제한.
- 상태 보존 — 이미 받은 부분 텍스트를 유지하고, 재연결 시 그 위에 이어 붙임. 사용자 입력·대화 컨텍스트는 보관.
- 재개(resume) vs 재요청
- SSE:
EventSource는 자동 재연결하며Last-Event-ID헤더로 마지막 받은 지점 이후를 서버가 이어 보내도록 설계 가능. - 이어받기 지원이 없으면: 서버에 “이미 N 토큰까지 받음”을 알리거나, idempotency 키/요청 ID로 같은 생성을 재개·중복 방지.
- 최후엔 동일 프롬프트로 재생성(중복 출력 가능성 안내).
- SSE:
- 명확한 UX — “연결이 끊겨 재연결 중…” 표시, 진행/실패 상태, 수동 재시도 버튼 제공. 무한 로딩 금지.
- 멱등성·중복 방지 — 재시도가 서버에서 중복 처리/중복 과금되지 않도록 요청 식별자 사용.
재연결 루프 예시
async function streamWithRetry(send, { maxRetries = 5 } = {}) {
let attempt = 0;
while (attempt <= maxRetries) {
try {
await send(); // 스트림 소비 (성공 시 정상 종료)
return;
} catch (err) {
if (err.name === 'AbortError') return; // 사용자가 중단 → 재시도 안 함
attempt++;
if (attempt > maxRetries) throw err;
const delay = Math.min(1000 * 2 ** (attempt - 1), 30_000) + Math.random() * 300;
showReconnecting(attempt);
await new Promise((r) => setTimeout(r, delay)); // 백오프 + 지터
}
}
}주의: 사용자가 의도적으로 중단한
AbortError는 재연결 대상이 아닙니다. 네트워크 오류와 구분해야 합니다.
스트리밍 중 네트워크 끊김에 대한 재연결 전략으로 적절하지 않은 것은?
이 레슨을 다 읽으셨나요?
완료 표시는 이 브라우저에 저장됩니다.