회사의 비디오 카테고리 그리드는 타사 CDN에서 최적화되지 않은 대용량 JPEG 썸네일을 핫링크하고 있어 모바일 Largest Contentful Paint(LCP) 시간이 느려지는 원인이 되었습니다. 이는 전체 해상도 이미지를 제공하고 CSS로 축소하여 상당한 대역폭을 낭비했기 때문입니다. 이를 해결하기 위해 썸네일 생성 프로세스를 담당하는 Go 서비스를 개발했습니다. 이 서비스는 FFmpeg를 사용하여 원본 비디오 또는 포스터 프레임에서 시각적으로 구분되는 프레임을 추출합니다. 그런 다음 이 프레임을 JPEG보다 효율적인 여러 WebP 너비로 인코딩합니다. Go 서비스는 다운로드 트래픽 제어도 처리하여 FFmpeg 프로세스가 효율적으로 관리되도록 합니다. PHP는 실행 시간 및 프로세스 관리의 공유 호스팅 제한으로 인해 이 작업에 부적합하다고 판단되었습니다. Go 서비스는 더 빠른 탐색을 위해 -i 앞에 -ss와 같은 FFmpeg 플래그를 사용하고 더 나은 프레임 선택을 위해 thumbnail=300을 사용합니다. 또한 중복 처리를 방지하고 동시성을 관리하기 위해 제한된 워커 풀과 singleflight를 사용합니다. 생성된 썸네일은 임시 파일에 기록된 다음 원자적으로 이름이 변경되어 불완전한 파일이 제공되는 것을 방지합니다. 이 Go 서비스는 썸네일 생성 작업을 큐에 넣는 cron 작업에 의해 트리거됩니다. 그런 다음 프론트엔드 PHP 애플리케이션은 간단한 SQLite 데이터베이스를 쿼리하여 이러한 썸네일의 상태를 확인합니다. 데이터베이스 스키마는 기본적이며 비디오 ID, 소스 URL, 상태 및 재시도 횟수를 저장합니다. PHP cron 작업은 Go 서비스에 HTTP 요청을 하여 이 큐를 비웁니다. Go 서비스의 쓰기 시간 초과는 잘린 응답을 피하기 위해 의도적으로 작업의 실행 예산보다 길게 설정됩니다.
-i앞에-ss와 같은 FFmpeg 플래그를 사용하고 더 나은 프레임 선택을 위해thumbnail=300을 사용합니다. 또한 중복 처리를 방지하고 동시성을 관리하기 위해 제한된 워커 풀과 singleflight를 사용합니다. 생성된 썸네일은 임시 파일에 기록된 다음 원자적으로 이름이 변경되어 불완전한 파일이 제공되는 것을 방지합니다. 이 Go 서비스는 썸네일 생성 작업을 큐에 넣는 cron 작업에 의해 트리거됩니다. 그런 다음 프론트엔드 PHP 애플리케이션은 간단한 SQLite 데이터베이스를 쿼리하여 이러한 썸네일의 상태를 확인합니다. 데이터베이스 스키마는 기본적이며 비디오 ID, 소스 URL, 상태 및 재시도 횟수를 저장합니다. PHP cron 작업은 Go 서비스에 HTTP 요청을 하여 이 큐를 비웁니다. Go 서비스의 쓰기 시간 초과는 잘린 응답을 피하기 위해 의도적으로 작업의 실행 예산보다 길게 설정됩니다.