Skip to content

[Bug] 얼굴 인식 프레임이 간격 기준 때문에 가끔 429(FACE_FRAME_RATE_LIMITED)로 거절돼요 #265

Closed

Description

@wook10

🐞 증상


운영(/admin/face)에서 프레임 요청 약 6%(48건 중 3건)가 429로 거절되고, 웹에 잠시 후 다시 시도해 주세요. 토스트가 뜨며 인식이 잠깐 멈춥니다.

🤔 문제 상황


웹과 서버가 "프레임 시작"을 서로 다른 시점으로 잽니다.

  • 웹은 보낸 시각부터 250ms를 셉니다. 응답이 250ms보다 늦으면 응답을 받자마자 다음 프레임을 보냅니다.
  • 서버(FaceRecognitionService.recognize)는 인증 → findOwned(DB)를 마친 뒤의 시각(now = clock.instant())을 last_frame_started_at으로 기록하고, 다음 프레임의 claimFrame에서 now - 200ms와 비교합니다.

이전 요청이 서버 앞단(업로드·인증·DB)에서 오래 머물면 서버가 기록한 시작 시각이 응답 직전으로 밀립니다. 응답 직후 웹이 보낸 다음 프레임은 서버 기준으로 200ms가 안 지나서 FACE_FRAME_RATE_LIMITED가 됩니다.
웹에서 막으려면 응답 뒤에 매번 200ms를 쉬어야 해서, 출석 처리 속도가 초당 약 4장에서 약 2.4장으로 떨어집니다.

✅ 요청


src/main/resources/application.yaml의 기본값을 1ms로 바꿔 주세요.

min-frame-interval: ${FACE_MIN_FRAME_INTERVAL:1ms}   # 200ms → 1ms
  • 0은 안 됩니다. FaceProperties.requirePositive가 0 이하를 거부해서 서버가 시작되지 않습니다.
  • 운영 .env만 고쳐서는 반영되지 않습니다. compose.prod.yaml의 server environment에 FACE_MIN_FRAME_INTERVAL이 없기 때문입니다. 그래서 기본값을 바꾸는 방식으로 요청합니다.
  • 1ms여도 과부하 보호는 그대로입니다.
    • 세션당 처리 중 프레임은 1개만 받는 잠금(frame_lock_token)이 남아 있습니다. 서버는 응답 전에 잠금을 풀고, 웹은 응답을 받은 뒤에만 보내므로 걸리지 않습니다.
    • 서버 전체 동시 처리 한도(FACE_MAX_CONCURRENT_FRAMES, 4)도 그대로입니다.
    • 실제 속도 상한은 웹 간격(250ms)입니다.
  • 함께 고칠 것: 위 줄의 주석과 프레임 인식 swagger의 "최소 간격 200ms" 설명. FaceSessionStoreTest 등 간격을 쓰는 테스트는 ./gradlew build로 확인해 주세요.

📌 해야 할 일


  • min-frame-interval 기본값 200ms → 1ms
  • 주석·swagger 설명 수정
  • ./gradlew build 통과 확인
  • main 반영·배포 뒤 운영 Network 탭에서 frames 429가 0인지 확인 (남는 429는 FACE_SERVICE_BUSY뿐이어야 함)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug버그 제보

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions