개발하는 일상

입맛대로 적용한 이벤트 드리븐 아키텍처(Event Driven Architecture) 후기 본문

개발 기록

입맛대로 적용한 이벤트 드리븐 아키텍처(Event Driven Architecture) 후기

롯데빙빙바 2023. 10. 16. 17:10

요약

장점

  • 코드의 연결이 느슨해진다
  • 유지보수가 쉬워진다

단점

  • 트랜잭션처리에 약하다
  • 코드를 보고 서비스 로직을 파악하는 게 쉽지 않다

 

어떤 문제가 있었나?

모듈형 구조만으로는 코드의 연결을 충분히 감당할 수 없었다.

우리 서버는 NestJS 기반의 모듈형 구조였다. 유저, 구매, 메세징 등 역할마다 모듈을 만들었다. 알아보기 쉽고 유지보수를 편하게 하기 위해서 모듈은 최대한 서로 연결되지 않도록 하고 싶었다. 하지만 당연하게도 서비스 로직은 그렇지 않은 경우도 많다. "구매를 완료하면 유저 정보가 업데이트되고 알림메세지를 보낸다." 앞서 말한 3가지 모듈이 전부 쓰여야 하는 "구매완료"라는 서비스 로직이다. 처음에는 모듈 멤버 중 다른 모듈에서 꼭 쓰여야 하는 멤버만 export 해서 사용하는 식으로 버텼다. 얼마 안 가서 export 하는 멤버가 많아지고, 가져다 쓰는 모듈도 많아지면서 연결이 끈끈해지기 시작했다. 문제임을 느꼈다.

 

그리고 같은 팀 동료 타코가 이벤트 드리븐 아키텍처를 제안해주셨다.

 

 

기존 모듈형 구조 vs 이벤트 드리븐 아키텍쳐

이벤트 드리븐 아키텍처(Event Driven Architecture, 이하 EDA)라고 해서 기존 모듈형 구조를 버린 건 아니다. 모듈 간 연결이 발생하는 부분에 EDA를 도입한 모양새이다. 연결이 발생할 때 모듈형 구조와 EDA가 어떤 차이가 있는지 비유를 들어보자.

그림1. 모듈구조 VS EDA


회원 모듈과 구매 모듈이 있다고 하자. 회원이 어떤 상품을 구매하면, 회원의 권한을 업데이트해야 한다. 기존의 모듈 구조에서는 구매 모듈에서 회원 모듈의 회원 권한을 업데이트하는 멤버를 빌려와서 로직을 처리한다.
EDA에서는 이벤트 관리부가 새로 만들어진다. 회원 모듈과 구매 모듈은 멤버를 빌려주지 않고, 이벤트 관리부를 통해 구매가 일어났다는 사실을 알리거나, 알림 받는다. 회원 모듈은 구매 알림을 받으면 모듈 안에서 회원 권한을 업데이트한다.

 

 

써보며 느낀 이벤트 드리븐 아키텍처의 장점

이 구조 때문에 내가 큰 노력을 들여 생각하지 않아도 모듈러 하게 코드를 작성하게 되는 것을 느꼈다. 이전에는 "모듈러 하게 짜야지"라고 마음먹어도 실제로 구현하다 보면 다른 모듈의 멤버를 쉽게 빌려올 수 있다 보니 나도 모르게 그런 방향으로 가기가 쉬웠다. 시간의 압박이 있으면 더 쉽게 그렇게 됐다. EDA를 도입하고 구조가 정해져 있어서 생각력(?)을 아낄 수 있는 것이 내가 느낀 가장 좋은 점이었다.


유지보수가 쉽다는 것도 매우 체감되었다. 만약 회원의 구조가 변하면, 모듈 위주로 변경을 체크하면 된다. 불가피하게 빌려준 멤버가 있더라도 기존 모듈구조보다 훨씬 적기 때문에 체크해야 할 것이 줄어든다. 이벤트를 보통 서비스 로직과 비슷하게 만들기 때문에, 서비스 로직에 수정이 생겼을 때 이벤트만 추가로 발생시켜서 해결했던 것이 기억난다.

 

 

이벤트 드리븐 아키텍처의 단점

첫 번째로 트랜잭션처리가 어렵다는 점이다. 기존 방식처럼 빌려와서 처리할 수도 있고, 모듈 내에 retry/rollback 기능을 추가해서 해결할 수도 있다. 트랜잭션처리가 서비스에서 아주 중요한 로직에서는 그렇게 했지만, 그렇지 않다면 로깅만 빡세게 했다. 문제가 발생하면 수동으로 처리할 수 있을 만큼 서비스 규모도 작았고, 수정도 자주 일어나기 때문에 트랜잭션 처리를 힘들게 해 놔도 버리게 될 수도 있었기 때문이다.

 

두 번째로 보통 "코드만 보고 서비스 플로우를 파악하기가 힘들다. 디버깅이 힘들다." 같은 단점을 드는데, 우리 팀의 경우 개발자들이 이미 서비스 플로우를 잘 알고 있어서 체감하긴 어려웠다.

 

 

마무리

NestJS에서는 공식적으로 EDA를 지원한다(https://docs.nestjs.com/techniques/events). 적용자체는 어렵지 않았으나 쓰자마자 차이점을 실감하진 않았던 것 같다. 여러 번 코드를 써보고 유지보수를 하면서 장점을 느꼈고, 앞으로 새로 설계를 하더라도 적극적으로 도입하지 않을까 한다. 프론트에서도 비슷한 짜증 나는 문제점을 느꼈는데, 검색을 대충 해서 그런지 이벤트버블링캡처링밖에 안 나오는 느낌이더라. 직접 만든다고 해도 그렇게 어려울 것 같지는 않아서 시간이 나면 한번 해보고 싶다.

 
 
Comments