배경 및 목표

행동과학 연구소 연동은 채용담당자가 행동과학 연구소 사이트에서 지원자 목록을 대조하며, 검사 요청하는 것이 아닌 자사 채용서비스에서 검사 요청과 결과 조회를 제공해주기 위한 연동 과제입니다.

ORP 사례의 메모리 로드 문제

행동과학연구소 연동에서는 이전 ORP 연동 사례에서 우려되었던, 애플리케이션 메모리에 파일 데이터를 한 번에 로드한 후 S3에 업로드하는 방식을 해소하는 것을 주목표로 하였습니다.

왜 중요했는가

서버가 파일을 받아 메모리에 올리는 구조에서는 파일 크기가 그대로 힙 점유가 됩니다. 동시 요청이 많아질수록 OOM의 가능성이 높아지고, 이는 특정 기능의 실패가 아니라 서비스 전체 가용성 문제였습니다.

제약

제약선택지에 미친 영향
별도 배치 구현 공수 부담결과 조회 배치를 신설하면 개발 공수와 운영 대상이 하나 늘어납니다
대용량 파일 크기 예측 불가외부에서 올리는 파일이라 상한을 통제할 수 없어 크기와 무관하게 안전한 구조가 필요했습니다
외부 서비스가 업로드 주체자사 서버가 중계하지 않으려면 외부가 직접 접근할 수 있는 경로를 열어줘야 했습니다
권한 노출 최소화외부에 저장소 접근을 허용하는 만큼 유효 시간과 범위를 제한해야 했습니다

목표

  • 서버 직접 처리로 인한 파일 OOM 위험을 제거합니다.
  • 별도 배치 구현 없이 이후 다른 외부 연동에서도 재사용 가능한 파일 업로드 플로우를 확보합니다.

맡은 역할과 판단

구분내용
담당 범위결과 요청부터 결과 업로드까지의 플로우 설계와 구현을 단독으로 담당했습니다
직접 내린 판단1. 결과 조회 배치 신설 대신 업로드 경로에서 서버를 제외
2. 유효 기간이 제한된 업로드 권한을 발급해 접근 범위를 좁힘
3. 일회성 구현이 아니라 이후 연동에서 재사용할 공통 패턴으로 정리
협업, 합의플로우를 먼저 구성해 외부 기관에 선제시하고, 문제없다는 확인을 받은 뒤 확정했습니다

해결 방법과 해결 후보군

방식설명한계
서버 직접 처리서버가 파일을 받아 메모리/디스크에 적재 후 S3 업로드파일이 서버 메모리를 경유 → OOM 위험, 서버 대역폭 소모
결과 조회 배치 앱별도 배치를 신설하여 결과 조회 책임을 격리안전하지만 신규 배치 구현, 운영 공수 큼
Presigned URL (채택)서버는 URL만 발급, 외부가 S3에 직접 업로드서버가 파일 데이터를 거치지 않음 → OOM 원천 제거 + 구현 간단

1. 유효 기간이 제한된 업로드 권한(Presigned URL) 발급

서버는 S3에 대한 만료 시간이 있는 업로드 권한(URL)만 발급합니다. 실제 파일 바이트는 서버 메모리를 전혀 거치지 않습니다.

fun generatePresignedUrl(fileName: String): String {
    val request = GeneratePresignedUrlRequest(bucket, fileName)
        .withMethod(HttpMethod.PUT)
        .withExpiration(Date.from(Instant.now().plus(Duration.ofMinutes(30))))
    return s3Client.generatePresignedUrl(request).toString()
}

2. 외부가 S3로 직접 업로드하는 플로우

외부 서비스는 발급받은 URL로 S3에 직접 PUT합니다. 서버는 업로드 경로에서 완전히 빠져 파일 크기와 무관하게 메모리 사용량이 일정합니다.

sequenceDiagram
    participant Ext as 외부 서비스
    participant API as 서버
    participant S3 as AWS S3
    Ext->>API: 업로드 URL 요청
    API->>S3: Presigned URL 생성
    API-->>Ext: URL 응답 (30분 만료)
    Ext->>S3: 파일 직접 PUT (서버 미경유)
    S3-->>Ext: 업로드 완료
    Ext->>API: 업로드 완료 통지 (key)

기존에는 파일이 서버 메모리를 거쳤지만, 개선 후에는 URL 발급 요청/응답만 서버를 지나갑니다.

3. 재사용 가능한 공통 패턴으로 정리

버킷, 키 규칙, 만료 시간을 표준화한 공통 유틸리티로 정리하여, 이후 다른 외부 연동에서 파일 처리가 필요할 때 동일한 패턴을 재사용할 수 있도록 했습니다.


결과

지표결과
서버 메모리파일 미경유 (위험 0)
구현 범위URL 발급 로직만
재사용성공통 패턴화