ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Cloudflare Queues][운영] pull consumer에서 lease 재발급 뒤 ack batching과 retry delay_seconds를 어떤 순서로 검증하나
    기타개발지식/풀스택개발 2026. 8. 15. 20:15

    IT 리서치 노트

    [Cloudflare Queues][운영] pull consumer에서 lease 재발급 뒤 ack batching과 retry delay_seconds를 어떤 순서로 검증하나

    Cloudflare Queues pull consumer를 운영하다 보면 같은 메시지를 다시 봤을 때 lease가 만료된 건지, 새 lease로 다시 읽힌 건지, retry delay_seconds 때문에 짧게 되돌아온 건지 한 번에 섞이는 순간이 온다. 2026년 8월 15일 기준 Cloudflare 공식 문서를 다시 보면 visibility timeout 이후에는 기존 lease_id가 더 이상 유효하지 않고, pull consumer ack endpoint는 ack와 retry lease 배열을 같이 받으며, 메시지 단위 retry는 옵션을 통해 delay를 함께 남길 수 있다. 이 글은 lease 재발급 뒤 ack batching과 retry delay_seconds를 어떤 순서로 검증해야 pull consumer triage가 짧아지는지 정리한 것이다.

    1. 개요

    결론부터 말하면 pull consumer triage는 lease_id 유효성, ack batching 묶음, retry delay_seconds, backlog·message operations 기준선 순으로 보는 편이 가장 빠르다. 새 lease를 받기 전까지는 ack batching도, retry delay 해석도 모두 흔들린다.

    즉 첫 질문은 "이 lease가 아직 유효한가"이고, 두 번째 질문은 "이 ack 배열이 old batch인지 new batch인지", 세 번째 질문은 "retry가 즉시 돌아왔나 아니면 의도한 delay 뒤에 돌아왔나"다.

    2. 어디서 실제로 막히는가

    실무에서 흔한 실수는 네 가지다. 첫째, visibility timeout 이후에도 예전 lease_id를 들고 ack batching을 계속 시도한다. 둘째, 새로 pull한 batch의 lease와 예전 batch lease를 같은 ack 배열 메모에 넣는다. 셋째, attempts만 보고 retry가 즉시 돌아온 것인지 delay_seconds가 있었는지 기록하지 않는다. 넷째, backlog와 operations 기준선을 남기지 않아 원래 적체와 retry 폭주를 한 덩어리로 본다.

    Cloudflare pull consumer 문서는 visibility timeout 이후 기존 lease_id가 더 이상 유효하지 않다고 적고, 같은 문서에서 ack endpoint가 lease_id 배열로 ack와 retry를 같이 받는다고 설명한다. JavaScript API 문서는 메시지 단위 retry(options?)를 보여 준다. 이 셋을 같이 읽으면 pull consumer incident는 메시지 body보다 lease 시간축이 먼저라는 점이 분명해진다.

    특히 pull consumer는 replay와 운영 체크리스트가 push consumer보다 더 시간축 중심이다. 같은 idempotency key라도 old lease 기반 read인지, 새 fetch인지, explicit retry로 즉시 되돌아온 것인지에 따라 조치가 완전히 달라진다.

    • 증상: 같은 메시지가 계속 다시 보인다.
    • 실패: 만료된 lease_id를 계속 기준값으로 쓴다.
    • 막힘: ack batching과 retry delay를 같은 메모에 순서 없이 적는다.
    • 누락: backlog와 message operations 기준선을 안 남긴다.
    증상 먼저 볼 곳 판단 기준
    ack가 먹지 않는 것처럼 보인다 lease_id와 visibility timeout 만료된 lease인지 본다
    retry 후 바로 다시 읽힌다 delay_seconds 0 또는 짧은 지연인지 본다
    원래 적체인지 재시도 폭주인지 모르겠다 backlog와 operations 기준선 대비 spike 여부를 본다

    3. 실무에서 적용하는 순서

    실무 확인 순서는 네 단계면 충분하다. 먼저 dashboard나 API 응답 화면을 열고 현재 lease_id가 아직 유효한지 visibility timeout 기준으로 확인한다. 두 번째로 ack endpoint 요청 본문에서 새 fetch lease 묶음과 예전 lease 묶음을 분리해 적는다. 세 번째로 retry API를 호출했다면 delay_seconds 값을 같이 입력하고 저장한다. 마지막으로 backlog와 message operations 기준선을 조회해 같은 표에서 비교한다.

    1. lease_id 유효성을 먼저 확인한다.
    2. old batch와 new batch를 분리해 적는다.
    3. retry delay_seconds를 attempts와 함께 저장한다.
    4. backlog와 operations 기준선을 붙인다.

    이 순서를 쓰면 "다시 보였다"는 한 증상을 훨씬 짧게 자를 수 있다. old lease 만료라면 새 fetch로 넘어가면 되고, retry delay가 너무 짧다면 backoff 정책을 바꾸면 되며, backlog 급증이 동반됐다면 retry 폭주나 downstream 장애를 별도 branch로 떼면 된다. 콘솔에서 queue를 열고 metrics 메뉴를 클릭하고 lease_id 값을 복사하고 ack 요청 본문을 붙여 넣고 retry delay 값을 비교해 두면 다음 incident에서도 같은 화면 기준으로 다시 확인할 수 있다.

    incident 메모 예시
    lease_valid_before_ack=true|false
    old_batch_lease_ids=[...]
    new_batch_lease_ids=[...]
    retry_delay_seconds=120
    attempts=3
    backlog_before=184
    operations_before=retry_spike

    특히 pull consumer는 replay와 재배달을 같은 말로 적지 않는 편이 좋다. lease 재발급은 제어권 갱신이고, retry delay는 재등장 시점 조절이며, backlog는 전체 흐름이다. 이 세 층을 분리해야 incident가 짧아진다.

    4. 공식 문서와 예시 화면으로 확인하기

    첫 실제 자료는 pull consumer 문서의 핵심 문장이다. Cloudflare는 visibility timeout이 지나면 기존 lease_id가 더 이상 유효하지 않다고 분명히 적고 있다.

    visibility timeout 이후에는 예전 lease_id를 ack나 retry 근거로 계속 쓸 수 없다.
    visibility timeout 이후에는 예전 lease_id를 ack나 retry 근거로 계속 쓸 수 없다.

    즉 같은 메시지를 다시 봤을 때 첫 질문은 side effect보다 lease 유효성이다. 오래된 lease를 붙잡고 있으면 그 뒤 ack batching과 retry delay 판단도 전부 뒤틀린다.

    두 번째 공식 화면은 pull consumer ack endpoint 설명이다. pull consumer는 /ack 요청 본문에 ack와 retry용 lease_id 배열을 함께 보낼 수 있다.

    pull consumer ack batching은 lease_id 배열을 기준으로 ack와 retry를 같이 보낸다.
    pull consumer ack batching은 lease_id 배열을 기준으로 ack와 retry를 같이 보낸다.

    이 구조 때문에 lease 재발급 뒤에는 어떤 lease 묶음이 old batch였는지, 어떤 lease 묶음이 새 fetch에서 온 것인지 분리해 메모해야 한다. 배치 단위 ack를 편하게 쓰려다 오래된 lease를 섞으면 triage가 더 길어진다.

    세 번째 자료는 Message API다. Cloudflare는 메시지 단위에서 ack()와 retry(options?)를 제공한다고 적는다.

    ack와 retry는 같은 메시지 수명 안에서 다른 의미를 갖고, retry는 별도 옵션을 받을 수 있다.
    ack와 retry는 같은 메시지 수명 안에서 다른 의미를 갖고, retry는 별도 옵션을 받을 수 있다.

    따라서 pull consumer incident 메모에서 retry 횟수만 적는 것은 부족하다. 같은 메시지라도 언제 새 lease로 다시 읽혔는지, 어떤 delay_seconds로 retry했는지 같이 남겨야 시간축이 풀린다.

    실무에서는 lease 재발급 직후 점검 순서를 표로 고정해 두는 편이 빠르다. lease 유효성, ack batching 묶음, retry delay_seconds, backlog 기준선을 한 칸씩 나눴다.

    lease 재발급 뒤 pull consumer triage 순서를 정리한 표다.
    lease 재발급 뒤 pull consumer triage 순서를 정리한 표다.

    이미 backlog와 message operations 시간축 글을 읽었다면 이번 표는 그 안의 pull consumer 분기만 더 좁힌 것이다. 앞선 push vs pull replay 글과도 이어진다.

    마지막 자료는 메모 예시다. 핵심은 새 lease를 받은 뒤 ack 배열과 retry 배열을 섞어 적되, old lease와 new lease를 한 줄로 합치지 않는 것이다.

    lease 재발급 뒤 ack batching과 retry delay_seconds를 같이 남기는 예시다.
    lease 재발급 뒤 ack batching과 retry delay_seconds를 같이 남기는 예시다.

    이 정도 메모가 있으면 같은 메시지가 다시 보였을 때 visibility timeout 만료인지, retry 지연이 짧아서 즉시 돌아온 것인지, 아예 새 batch에서 다시 읽힌 것인지 훨씬 빨리 갈린다. 실제로는 대시보드를 열고 lease_id 값을 확인하고 ack 배열을 복사하고 retry delay_seconds를 입력하고 backlog 수치를 저장한 뒤 같은 표에서 다시 비교하는 순서가 가장 짧다. 화면 옆 표에 old batch와 new batch를 나눠 적고 값 칸을 같이 저장해 두면 다음 incident에서도 어떤 lease를 다시 열어야 하는지 바로 보인다.

    5. 주의사항과 리스크

    첫 번째 리스크는 만료된 lease_id를 계속 기준으로 삼는 것이다. 두 번째는 old batch와 new batch를 같은 ack 배열 메모에 넣어 증거를 섞는 것이다. 세 번째는 delay_seconds를 빼고 attempts만 남겨 재등장 시간축을 설명하지 못하는 것이다.

    운영 전에 확인할 때는 최소한 lease 유효성, retry delay, backlog 기준선을 한 줄 메모로 남기는 편이 좋다. 이 세 줄이 없으면 pull consumer incident는 거의 항상 길어진다.

    • lease 유효성을 body보다 먼저 본다.
    • ack batching은 old batch와 new batch를 섞지 않는다.
    • retry delay_seconds를 항상 같이 남긴다.

    6. 결론

    pull consumer에서 lease 재발급 뒤 같은 메시지를 다시 봤다면 먼저 lease 유효성부터 자르는 편이 맞다. 그다음 ack batching 묶음과 retry delay_seconds를 분리하고 backlog 기준선을 붙이면, 재시도 시간축과 실제 중복 증상을 훨씬 빨리 설명할 수 있다.

    • lease_id 유효성부터 확인한다.
    • ack batching과 retry delay를 따로 적는다.
    • backlog 기준선으로 원래 적체와 재시도 반응을 나눈다.

    7. 참고 링크

    1. https://developers.cloudflare.com/queues/configuration/pull-consumers/
    2. https://developers.cloudflare.com/queues/configuration/javascript-apis/
    3. https://developers.cloudflare.com/queues/observability/metrics/
Designed by Tistory.