Skip to content

아이템 등록 한도를 실제 소비량 기반 사후 정산으로 정밀화 #910

Description

@m-a-king

#339 로 들어간 아이템 등록 한도는 등록 1건을 균일하게 1 차감하는 선불 예측 방식이다. 등록 시점엔 그 링크가 어느 경로로 풀릴지 알 수 없어 균일이 유일한 선택이었지만, 실제 소비량은 경로마다 크게 다르다.

  • 파서로 풀리는 경우 (무신사·29cm·지그재그 등): fetch 대역만
  • HEADLESS_FIRST 사이트 (kream·올리브영·에이블리): 헤드리스 렌더러 + residential proxy. 프록시는 사용량 과금이라 LLM 과 별개로 돈이 나간다
  • 파서 실패로 LLM fallback: Gemini 호출

균일 차감은 싼 경로를 과하게 깎고 비싼 경로를 덜 깎는다. 정상 사용자가 싼 사이트만 쓰는데도 한도에 닿거나, 비싼 사이트만 골라 쓰는 요청이 상대적으로 싸게 통과한다.

무엇을

파싱이 끝난 뒤 실제로 소비한 자원을 세어 정밀화한다. 등록 시점의 선불 차감(1)은 예약으로 두고, 확정 비용과의 차액을 파싱 완료 시점에 반영하는 구조다.

세는 대상:

  • LLM 을 실제로 탔는지 (파서로 풀렸으면 0)
  • residential proxy IP 로테이션 횟수
  • 헤드리스 렌더러 사용 여부

먼저 잡을 케이스: 캐시 재사용은 파싱이 아예 없다

정밀화 이전에 소비가 0 인데 1 을 깎는 경로가 이미 하나 있다. POST /wishlists 로 URL 을 등록할 때, 다른 사용자가 같은 상품을 이미 등록해 완성된 snapshot 이 살아 있으면 파싱 없이 그 값에 붙는다(reused=true, 즉시 READY). 새 파싱 작업이 큐에 들어가지 않는데 몫은 1 깎인 뒤다.

차감 기준이 "새 파싱 작업이 큐에 들어가는가" 이므로 이 경우는 0 이어야 맞다. 지금은 WishlistService.registerFromUrl 이 영속화 이전에 차감하는데, 재사용 여부는 영속화 트랜잭션 안에서 기존 item 을 찾아봐야 알 수 있어 차감 시점에는 알 수 없다.

방향이 보수적이라(과다 차감) 남용을 통과시키지는 않지만, 이 이슈의 "선불 예약 → 사후 정산" 구조가 들어오면 자연히 해소된다. 예약 1 을 확정 0 으로 정산하는 가장 단순한 케이스이므로, 정산 메커니즘의 첫 검증 대상으로 쓰기 좋다. (core#935 의 CodeRabbit 리뷰에서 지적됐고 그 PR 범위를 넘어 여기로 넘겼다.)

단계를 나눈다 — 관측 먼저, 차감은 나중

바로 차감으로 넣으면 사용자가 예측할 수 없는 차단이 생긴다. 계정 한도 30 기준으로:

  1. 사용자가 링크 15개를 담는다 → 등록 시점에 15 차감 → 잔액 15
  2. 응답은 전부 201 성공. 사용자는 "15개 더 담을 수 있겠네" 로 인식한다
  3. 그런데 그 15개가 전부 HEADLESS_FIRST 사이트였다 → 실제 비용은 건당 3
  4. 사후 정산이 차액 2씩, 총 30 을 추가로 깎는다 → 누적 45
  5. 16번째를 담으려 하면 429

사용자 입장에서는 "방금 15개 담았는데 왜 벌써 막히지" 가 된다. 자기 행동과 막힌 시점 사이에 보이지 않는 정산이 끼어서 예측이 안 된다. 실제 비용 분포를 모르는 상태에서는 이 상황이 얼마나 자주 터질지도 알 수 없다.

그래서 두 단계로 나눈다.

단계 내용 판단 근거
1. 관측 실제 소비를 메트릭으로 기록만 하고 차단에는 쓰지 않는다 비싼 경로가 전체의 몇 퍼센트인지, 사용자당 실제 소비 분포가 어떤지를 먼저 본다
2. 차감 관측 결과를 근거로 정산을 한도에 반영한다 그때는 한도 값도 실측 기반으로 다시 잡을 수 있다

구현 메모

선행 조건

  • extractor 가 소비 정보(LLM 사용 여부, 프록시 로테이션 횟수, 헤드리스 사용 여부)를 응답 계약에 실어야 한다

이 이슈의 전제가 흔들릴 수 있다

정직함 전환(core#932)으로 헤드리스·프록시가 기본 차단되고 허가 도메인 화이트리스트만 남았다. 화이트리스트 전환이 진행되면 비싼 경로 자체가 줄어들어 경로별 비용 편차가 좁아진다. 편차가 충분히 작아지면 균일 차감으로 충분해지고 이 이슈의 동인이 사라진다. 관측 단계를 먼저 두는 이유가 여기에도 있다 — 정밀화가 필요한지부터 데이터로 확인한다.

참고

Metadata

Metadata

Assignees

Labels

feat외부 가시적 새 기능

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions