Skip to content
hello tis
Go back

리버스 엔지니어링으로 MSA 환경 개선하기

0. 개요

마이크로서비스를 운영하고 있다.

기능 단위로 추출해 마이크로서비스를 운영하고 있다. 마이크로서비스를 사용하는 대상은 다음과 같다.

다음과 같은 기능을 제공하고 있다.

선례가 없다면 결과 예측이 어렵다.

마이크로서비스를 구성하다보면 계획에 맞게 영역을 구분하고 마이크로서비스를 생성한다. 그렇게 마이크로서비스가 제공하는 장점을 활용하면된다. 그러나 중요한건 인생은 계획대로 흘러가지 않는다는 점이다.

계획에 어긋난다고 생각하는 시점은 생각치못한 기능 추가(또는 수정)가 되는 순간이다. 마이크로서비스와 유사하다는 이유로 추가 기능이 덕지덕지 붙게되면서 마이크로서비스 이점을 잃게 된다.

기능 하나하나 추가될 떄마다 마이크로서비스를 만들 수는 없다.

리버스 엔지니어링을 활용한 사례 분석으로 모놀리식과 마이크로서비스가 공존하는 시점으로 회귀할 필요성을 느꼈다. 마이크로서비스 전환 사례를 분석해 현재 마이크로서비스 단점을 보완해보려 한다.

마이크로서비스 경험을 메우기 위해 도메인 주도 설계 첫걸음 책과 국내 또는 해외 사례를 고했다.

1. 안건 1 : 모호해진 마이크로 서비스

문제 1 : 영역이 모호해진 마이크로서비스

우리는 마이크로서비스를 기능 단위로 추출했다. 다음은 예시다.

설계가 서비스 영향으로 이어졌다.

백오피스가 함께 관리되면서 권한 계층이 필요해졌고 권한과 관련된 부가 기능이 지속적으로 늘어나고 있다.

서비스 간 영역이 모호해지면서 의아한 기능 반영 모습도 확인했다.

포인트리 앱에서 문의 정보구독 정보가 노출되는 상황

포인트리 앱에서 제품 관리 홈페이지의 문의 정보와 구독 정보가 노출되는 화면

제품 관리 홈페이지에서 포인트 전환이 노출되는 상황

제품 관리 홈페이지에서 포인트리 앱의 포인트 전환이 노출되는 화면

원인 1 : 이해관계자 참여가 어려웠다.

설계 과정에서 이해관계자 참여가 어려웠던 점이 컸다고 생각한다. 마이크로서비스가 예상한 방향성은 사업 방향과 불일치했기 때문이다. 제품 구독 서비스에 맞게 성장하는 목표가 있었지만 일부 기능은 전사가 사용할 목적으로 성장하기도 했다. 대표적으로 회원 서비스포인트 서비스다.

제품 구독 서비스에서 전사용으로 성장한 회원 서비스와 포인트 서비스 구조

제품 구독 서비스에 한정지어서 기능 단위로 모듈화한다면 관리 부담이 적었겠지만 마이크로서비스가 제공하는 플랫폼이 많아지면서 개발 속도가 점차 느려졌다.

해결 1 : 이해관계자와 목적과 방향성 공유

개선안을 통해 마이크로서비스 개선 필요성을 부각시켰고 조직 구성원의 공감대를 형성했다.

이해관계자와 마이크로서비스 개선 목적과 방향성을 공유한 자료

LG CNS 사례에서 이해관계자 간 상호 검증을 통해 서비스 분리, 통합 방안을 신중하게 하고 목표와 수준에 대한 합의점을 찾기 위해 노력해야 한다. 프로젝트 규모에 따라 1~2년이 소요되고 개선 기간동안 요구사항 추가 변경에 대응하면서 시스템이 변형될 수 있다.라고 설명한다.

결과 1 : 이해관계자와의 공감대 형성

효과적이다.

사례를 바탕으로 공감대를 형성한 과정은 이해관계자에게 현재 상황을 쉽게 전달할 수 있었다. 덕분에 마이크로서비스 개선 리소스를 할당받을 수 있었다.

효과적이지 않다.

