Outbox의 경우 오류를 알아채기가 쉽지 않다. 왜냐하면 DB에 failed 항목이 계속 누적이 될 뿐, 실제 서비스 동작은 이상 없는것처럼 보일 수 있기 때문이다. 따라서 모니터링이 필요하다. 이전 글 https://dean83.tistory.com/407 과 연계되는 부분이 있다.
OutboxMetirics 컴포넌트
@Component
@RequiredArgsConstructor
public class OutboxMetrics {
private final MeterRegistry registry;
private final AtomicInteger pendingCount =
new AtomicInteger(0);
@PostConstruct
void init() {
Gauge.builder("outbox.pending.count", pendingCount, AtomicInteger::get)
.description("Pending outbox events")
.register(registry);
}
public void setPendingCount(int count) {
pendingCount.set(count);
}
public void incrementSent() {
registry.counter("outbox.sent.total").increment();
}
public void incrementFailed() {
registry.counter("outbox.failed.total").increment();
}
public Timer.Sample startPublishTimer() {
return Timer.start(registry);
}
public void recordPublishLatency(Timer.Sample sample) {
sample.stop(registry.timer("outbox.publish.latency"));
}
}
Poller 에서 사용
@Transactional
public void poll() {
List<Outbox> batch =
repository.findPendingForUpdate(100);
metrics.setPendingCount(batch.size());
for (Outbox outbox : batch) {
Timer.Sample sample = metrics.startPublishTimer();
try {
publisher.publish(outbox);
outbox.markSent();
metrics.incrementSent();
} catch (Exception e) {
outbox.markFailed();
metrics.incrementFailed();
} finally {
metrics.recordPublishLatency(sample);
}
repository.save(outbox);
}
}
Metric설명
| kafka.producer.record.send.total | 전송 시도 |
| kafka.producer.record.error.total | 전송 실패 |
| kafka.producer.request.latency.avg | 브로커 응답 지연 |
| kafka.producer.retries.total | 재시도 횟수 |
Grafana 설정값 설명
- outbox_pending_count : 계속 증가하면 장애
- 전송 성공/실패
- rate(outbox_sent_total[1m])
- rate(outbox_failed_total[1m])
프로메테우스, 그라파나 설정은 https://dean83.tistory.com/403 여기를 참조 한다.
'Backend > SpringBoot' 카테고리의 다른 글
| SSE 예제 (0) | 2026.01.14 |
|---|---|
| 순수 WebSocket (+Protobuf) (0) | 2026.01.14 |
| Kafka-Outbox 전략 구현 예 (0) | 2026.01.12 |
| Kafka (+Kafka UI) 설정 및 연동 (오류 핸들링 포함) (0) | 2026.01.12 |
| Prometheus + Grafana 를 이용한 모니터링 (0) | 2026.01.05 |