
게시 시점 이전에 기사 재고를 감시하는 백프레셔 (Backpressure) 설계 - 구현 절차
요약
기사 자동 게시 시스템의 안정성을 확보하기 위해 입력 큐의 재고를 감시하고 보충하는 백프레셔(Backpressure) 설계 방식을 설명합니다. 프로세스를 4단계로 분리하여 상태를 구조화하고, 데이터 계약을 통해 중단된 지점부터 재개할 수 있는 구현 절차를 다룹니다.
핵심 포인트
- 미공개 재고의 최소 수(예: 7일분)를 유지하는 생산 불변 조건 설정
- 생성, 품질, 조작, 결과의 4단계 완료 조건 분리를 통한 상태 관리
- 자유 형식 로그 대신 구조화된 JSON을 통한 공정 간 계약(Contract) 준수
- 중간 정지 시 마지막 통과 단계를 기록하여 정확한 지점에서 재개 가능
게시 시점 이전에 기사 재고를 감시하는 백프레셔 (Backpressure) 설계 - 구현 절차
자동 처리는 스케줄 등록만으로는 안정적이지 않습니다. 스케줄러가 정상이라도 입력 큐 (Input Queue)가 비어 있다면 기사는 공개되지 않습니다.
이 기사에서는 「구현 절차」의 관점에서 입력, 처리, 결과물, 공개 결과를 분리하는 방법을 정리합니다. 메커니즘 전체의 이유까지 다룹니다.
기본 방침
미공개 재고의 최소 수를 생산 불변 조건으로 설정하고, 게시 시점 이전에 보충합니다.
프로세스가 종료되었다는 것과 목적을 달성했다는 것은 별개입니다. 초안 생성, 품질 검사, 외부 공개, 공개 URL 확인을 개별적으로 기록합니다. 상태를 분리함으로써, 다음 날의 처리를 추측이 아닌 증거를 바탕으로 재개할 수 있습니다.
구현 절차
매체별로 검증된 미공개 후보를 카운트한다
7일분의 버퍼를 유지한다
재고 부족을 공급 장애로 기록한다
각 공정은 다음 공정이 기계적으로 판단할 수 있는 JSON을 출력합니다. 자유 형식의 로그에만 의존하면, 재실행 시 어디까지 완료되었는지를 인간이 추측해야 합니다.
for provider in providers:
while unpublished_count(provider) < 7:
generate_next_unique_candidate(provider)
중요한 것은 코드의 양이 아니라, 입력과 결과의 계약 (Contract)이 고정되어 있다는 점입니다. 성공뿐만 아니라 후보 부족이나 인증 대기 상태도 구조화하여 남깁니다.
완료 조건을 4단계로 분리
생성 완료: 본문, 메타데이터, 출처 정보가 존재함 -
품질 완료: 글자 수, 태그, 코드 예시, 중복 검사를 통과함 -
조작 완료: 허가된 runner가 대상을 한정하여 실행함 -
결과 완료: 실제 URL이나 외부 ID를 결과 파일로 확인함
중간 정지 시에는 마지막으로 통과한 단계와 다음 처리를 기록합니다. 처음부터 다시 시작하지 않고, 올바른 지점에서 재개할 수 있습니다.
자주 발생하는 실수
- CLEAN_HOLD가 상시적인 부족을 숨김
- 생성과 공개가 분리된 상태로 남음
- 일일 목표에 대해 소비물이 없음
재시도 횟수를 늘리기 전에, 어떤 상태라면 재시도가 가능한지를 결정합니다. 외부 공개 직전에는, 당일 공개되었는지, 제목과 본문 해시 (Hash)가 새로운지, 대상 초안이 이번에 작성된 것인지 확인합니다.
테스트 관점
- 동일한 입력을 2회 처리해도 후보가 중복되지 않음
- 이미 공개된 제목을 후보로 선택하지 않음
- 본문 해시 충돌 시에는 다른 각도로 전환함
- 결과물이 누락된 경우에는 성공으로 처리하지 않음
- 외부 URL이 없는 경우에는 공개된 것으로 기록하지 않음
- 7건의 재고를 밑돌면 게시 전에 보충함
일일 처리의 구체적인 예
게시 시각을 10시 30분이라고 가정합니다. 2시 30분의 공급 처리에서는 단순히 Markdown 파일을 세는 것이 아니라, source_packet.json과 candidate_audit.json이 갖춰져 있고, 모든 품질 체크가 참 (True)인 후보만을 미공개 재고로 카운트합니다. 재고가 7건 미만이라면, 부족한 수만큼 다른 주제나 각도를 선택하여 로컬에서 생성합니다. 이 단계에서는 외부 화면을 조작하지 않습니다.
10시 30분의 공개 처리에서는 재고의 맨 앞 항목을 1건 선택합니다. 선택 후에 공개된 제목과 정규화된 본문 해시를 다시 한번 읽습니다. 문제가 없다면 해당 후보로부터 하나의 초안 요청을 생성하고, 저장 결과에 포함된 제목과 초안 상태를 확인합니다. 공개 요청은 방금 생성한 동일한 초안만을 대상으로 합니다. 마지막으로 실제 URL에 도달했음을 결과 JSON에 저장하여 완료합니다.
이미지 생성에 실패한 경우, 본문 후보는 삭제하지 않습니다. cover_generation_failed로서 후보를 재고에 남깁니다. 인증이 만료된 경우에도 동일한 후보를 다시 만들지 않고 authentication_required로서 멈춥니다. 공개 버튼 실행 후 확인 단계에서 타임아웃이 발생한 경우에는, 다음 처리에서 외부 상태를 먼저 읽고, 미공개 상태임을 증명할 수 있을 때까지 재클릭하지 않습니다.
모니터링하는 수치
일일 모니터링에서는 다음을 별도로 기록합니다.
- 보충 전과 보충 후의 미공개 후보 수
- 새로 생성한 후보 수
- 제목 중복과 본문 중복으로 제외한 건수
- 외부 조작을 시작한 건수
- 실제 URL을 확인한 건수
- 마지막으로 통과한 공정과 정지 이유
「태스크가 기동된 횟수」만을 성공 지표로 삼으면, 후보가 0건인 상태로 매일 정상 종료되는 문제를 놓치게 됩니다. 공개 URL이 필요한 레인 (Lane)에서는 실제 URL 확인 건수가 1이 되어야 비로소 일일 목표 달성으로 판단합니다.
재기동 후의 복구
재기동 후에는 메모리상의 상태가 아니라 파일 결과물로부터 재개합니다. 후보 감사 (Candidate Audit)가 완료되어 있다면 생성을 생략하고, 초안 저장 (Draft Save) 결과가 있다면 새로운 초안을 만들지 않습니다. 공개 결과에 실제 URL이 있다면 당일 처리를 종료합니다. 이 순서에 따라 PC 재부팅이나 runner 정지가 발생하더라도, 외부 조작을 중복시키지 않고 계속 진행할 수 있습니다.
테스트에는 후보 0건, 손상된 JSON, 잔류 락 (Residual Lock), 공개 결과 없음 등을 포함합니다. 일일 운영에서 발생하기 쉬운 상황은 예외(Exception)보다 "처리는 끝났지만 목적물이 없는" 상태이기 때문입니다.
운영 체크리스트
- 입력원과 SHA-256이 기록되어 있음
- 제목과 본문의 중복 검사를 통과함
- provider와 action이 고정되어 있음
- 1일당 공개 상한을 초과하지 않음
- 결과 JSON에 실제 URL 또는 정확한 중단 사유가 있음
이러한 형태라면, 후보 생산과 공개를 독립시키면서 재고 수를 계약 (Contract)으로서 연결할 수 있습니다. 게시 시점에 후보가 없다면, 공급 공정을 실행한 후 재평가합니다.
관련된 실전 사례는 AI Compass Journal의 목록에서 확인할 수 있습니다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기