회고록

두 번의 프로젝트를 마치며

yemong 2026. 4. 15. 12:53

2/24일부터 4/8일까지 총 두번의 프로젝트를 진행했다. 

첫번째 프로젝트는 배달의 민족과 같은 음식 주문 관리 시스템을 주제로 개발했다. 모노리식 형태로 구현했고 MSA로 확장가능하도록 4계층 구조로 설계했다.

두번째 프로젝트는 쿠팡를 참고해 물류관리 및 배송 시스템을 만들어 보았다. 처음으로 MSA 아키텍처를 제대로 적용해 본 것 같다. 처음 사용해 보는 기술이 많아 구현하는데 많이 더뎠 것 같았지만 그래도 배운 점은 많았던 것 같다.

프로젝트를 진행하면서 경험했던 고민과 결정에 대한 기록을 간단하게 남겨보려고 한다.

사용한 기술

 

1. Querydsl

2. DDD 설계

3. Config Server

4. Gateway

5. common 모듈

6. Kafka

...  더 많지만 일단 생각나는 것만 작성해 봤고 추후에 추가로 작성할 예정이다.

 

 

왜 그 기술을 선택했는가

 

Querydsl을 선택하게 된 상황은 다음 링크로 연결해서 자세히 알 수 있다.

간단하게 설명하자면, JPA로 간단하게 쿼리를 작성하는 경우에는 편리하다. 

하지만 복잡한 쿼리에서는 원하던 형태로 적용되지 않는 경우가 발생하는 것을 알게되었고 여러 복잡한 조건들을 동적 쿼리로 적용하기 위해서는 Querydsl을 도입하는 것이 좋겠다고 판단하여 해당 기술을 선택하게 되었다.

 

 

 

 

어떤 문제를 어떻게 해결했는가

 

트러블 슈팅

MSA 기반의 프로젝트를 수행하던 중, 상품을 조회/명령(요청)할 때 사용자의 권한에 따라 조회하는 조건이 다르다.

예를들어, 마스터 관리자는 모든 조회가 가능하지만, 허브 담당자는 본인이 해당하는 허브에 관한 상품정보만 조회가 가능하다. 따라서 사용자 본인의 허브ID를 받아와야하는 경우가 발생한다. 그렇다면 아이템 조회하는 매 요청마다 userId 기반으로 소속 hubId를 조회해야 해서 OpenFeign 호출이 발생하게 된다.

매 요청마다 이러한 방식이 반복된다면 서비스 간 호출 비용 증가와 응답 지연이 발생할 수 있다고 판단하여 다른 방안을 고민해보았다. Header 전달 방식과 캐싱 방식이 존재한다. 

 

Header 전달방식은 Gateway에서 JWT를 파싱하여 해당 유저의 companyId, HubId를 전달하는 방식으로 구현했다. 이 방식을 사용하면, 각 요청에 대해서 서비스 간 호출이 감소되어 성능이 개선되는 장점으로 선택하게 되었다.

 

 

캐싱 방식은 한 번 조회된 사용자 정보를 캐시에 저장하여 반복 조회를 줄이는 방식이다. 이로인해 서비스 간 호출이 감소되어 성능이 개선되게 된다.  하지만 캐시 데이터와 실제 데이터 간의 불일치가 발생할 수 있으며, 캐시 무효화 전략이 필요하다.

 

이번 프로젝트에서는 서비스 간 호출 제거와 구조의 단순성을 고려하여 Header 전달 방식을 선택했다.
다만, JWT는 발급 시점의 정보를 기준으로 하기 때문에 권한이나 소속 허브가 변경될 경우 즉시 반영되지 않는 한계가 있다. 이러한 점을 고려했을 때, 이후에는 캐싱 전략을 적용해 JWT에서는 userId와 같은 최소 정보만 담고, 실제 권한 정보는 캐시를 통해 조회하는 방식을 고려해보고 싶다. 이를 통해 반복적인 서비스 간 호출을 줄이면서도 최신성을 확보할 수 있을 것이라고 생각한다.