Skip to content
isdnetworks
Go back

다섯으로 수렴한 실패 사유

대량 재전송을 100건씩 나눠 돌렸다. 웨이브마다 몇 건씩 실패해서 그때마다 로그를 조회해 사유를 분류했다.

Table of contents

Open Table of contents

결과 — 다섯으로 모인 사유

몇 웨이브를 돌리니 사유가 모였다.

카테고리와 옵션 매핑 불일치   가장 빈번
카테고리 코드 무효
옵션명 중복
상품 옵션 정보 없음
무음 스킵

무음 스킵 까지 다섯 종이 반복해서 나오고 새 사유가 더 나오지 않았다.

새로운 것이 안 나온다는 것 자체가 정보였다. 남은 웨이브에서도 이 다섯 안에서 실패할 것이라고 볼 수 있게 된다.

비율이 안정적이었다

실패율도 세어 봤다.

100건 웨이브 기준 2~3%

100건 짜리 웨이브마다 비슷하게 나왔다.

[비율을 모름]  얼마나 걸릴지 모름
[2~3%]        웨이브당 2~3건의 판정·원복

비율이 정해지면 남은 작업량을 미리 계산할 수 있다.

100건 웨이브를 열 번 돌리면 20건에서 30건의 후속 작업이 나온다는 뜻이다. 그만큼의 시간을 일정에 미리 넣어 둘 수 있게 됐다.

조치 — 사유별 사전 게이트

사유가 다섯으로 정해지니 미리 거를 수 있는 것이 보였다.

[전송 후 실패]  실패 처리 → 원복 → 재작업
[사전 게이트]   대상에서 미리 제외

각 사유를 전송 전에 확인 가능한 조건으로 바꾸면 된다.

카테고리 코드 무효   →  코드 유효성 사전 확인
옵션 정보 없음       →  옵션 존재 확인
옵션명 중복          →  중복 검사

카테고리 코드 무효 부터 옵션명 중복 까지 넷은 우리 쪽 자료만으로 판정할 수 있었다.

미리 거르면 보내는 건수가 줄고 상대 쪽 부담도 준다. 다만 그 조건이 틀리면 보낼 수 있는 건까지 빠지므로 거른 건수를 따로 세어 실패했을 수와 맞는지 대조했다.

다섯째가 달랐다

무음 스킵만 성격이 달랐다.

배치 호출은 200으로 수락
실패 목록도 비어 있음
그런데 생성 작업 자체가 안 만들어짐

200 을 받았는데 아무것도 안 생긴다.

[다른 넷]  작업이 생기고 실패 → 실패 로그가 남음
[무음 스킵]  작업이 안 생김 → 로그가 없음

stuck_reason 을 채우는 조회로는 이 종류가 잡히지 않는다.

앞서 정리한 것과 같은 모양이다. 오류는 목록에 남고 미발생은 아무 데도 안 남는다.

검증 — 건수 대조

없는 것을 찾으려면 다른 방법이 필요했다.

전송한 대상 목록
    vs
실제로 생성된 작업 목록

보낸 COUNT(*) 와 생성된 COUNT(*) 를 맞춰 보면 그 차이가 무음 스킵 이다.

[로그 기반]  실패한 것을 찾음
[건수 대조]  없어진 것을 찾음

두 방법이 서로 다른 것을 잡으므로 로그만 보면 다섯 중 넷만 보인다.

분류한 사유는 작업 표에 컬럼을 두고 웨이브마다 기록했다.

UPDATE tracking SET stuck_reason = ? WHERE product_id = ?;

stuck_reason 을 쌓아 두니 분포를 볼 수 있게 됐다.

SELECT stuck_reason, COUNT(*) FROM tracking
 WHERE stuck_reason IS NOT NULL GROUP BY 1;

기록하지 않고 웨이브마다 로그만 봤으면 사유가 다섯인지 열인지 몰랐을 것이다. 한 웨이브의 실패는 흩어져 보이고 열 웨이브의 실패는 분포를 만든다.

대응 — 재개 지점을 조건으로

여러 웨이브를 돌리니 어디부터 다시 할지가 필요해졌다.

SELECT product_id FROM tracking t
  JOIN products p ON p.id = t.product_id
 WHERE t.sent_at IS NULL
   AND t.rollback_at IS NULL
   AND t.stuck_reason IS NULL
   AND p.status = 'normal'
 ORDER BY t.product_id
 LIMIT 100;

sent_atrollback_atstuck_reasonstatus 네 조건이 남은 대상을 고른다.

[진행 번호로]  어디까지 했는지 기억해야 함
[조건으로]     테이블이 상태를 갖고 있음

조건이 상태를 표현하니 중간에 멈춰도 같은 쿼리로 이어지고 stuck_reason 이 채워진 건은 자동으로 빠진다.

ORDER BY 를 넣은 것은 실행마다 순서가 달라지지 않게 하려는 것이었다. 순서가 고정되면 같은 대상이 같은 묶음에 들어가고 문제가 생겼을 때 어디까지 갔는지가 확실해진다.

확인된 실패건을 전량 원복할 수 있다는 것이 이 방식의 전제였다. 원복이 되니 웨이브를 계속 돌릴 수 있었고 그렇지 않았으면 한 건의 실패가 사고가 됐을 것이다.

정리


Share this post on:

Previous Post
초 단위로는 순서를 못 가렸다
Next Post
전파가 환불에 매달려 있었다