사업팀과 개발팀 사이에서 목표지점을 찾는 과정에서 이벤트스토밍을 시도했지만 효과는 없었다. 이해관계자에게 추가 학습을 강요하는 상황이었기 때문이다. (이벤트스토밍이 현재 상황에서 꼭 필요한 절차인지 납득시키지 못한 점도 컸다.)

이벤트스토밍을 시도했지만 효과가 없었던 상황

이해관계자의 추가 학습을 요구하게 되는 일이니 신중할 필요가 있음을 깨달았다.

2. 안건 2 : 서비스 간 의존성 관리 어려움

문제 2 : 서비스 간 의존성 관리 어려움

왜 관리해야 한다고 생각했지? 어떤 문제가 발생하는거야?

코드 수준에서 인사이트를 얻어봤다. MangKyu’s Diary | 의존성(Dependency)이란? 글에 따르면 의존성이 최소화돼야 하는 이유는 의존성 전이 때문이라고 한다. 즉, 변화할 때마다 의존된 모든 컴포넌트에게 영향을 끼친다는 점이다.

현재 상황은?

포인트리 앱에서 제공하는 포인트 일부 기능전사 플랫폼 서비스로 이전 되면서 이런 강결합을 없애야하는 상황도 발생했었다. 회원포인트 두 마이크로서비스 간 강결합이 높아진 경우 예시를 가져와봤다.

서로 다른 플랫폼에도 영향이 가는 문제도 경험했다. 제품 관리 홈페이지 기능을 수정했는데 전체 서비스 영향도를 검사하면서 마이크로서비스 장점인 배포 용이성을 잃었음을 경험했다.

결론은?

서비스 의존성을 관리하지 않으면 변경이 어려워진다. 마이크로서비스가 제공하는 독립성을 잃게된다. 독립성을 잃게 되면서 서비스 영향도가 커지면서 배포가 점

원인 2 : 분산되고 커다란 진흙 덩어리

마이크로서비스 기반 시스템은 글로벌 복잡성과 로컬 복잡성을 최적화해야 한다.

글로벌 복잡성과 로컬 복잡성, 커다란 진흙 덩어리와 분산된 커다란 진흙 덩어리를 나눈 사분면

참고자료 : 도메인 주도 설계 첫걸음 233p

극단적인 예시를 가져왔다.

분산된 커다란 진흙 덩어리 : HTTP 인터페이스로 연결한 경우

HTTP 인터페이스로 연결해 분산된 커다란 진흙 덩어리가 된 구조

커다란 진흙 덩어리 : 코드로 연결한 경우

코드로 연결해 하나의 커다란 진흙 덩어리가 된 구조

시간이라는 변수가 추가되면 위 사례보다 더욱 끔찍한 상화에 모면한다. 시간이 지나면서 시스템 복잡성과 로컬 복잡성이 증가하는 모습을 동시에 경험한다. 예시를 들면, 마이크로서비스에서 의도하지 않은 기능이 추가되는 상황이다.

시간이 지나며 의도하지 않은 기능이 추가되어 복잡성이 증가하는 상황

우리는 두 가지 중 하나를 선택해야 힌다.

현재 상황을 요약하면 어떤 상황이더라도 분산되고 커다란 진흙 덩어리에서 퇴화하고 있다. 이런 상황에서 우리는 문제를 어떻게 해결해야 하는가

해결 2 : 전략적 접근과 전술적 접근

전략적 접근으로 해결하기

첫 번째로 하위 도메인을 재정의해 의존성 전이를 제거해보려한다. 서비스가 하위 도메인 경계와 일치한다면 의존성 전이가 감소하지 않는다. 왜냐하면 비즈니스 모델이 외부로 유출되지 않기 때문이다.

마이크로서비스를 설계하는 데 균형 잡힌 휴리스틱은 비즈니스 하위 도메인의 경계와 서비스를 일시키는 일이다. 하위 도메인은 같은 비즈니스 도메인 모델을 사용하고 같거나 밀접하게 관련된 데이터를 다루며 강한 연관성을 갖는다. - 도메인 주도 설계 첫걸음 236p

하위 도메인 경계를 식별하는 방법은 서비스를 이용하는 사용자가 같은지로 결정했다.

