Engineering Notes
삽질, 고민, 결정의 순간들 — 나중의 나와 팀을 위한 메모
72시간 마감 안에 4번 리마인더, 선생님이 응답하면 즉시 취소. @Scheduled 폴링으로는 개별 취소가 안 된다. Quartz JDBC Store로 스케줄 상태를 외부화하고, 도메인 모델을 깔끔하게 유지한 과정.
NCP 장애가 나도 API는 성공해야 한다. 알림은 부가 기능이고, 장애 도메인은 격리되어야 한다. @TransactionalEventListener + @Async 조합을 고른 이유, 그리고 언제 Outbox 패턴이 필요해지는지.
TEXT 컬럼이 상태 변경 쿼리마다 딸려온다. @Basic(fetch = LAZY)를 붙여도 Hibernate는 무시한다.
단순 필드는 프록시를 쓸 수 없기 때문이다. Bytecode Enhancement 플러그인으로 실제 lazy load를 구현한 과정.
App Runner → GCP Cloud Run 호출이 정확히 10초에 timeout. NAT Instance에서 curl은 되는데 왜? FORWARD 체인 policy가 DROP이었다. NAT Instance 자신의 트래픽(OUTPUT)과 라우팅되는 트래픽(FORWARD)은 다른 체인을 탄다.
EnvironmentPostProcessor가 아무 로그도 남기지 않고 조용히 실패하고 있었다.
bootJar를 열어보니 AWS SDK JAR이 없었다. Gradle implementation vs api의 차이가 만들어낸 삽질 기록.
7개 레포 MSA로 출발했다. 중복 코드, 다수 레포 동시 변경, 월 20만원 인프라 비용 — 직접 운영하면서 문제들이 쌓였다. 서비스 규모에 맞지 않는 구조라고 판단하고, Domain 추상화 기반 Modular Monolith로 전환한 과정.