Commit 79aa8ea
authored
feat : 장애 대응 및 재처리 로직을 적용한 고가용성 알림 시스템 구축 (#195)
* fix : mysql 드라이버 불러오지 못하는 문제 해결
- `runtimeOnly` 사용 시 실행할 때에만 classpath에 올라가므로, IDE/빌드 환경에 따라 드라이버를 찾지 못하는 경우가 발생함
* feat : MongoDB 트랜잭션 도입 및 적용 테스트
- mongo db에 트랜잭션을 도입하기 위해서 replica set 설정을 수행하고, 실제로 적용되었는지 확인하기 위해 테스트 수행
- 정상적으로 동작하는 것 확인
- 실제 배포 환경에 있는 mongo db 백업 후 replica set 적용해야 함
* refactor : 트랜잭션 관련 코드 개선
- 기존 코드에서는 @transactional 메서드 안에서 DB 저장과 알림 발송이 순차적으로 일어난다.
- 알림이 발송된 직후, 커밋 단계에서 데이터베이스 문제 등 예측하지 못한 이유로 트랜잭션이 롤백된다면?
- 사용자는 알림을 받았지만, 정작 DB에는 해당 알림 데이터가 존재하지 않는 유령 데이터가 발생한다.
- 스프링에서 제공하는 @TransactionalEventListener를 사용하여 트랜잭션 성공 이후 알림이 발송되는 것을 보장하고, 코드의 관심사를 분리했다.
* feat : 알림 데이터 저장 시 DB 장애 시를 대비하여 서킷 브레이커 패턴 적용
- 메시지를 처리하는 과정에서 DB에 장애가 발생했을 시, 처리되지 않은 메시지가 누적되어 시스템이 과부하되는 것을 방지하기 위해 서킷 브레이커 패턴을 적용했다.
- Resilience4j 라이브러리 사용
- 테스트 코드를 통해 실제로 서킷 브레이커가 동작하는지 확인함
* feat : 서킷 브레이커 정상적으로 동작하도록 수정
- 서킷 브레이커에 대해 잘못 이해하고 있는 부분이 있어서 테스트 코드에 오류가 있었음
- 실제로 발생할만한 예외가 던져지도록 하고, 해당 예외가 fallback 메서드를 통해 NotificationException으로 던져지는 것을 확인하도록 함
- 새로 구현된 NotificationProcessLog document에 데이터가 있으면 서킷 브레이커 테스트 중 에러가 발생함. 추후 이 점 유의해야 함
* feat : consumer에서 메시지 처리 중 에러가 발생했을 때를 대비해 상태 기반 재처리 로직 구현
- consumer에 메시지가 들어오면 로그를 db에 적재 (PENDING)
- 이후 메시지 처리 성공 여부에 따라 상태를 업데이트함 (SUCCESS, FAILD)
- 실패했던 메시지들은 별도의 스케쥴러에서 다시 재시도 처리함
- 만약 특정 횟수의 시도 이후에도 실패한다면 PERMANENTLY_FAILED로 상태 변경
- 해당 메시지들은 추후 개발자가 직접 처리할 수 있도록 함 (Grafana 등 연동)
* feat : 테스트 코드가 항상 성공하도록 수정
- AfterEach 추가해서 어떤 시점에 테스트를 실행해도 전부 통과할 수 있도록 함
- 그러나 DB를 매번 초기화하므로 개발, 배포 환경에 영향이 가지 않도록 disabled 해뒀음
* feat : 스크립트 shebang 추가
* feat : Mongo 트랜잭션 매니저 Bean 이름 충돌 문제 해결
- MongoDB 트랜잭션 매니저를 transactionManager라는 기본 이름으로 등록하면, JPA 등 다른 데이터소스용 기본 트랜잭션 매니저와 충돌하거나 덮어써서 애플리케이션 부팅 실패 혹은 잘못된 매니저 선택으로 이어질 수 있음
* feat : 커스텀 메시지 ID 누락 시 무한 재시도 위험 문제 해결
- null 예외 처리 추가해서 커스텀 message id 헤더가 존재하지 않는 메시지가 무한히 재시도 되는 상황을 방지함
* refact : 메시지 처리 메서드 호출 시 messageId에 해당하는 데이터가 없을 경우 로그 추가
- finishProcessing, finishProcessing 메서드의 findById()가 비어있다면 `ifPresent` 블록은 아무 일도 하지 않고 넘어감
- 개발자는 에러가 발생했다는 사실조차 모르고 넘어감 -> 조용한 실패(Silent Failure)
- finishProcessing에서 로그가 없다는 것은 비즈니스적인 문제(사용자 잘못 등)가 아니라, 시스템 내부의 심각한 상태 불일치를 의미
- 따라서 NotificationException보다는 IllegalStateException이나 SystemException 같은 런타임 예외를 사용하는 것이 의미상 더 적합함
* refact : 더 이상 사용되지 않는 테스트 코드 disabled1 parent 08fedac commit 79aa8ea
File tree
23 files changed
+909
-76
lines changed- scripts
- src
- main
- java/org/ezcode/codetest
- application/notification/exception
- infrastructure
- mongo/config
- notification
- event
- model
- publisher
- repository
- service
- resources
- test
- java/org/ezcode/codetest/infrastructure/notification
- resources
23 files changed
+909
-76
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
| 46 | + | |
46 | 47 | | |
47 | 48 | | |
48 | 49 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
55 | 55 | | |
56 | 56 | | |
57 | 57 | | |
58 | | - | |
| 58 | + | |
59 | 59 | | |
60 | 60 | | |
61 | 61 | | |
| |||
120 | 120 | | |
121 | 121 | | |
122 | 122 | | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
123 | 127 | | |
124 | 128 | | |
125 | 129 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 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 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 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 | + | |
Lines changed: 9 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
27 | 36 | | |
Lines changed: 2 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
| 15 | + | |
| 16 | + | |
16 | 17 | | |
17 | 18 | | |
18 | 19 | | |
| |||
Lines changed: 15 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
Lines changed: 12 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
Lines changed: 72 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 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 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
0 commit comments