내부적인 업무를 조사하면 서비스를 운영하기 위해서 업무가 세분화된다. 그리고 가진 업무를 세분화하고 유스케이스를 나열한다. 나열한 유스케이스를 응집해 세부 하위도메인을 식별한다. - 도메인 주도 설계 첫걸음 12p ~ 14p 요약

그렇게 분리된 결과는 다음과 같다.

ASIS

하위 도메인 경계를 재정의하기 전 ASIS 서비스 구조

TOBE

하위 도메인 경계를 재정의한 후 TOBE 서비스 구조

위처럼 경계를 식별한다면 모든 서비스를 물리적으로 분리하면서 글로벌 복잡도가 증가했다. 모든 마이크로서비스를 물리적으로 운영한다면 글로벅 복잡도만 늘릴 뿐이다.

바운디드 컨텍스트보다 넓은 경계를 정의하면 커다란 진흙 덩어리를 만들고 마이크로서비스보다 작은 경계는 분산된 커다란 진흙 덩어리를 만든다. 이 때, 마이크로서비스는 서비스의 가장 작은 유효한 경계를 정의한다. 그리고 바운디드 컨텍스트는 모델 일관성을 보호하기 위한 가장 넓은 유효한 경계를 정의한다. - 도메인 주도 설계 첫걸음 242p

그래서 바운디드 컨텍스트를 정의하고 마이크로서비스를 관리한다면 의존성 전이를 해결하고 서비스 독립성을 얻게 된다. 그리고 제품 규모에 따라 모놀리식, 마이크로서비스 형태를 결정하면 글로벌 복잡도 해소 가능하다.

A

제품 규모에 따라 모놀리식과 마이크로서비스를 선택한 구성 A

B

제품 규모에 따라 모놀리식과 마이크로서비스를 선택한 구성 B

글로벌 복잡성은 줄이기 쉽다. 시스템 구성요소 간 상호작용을 없애기만 하면 된다. - 도메인 주도 설계 첫걸음 236p

마이크로서비스 분리 여부를 결정하는 방법은 서비스 영향도를 지표로 의사결정 가능하다. 카카오 : 이모티콘 서비스는 왜 MSA를 선택했나? 에서는 서비스간 연결 관계를 istiokiali로 서비스 연결 관계를 분석했다.

istio와 kiali로 서비스 간 연결 관계를 분석한 화면

전술적 접근으로 해결하기

의도하지 않은 기능 추가로 로컬 복잡도가 증가하고는 문제는 BFF 패턴을 활용하면 임시적으로 해결 가능하다.

BFF는 디바이스나 인터페이스 전용 API 게이트웨이를 제공하는 방법이다. 덕분에 제공하는 인터페이스를 각자 자유롭게 구성할 수 있다.

SoundCloud에서는 마이크로서비스가 작을 경우 BFF 계층으로 이동시켜 관리하는 방법으로 위 문제를 회피했다.

SoundCloud가 작은 마이크로서비스를 BFF 계층으로 이동시켜 관리한 구조

그러나 BFF에 의도하지 않은 기능이 모일테니 다음과 같은 단점이 존재한다.

SoundCloud에서는 복잡성 증가, 중복 코드 발생 빈도 증가, 서비스 간 의존성 관리 어려움을 겪고 VAS 형태로 시스템을 구성했다. VAS는 edge service, value-added service, foundational service 로 세 계층으로 구성한다.

value-added service 에서 사용자 경험 향상을 위해 foundational service 기능을 소비하고 처리한다. edge service 는 게이트웨이 역할로 단순한 작업만 진행한다.

즉, 선택적으로 공통 기능으로 제공해야 하는 경우 value-added service를 구성하고 공통 기능으로 제공하지 않는 경우 BFF에서 관리하는 방법으로 BFF가 비대해지는 현상을 해소할 수 있다.

VAS 추가되면 좋은 경우

공통 기능으로 제공할 때 VAS를 추가하면 좋은 경우 구조

BFF 추가되는 경우

공통 기능으로 제공하지 않을 때 BFF를 추가하는 경우 구조

추가 주제로는 시스템적 강결합 해소하는 방법과 마이크로서비스 경계를 최적화하기 위한 방법을 정리했다.

