안녕하세요? 벡엔드 개발하고 있는 에밀리입니다.
현재 회사가 모놀리식 아키텍처로 시스템이 설계되어있고, 개발을 하다보니,
생산성, 소스관리, 배포작업이 불편하다고 느껴졌습니다.
그리고 마이크로서비스는 이런 부분들이 개선될 수 있는 좋은 방법론이라고 생각합니다.
그래서 아키텍처 전환 도입을 고민하게 되었고, 이것이 정말 좋은지, 좋다면 어떻게 구현해야 하는지에 대해서
공부한 내용을 이야기 하려고 합니다.
(참고 책 : 마이크로서비스 패턴 / 크리스 리처드슨 (2020년 발행)
마이크로서비스란(MSA) ?
실무적으로 경험한 내용은
- 마이크로서비스는 어플리케이션이 여러 모듈(기능, 서비스) 로 구성
- 각 서비스를 독립적으로 배포/확장할 수 있는 아키텍처 스타일
책에서
- 각 서비스마다 DB를 가지고 있다.
- 오직 API를 통해서만 통신.
- MSA와 모놀리스의 프로젝트 구성
- 서버구성
모 : load balancer 뒷면에 어플리케이션 인스턴스 여러개 실행. -> 애플리케이션 능력과 가용성을 개선할 수 있는 방법
마 : 각 서비스당 load balancer 있고 뒷면 여러 서비스 인스턴스를 가짐.
- CI/CD구성
-개발, 스테이징, 운영 탭별로 서비스 모두 있어야 함.
-JVM당 서비스 인스턴스 1개 가동. 각 서비스 인스턴스는 별도 프로세스.
각 아키텍처의 장점과 단점
모놀리스 | 마이크로 | |
장점 | -개발이 간단하다. (초기에는 굳이 정교한 분산을 할 필요 없음.) -쉽게 변경 가능. -배포 쉬움. (tomcat설치경로에 war파일만 복사) -확장이 쉬움. (인스턴스만 추가하면 됨) |
-크고 복잡한 애플리케이션을 지속적으로 전달/배포. -배포/ 확장이 쉬움. (서비스별로 관리하면 되므로) -새로운 기술 스택과 데브옵스 스타일 적용가능. -한 서비스에 버그있어도 다른 서비스는 정상 작동. -역할과 책임의 선을 명확히 -> 개발생산성 향상 |
단점 | -예전 기술스택을 계속 가져감. (신기술 도입에 제약) -버그 하나만 있어도 메모리 누수가 발생 -> 전체 애플리케이션 인스턴스 다운. -리소스 요건이 다를 경우 처리가 어려움. (고효율 이미지 업로드는 CPU 코어 수가 많은 서버에 배포하는 것이 최적일것 같고, 데이터많으면 메모리칩이 많이 장작된 서버가 좋겠지요.) |
-정교한 CI/CD 구축 필요. -구체적으로 정립된 알고리즘이 없음. (딱 어떻게 서비스를 나눠야 한다는 게 없음) -잘못 분해하면 분산 모놀리스를 구축할 수 있음. -서비스간 의존성 관리. |
도입전략
- 단계적 리펙토링
1. 새로운 서비스는 새 프로젝트에 구현
2. 프론트와 백엔드를 분리.
3. 기능을 여러 서비스로 추출해서 모놀리스를 분해.
1. 새로운 서비스는 새 프로젝트에 구현 - 모놀리스를 더이상 안 크게 .
모놀리스와 새로운 서비스를 연계한다.
연계는
[이벤트 발행, 이벤트구독] 어댑터와
[인바운드, 아웃바운드] 어댑터와
[API 게이트웨이] 가 한다.
API 게이트웨이 : 새 기능 요청은 새 서비스로, 기존요청은 모놀리스에 라우팅한다.
2. 프론트와 백엔드를 분리.
-표현계층과 벡엔드를 분리
-인메모리 세션기반을 토큰기반으로 변경.
-여전히 두개의 모놀리스. 서비스로 쪼갠 것이 아니라 관리문제 있음.
3. 기능을 여러 서비스로 추출해서 모놀리스를 분해.
-가장 가치가 큰 애플리케이션 영역을 집중적으로 리펙토링
-다른 class에 다른 기능들과 함께 묻혀 있던 새서비스만 떼어 내는 것.
마무리
이렇게 MSA는 유지보수성, 테스트성, 배포성이 우수하고 개발을 빨리 할 수 있으며,
확장성도 우수하고 오류격리도 잘 됩니다. 기술스택 발전시키기도 훨씬 쉽습니다.
하지만 아키텍처에는 정답이 없고, 시스템 개발/운영 상황과 기술트랜드에 맞게 설계해야 한다는 것을 느꼈습니다.
그리고 전환, 도입은 아무리 위의 전략이 있더라도 많은 시행착오가 있을것이고
나만의 방향설정이 필요할 것입니다.
그래서 무조건 도입을 밀어붙이거나 인프라 구성을 하는것은 비용낭비일 수 있으니,
서비스를 몇개 만들어 보면서 효용성에 대한 검증이 먼저 이뤄져야 한다고 합니다.
그 작업을 개발확정된 공통모듈(common) 을 만들면서 시도해봐야 겠다고 생각했습니다.
공통모듈을 멀티모듈로 설계하는 것을 해봐야겠습니다.
절대 달라지지 않을 것들과
그 외의 것들을 서비스로 쪼개서 하는 방향으로 시도해 보려고 합니다.
그리고 그 과정과 결과를 다음 회고때도 공유하겠습니다.