개발 slecs

크롤러 SEO 메타데이터 생성 실패 시 폴백으로 파이프라인 중단 방지

목차

여러 크롤러 봇에서 SEO 메타데이터 생성 로직의 fallback을 구현했다. 외부 의존성이 있는 작업은 실패할 수 있으니, 실패했을 때도 시스템이 우아하게 동작하도록 만드는 게 이번 작업의 핵심이다.

문제 상황: SEO 생성 시 시스템 장애

우리 서비스는 게시글을 수집해서 데이터베이스에 저장하고 웹에 노출할 때, 각 페이지의 SEO 메타데이터(title, description, og:image 등)를 자동 생성하는 파이프라인을 갖고 있다. ssul 크롤러와 werebridge 봇 둘 다 이 흐름을 쓴다.

문제는 seo_generate 함수가 항상 성공하지 않는다는 거다. API 타임아웃, 외부 이미지 호스트 연결 실패, 텍스트 처리 중 인코딩 오류 같은 사건들이 발생하면, 메타데이터 생성에 실패하고 전체 게시글 처리 파이프라인이 중단될 수 있다. 특히 크롤링은 배치 작업이라서, 하나의 실패가 뒤따르는 수십 개 게시글 처리를 블록하는 상황이 쌓였다.

해결: Fallback 패턴 도입

fallback은 간단한 패턴이지만 효과적이다. "먼저 주 로직을 시도하되, 실패하면 합리적인 대체 방식으로 계속 진행"하는 거다.

SEO 생성 흐름:
1. seo_generate() 시도 (API/텍스트 처리)
   └─ 성공 → 생성된 메타데이터 사용
   └─ 실패 → fallback (기본값 또는 부분 데이터)
      ├─ 크롤된 제목 + 기본 설명 + 기본 이미지
      └─ 아무것도 없으면 → 최소 구조(페이지 ID, 발행일)

이렇게 하면 SEO 생성이 실패해도 게시글이 여전히 데이터베이스에 저장되고, 웹에도 노출된다. 메타데이터가 최적화되지는 않았지만, "노출이 안 된다" 같은 완전한 장애는 피한다.

여러 봇에 걸친 일관된 구현

ssul/publish_crawl.pywerebridge-build/sync-posts-to-db.py 두 파일이 변경된 이유는, 같은 SEO 생성 로직을 쓰는 두 개의 독립적인 크롤러가 있었기 때문이다. 처음엔 각 파일에서 개별적으로 seo_generate를 호출하고 있었을 텐데, 한쪽에만 fallback을 넣으면 다른 쪽은 여전히 실패에 취약해진다.

이런 상황은 보통 두 가지 선택지가 있다:

방식 장점 단점
각 파일에 로직 추가 빠르고 즉시 효과 중복 코드, 향후 유지보수 어려움
공통 함수 추상화 DRY 원칙, 한 곳 관리 리팩토링 시간, 팀과 협의 필요

지금은 각 파일에 fallback을 추가했는데, 이건 "긴급 안정화" 관점에서는 합리적이지만, 나중에 공통 유틸리티 함수로 정리할 후보가 됐다. 팀과 코드리뷰할 때 이런 점을 짚고 넘어가는 게 좋다.

회고: 외부 의존성과 resilience

외부 API나 제3자 라이브러리에 의존하는 작업은 반드시 실패 시나리오를 염두에 두고 코드를 짜야 한다. 특히 배치/크롤링 같은 백그라운드 작업은 수동 개입이 어렵고, 한번 실패하면 몇 시간 이상 방치될 수 있다.

"seo_generate가 실패할 일은 거의 없을 거야"라는 낙관은 위험하다. SEO 메타데이터 생성은 거의 항상 외부 API(이미지 다운로드, 텍스트 요약 등)에 의존하고, 네트워크는 항상 불안정하다. 처음부터 "언제 실패할까"를 고민하고 fallback을 설계하는 게, 나중에 장애 대응 시간을 대폭 줄인다.

또 하나 배운 점은, 여러 시스템에 걸쳐 같은 문제가 나타났다는 건 그 문제가 구조적이라는 신호라는 거다. 한 곳만 실패했으면 "그 부분 개발자의 미숙함"일 수 있지만, 두 곳이 모두 영향받았으면 "공통된 외부 의존성의 취약점"이다. 이럴 땐 근본 원인 분석과 함께 여러 지점을 동시에 보강하는 게 맞다.


🛒 이 글과 어울리는 추천 상품

*위 링크는 쿠팡파트너스 활동의 일환이며, 일정액의 수수료를 제공받을 수 있습니다.

댓글 0

첫 댓글 달아줘.