앞에 인터페이스를 추가해 강결합을 해소할 수 있다. 인터페이스에 맞는지 확인하기 위한 OHS(오픈호스트 서비스)와 ACL(충돌 방지 계층)이 존재한다.

오픈 호스트 서비스

오픈 호스트 서비스로 공표된 언어를 도입해 글로벌 복잡성을 줄이는 구조

충돌 방지 계층

충돌 방지 계층으로 비즈니스 복잡성과 연동 복잡성을 분리하는 구조

콜백인 경우 우리가 제공자다. 우리가 구현한 정보가 외부까지 전달되면 복잡해질테다.

마이크로서비스 경계를 최적화하기 위한 방법으로는 이벤트 주도 아키텍처를 추천한다. 이벤트 주도 아키텍처로 분산 시스템을 설계하면 다음 이점을 가진다.

서비스가 잠시 중단되도 이전 요청들은 이벤트로 저장되기 때문이다.

그러나 쿠팡 사례에서는 강결합을 해소하기 위해 인하우스 메시지 큐 개발했지만 트랜잭션이 유지되지 않기 때문에 사용자가 혼란을 겪는 상황도 존재한다고 한다.

결과 2 : 개발 용이성 획득

효과적이다.

효과적이지 않다.

3. 안건 3 : 관리 기능에 대한 관리 부담

문제 3 : 관리 기능에 대한 관리 부담

공통 관리 기능 개선하는 작업이 부담된다.

다른 회사 사례를 분석해보면 MSA 전환 시점에서 공통 기능을 신중하게 분석했다.

원인 3 : 개발과 관리 간 강결합

개발 기능과 관리 기능 간 강결합으로 서로 간 영향을 전파한다. 이런 강결합을 해결하기 위해 사이드카 패턴을 활용하기도 한다.

개발 기능과 관리 기능의 강결합을 사이드카 패턴으로 분리한 구조

MS에서 설명하는 사이드카 패턴 : 사이드카는 애플리케이션에 연결되어 애플리케이션이 필요한 지원 기능을 제공한다.

해결 3 : 관리 기능 외부화

다른 서비스들 사례 분석해봤지만 MSA 환경을 개선하는 사례는 드물었다. 문제 해결 방법이 휴리스틱에 가까운 점 양해바란다.

책임 단위 독립성 유지

사이드카 패턴처럼 애플리케이션은 서비스에만 집중하고 남은 관리 방식을 외부화한다면 서비스 독립성을 유지할 수 있다.

로그 보관 기능을 외부화한 덕분에 로그 보관 방식 변경에도 서비스 영향도 없이 자유롭게 개선이 가능했다. 이후 보관 정책 변화에도 각 서비스는 유연하게 대응 가능했다.

로그 보관 기능을 외부화해 서비스 영향 없이 개선 가능한 구조

책임 단위 기능 유지

책임 단위로 관리했다면 기능 추가에 유연하게 대응할 수 있다. 로그 보관 모델로그 분석 모델 간 관계에서 로그 보관 모델 영향없이 로그 분석 모델을 구현할 수 있다.

로그 분석 모델에 로그를 쌓는건 로그 분석 모델이 가져야 할 책임이다.

로그 보관 모델과 로그 분석 모델을 책임 단위로 분리한 구조

구축했던 ELK가 사용성이 떨어져 종료한 경험이 있다. 분석 모델 필요성을 당장은 경험하지 못한다면 위 예시처럼 로그 보관만 먼저 수행하면 된다.

결과 3 : …

효과적이다.

효과적이지 않다.

4. 마무리

완벽한 마이크로서비스는 없다.

마이크로서비스와 모놀리식 간의 공생 관계가 이어지고 있다. 다음은 내가 취해야 할 스탠스이다.

바운디드컨텍스트는 완벽하게 정의할 수 없다. 이해관계자가 생각하는 서비스 방향성은 다르기 때문이다. 벽한 바운디드컨텍스트는 이론에 불과하다.

시간이라는 변수

책에서는 시간에 따른 도메인 변화를 고려하지 않는다. 정적인 상황에서 도움이 될지는 몰라도 유동적인 상황에서는 대응하기 어렵다고 생각한다.


Share this post:

Previous Post
어깨너머 성과지표 배워보기 - 29cm 편
Next Post
2024년 연간 회고