1편: 운영 로그에서 비동기 구간만 traceId가 빠졌다: MDC와 TaskDecorator로 해결하기에서 만든 TaskDecorator를 점검하다가, finally의 MDC.clear()가 요청 스레드의 traceId에 영향을 주는 것은 아닌지 확인해 본 과정을 정리합니다.TL;DR거부 정책이 기본값(AbortPolicy)이라면 MDC.clear()는 풀 스레드의 MDC만 비우므로 요청 스레드에 영향이 없습니다.하지만 CallerRunsPolicy를 쓰면 작업이 요청 스레드에서 직접 실행되어, clear()가 요청 스레드의 traceId까지 지웁니다.해결은 실행 전의 MDC를 prev로 저장했다가 finally에서 복원하는 것입니다. 풀 스레드에서는 기존 동작과 같습니다.1. 점검하게 된 계기1편에서..
요청마다 traceId를 MDC에 심어 로그를 추적하고 있었는데, CompletableFuture.supplyAsync 구간의 로그에서만 traceId가 빠지는 문제를 겪었습니다. 원인과 해결 방법을 정리합니다.TL;DRMDC는 ThreadLocal 기반이라, 스레드가 바뀌는 supplyAsync 구간에서는 traceId가 사라집니다.해결의 핵심은 작업을 제출하는 스레드에서 복사하고, 실행하는 스레드에서 주입한 뒤, 끝나면 정리하는 것입니다.ThreadPoolTaskExecutor에 TaskDecorator를 적용하고, supplyAsync와 thenApplyAsync에 executor를 반드시 지정하면 됩니다.1. 상황필터에서 traceId를 MDC에 넣고, logback 패턴(%X{traceId:-S..
사내 암복호화 유틸리티를 정리하다가, 예전에 안다고 생각했던 checked/unchecked 예외 개념이 다시 헷갈렸다. 막상 직접 설계하려니 설명이 안 되는 부분들이 있었는데, 헷갈렸던 순서대로 정리해본다."unchecked는 안 잡아도 되는 거 아니야?"checked는 catch나 throws가 없으면 컴파일이 안 되고, unchecked는 그런 제약이 없다 — 여기까지는 제대로 알고 있었다. 문제는 그다음이었다. "그럼 unchecked는 신경 안 써도 되는 거네"로 잘못 결론을 냈던 것이다.다시 짚어보니 이건 완전히 다른 이야기였다. "컴파일러가 강제하지 않는다"와 "실제로 발생했을 때 아무 일도 안 일어난다"는 다른 문제다. unchecked 예외는 throws에 적든 안 적든 똑같이 발생하고,..
문제의 시작리워드 배치가 파트너사 실적을 가져오다가 13개월 중 8개월꼴로 통째로 skip되는 사고가 있었다. 처음엔 타임아웃과 서킷브레이커 임계값을 손보면 될 줄 알았는데, 결국 손댄 곳은 "임계값"이 아니라 "이 자리에 서킷브레이커를 쓴다는 설계" 그 자체였다.문제: 13개월 중 8개월이 조용히 비어버렸다배치는 매 실행마다 미처리 월을 찾아 최대 13개월치를 순회하며, 월별로 파트너사 실적 조회 API를 호출해 회원 포인트를 적립한다. 재시도가 붙어 있는데도 결과적으로 서킷브레이커(모든 월이 공유하는 하나의 인스턴스)가 열려서 그 달 데이터가 통째로 skip되는 일이 반복됐다.이번이 처음이 아니었다는 게 이 사고를 다르게 보게 만들었다. 한 달 전에도 같은 유형의 사고("slow-call 임계값이 너..
한 줄 요약rewardJob이 2026-08-17 실행 이후 20일 연속 read=0 write=0 skip=0으로, 아무것도 처리하지 않은 채 COMPLETED로 조용히 끝났다.원인은 서로 다른 두 레이어에 겹쳐 있었다.레이어 1 — RewardOrderReader/RewardOrderProcessor가 StepScope 빈인데, Step 실행마다 상태가 제대로 리셋되지 않는 문제.레이어 2 — Spring Batch 6.0.0의 ChunkOrientedStep.chunkTracker가 한 번 소진되면 컨테이너를 재시작하기 전까지 영구히 고정되는 프레임워크 버그 (upstream #5126).1차 수정(레이어 1)은 실제로 필요한 수정이었고 정상 동작했다. 다만 증상의 절반만 설명하고 있었다.증상rew..
AI 에이전트를 안정적으로 제어하기 위한 구조: 하네스(Harness)와 컨텍스트 엔지니어링AI 에이전트(Agent) 기술을 도입할 때 자주 겪는 문제 중 하나는 에이전트가 예상치 못한 비정상 루프에 빠지거나, 정제되지 않은 결과를 출력해 시스템이 제어 불능 상태가 되는 점입니다.에이전트가 높은 자율성을 바탕으로 문제를 해결하는 과정에서 생기는 불확실성을 통제하기 위해 '하네스(Harness)'와 '컨텍스트 엔지니어링(Context Engineering)' 개념이 중요하게 다루어집니다. 두 개념의 역할과 차이, 그리고 기술적 발전 맥락을 정리합니다.1. AI 에이전트 시스템의 발전 과정AI 기술은 모델의 응답 정밀도를 높이는 단계에서 시작해, 자율적으로 실행하고 이를 통제하는 방향으로 진화했습니다.Pla..
- Total
- Today
- Yesterday
- hazelcast
- 프로젝트
- Java
- 동기/비동기
- 데이터적합성
- SQL
- 스케줄러
- 도커
- 에러
- ncp
- SpringBoot
- OpenFeign
- JPA
- 이슈
- 컨테이너
- 로그
- spring
- Cache
- 이슈해결
- MySQL
- 실무경험
- spring batch
- Linux
- Lock
- docker
- dockerfile
- 트랜잭션
- mybatis
- Quartz
- 알고리즘
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |