You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[FB-260] Internal MQ publisher confirm이 SaveChanges·NotifySaved를 막아 문파·그룹·저장이 멈춤 #681
Write-back: Redis-first 저장소의 SaveChangesAsync가 write-back 메시지를 RabbitMqService.PublishAsync로 동기 대기한다. publisher confirm이 무응답이면(쿼럼 과반 상실·디스크/메모리 block·브로커 hang) 예외도 안 나고 요청이 멈춘다. catch는 throw된 경우만 write_back_failure로 간다.
NotifySavedAsync: FB-132 수정으로 publish 예외는 삼키지만, confirm 대기는 그대로다. 문파자금·그룹·보관함·메일 등에서 Redis/DB 반영 뒤에도 응답 전에 기다리고, 문파·그룹은 분산 락을 쥔 채 기다린다.
둘 다 프로세스 단일 _channelLock이라 한 요청이 confirm에 붙잡히면 같은 파드의 다른 Internal publish(킥·공지·다른 저장)도 줄을 선다.
로그 브로커(FB-252)와는 별 채널(RabbitMQ:Internal)이지만, 장애 조건·락·무제한 confirm은 동일하다.
영향
Internal MQ 정지 → 캐릭터/문파/밴 등 Redis write-back이 포함된 SaveChanges가 hang → 로그인 저장·문파 입출금·그룹 조작·보관함 생성이 게임 HTTP 제한을 넘겨 실패.
문파·그룹 락을 쥔 채 NotifySaved가 멈추면 같은 문파/그룹의 다른 요청까지 연쇄 대기.
Redis에는 이미 반영된 뒤일 수 있어(문파자금 RequestId 멱등) 복제보다 가용성 정지가 핵심(FB-132와 직교).
수정 방향
Write-back: 요청 경로에서 confirm 대기하지 않기. 상한 있는 Channel에 적재 후 BackgroundService가 발행(실패 시 기존 write_back_failure 경로). 최소안: Publish에 1~2초 CancellationToken·짧은 연결 타임아웃.
NotifySaved: 저장 완료 응답을 먼저 돌리고 알림은 fire-and-forget/outbox(또는 같은 짧은 타임아웃). 분산 락은 SaveChanges 직후·NotifySaved 전에 해제.
FB-252(LogService)와 같이 publisher confirm tracking을 요청 경로에서 끄거나, confirm에 명시 데드라인을 둔다.
Activity
fix: queue side work and drop old tables #670 #680 #681 #682 #683
boyism80 commentedon Oct 16, 2026
[FB 리뷰어]
ce5d1119d에서 RabbitMqService가 Channel+HostedService 백그라운드 publish로 바뀌어 요청 경로의 publisher confirm 대기가 제거됐습니다. WriteBack은 FullMode=Wait·onFailure→RecordFailure로 런타임 실패는 기록됩니다. SaveChanges/NotifySaved hang(본문)은 해결로 닫습니다. 종료 시 인메모리 큐 유실·onFailure 미호출은 별도 FB-263으로 추적합니다.