OpenAI API 응답 스트리밍 처리 중 connection timeout 해결

문제 상황

사내 챗봇 서비스에서 GPT-4o API를 사용 중이었는데, 긴 응답을 스트리밍으로 받다가 중간에 연결이 끊기는 현상이 발생했다. 특히 코드 생성이나 긴 문서 작성 요청 시 30초~60초 사이에 에러가 났다.

const response = await openai.chat.completions.create({
  model: 'gpt-4o',
  messages: messages,
  stream: true,
});

for await (const chunk of response) {
  // 여기서 중간에 끊김
  process.stdout.write(chunk.choices[0]?.delta?.content || '');
}

원인 분석

로그를 확인해보니 ECONNRESET 에러가 발생하고 있었다. Nginx 프록시 서버의 proxy_read_timeout이 60초로 설정되어 있었고, OpenAI API가 스트리밍 중 일시적으로 데이터 전송이 느려질 때 타임아웃이 발생했다.

해결 방법

1. Nginx 타임아웃 설정 조정

location /api/chat {
  proxy_pass https://api.openai.com;
  proxy_read_timeout 300s;
  proxy_connect_timeout 10s;
  proxy_send_timeout 300s;
}

2. Node.js HTTP Agent 설정

import { Agent } from 'https';
import OpenAI from 'openai';

const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
  httpAgent: new Agent({
    keepAlive: true,
    keepAliveMsecs: 30000,
    timeout: 300000,
  }),
});

3. 재시도 로직 추가

완전한 해결을 위해 네트워크 에러 시 재시도하는 로직도 추가했다.

async function streamWithRetry(messages, maxRetries = 2) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await openai.chat.completions.create({
        model: 'gpt-4o',
        messages: messages,
        stream: true,
      });
      return response;
    } catch (error) {
      if (error.code === 'ECONNRESET' && i < maxRetries - 1) {
        await new Promise(resolve => setTimeout(resolve, 1000));
        continue;
      }
      throw error;
    }
  }
}

결과

타임아웃 설정 조정 후 긴 응답도 안정적으로 처리되었다. 5분 이상 걸리는 요청도 문제없이 완료되는 것을 확인했다. 프로덕션 환경에서는 인프라 레벨의 타임아웃 설정도 함께 체크해야 한다는 것을 다시 한번 배웠다.