Application Architecture - Microservice Architecture

Violet_Evgadn·2023년 4월 24일
0

Cloud Native Architecture

목록 보기
8/16

Microservice Architecture

Microservice Architecture(MSA)란?

MSA란 작은 애플리케이션들을 합쳐 큰 애플리케이션을 만드는 Application Architecture를 말한다.

MSA는 대형 프로젝트가 힘들다는 Monolithic Architecture 문제점을 해결하기 위해 나온 Architecture로써 SOA(서비스 지향 아키텍처)에서 발전된 형태를 가진다.

MSA의 가장 기본적인 철학은 "한 가지만 잘 처리하자"이다.

MSA에서는 단일 책임 원칙(SRP)을 중시하여 큰 문제를 최대한 독립성 있는 작은 문제로 분해한다. 이렇게 분해된 문제들을 Component를 통해 해결하고, 개발된 Component 간 REST API를 통해 데이터를 주고받음으로써 전체 애플리케이션이 동작하는 것이다.

중요한 점은 Component끼리 REST API를 통해 경량화된 데이터(Json 데이터 등)를 주고받음으로써 통신이 이루어지고, 각 Component는 최대한 다른 Component에 영향을 미치지 않아야 한다는 점이다.

이 Component들은 서로 독립적이기 때문에 Component를 배포할 때도 다른 컴포넌트와의 의존성 없이 독립적으로 배포된다는 특징을 가진다.

MSA의 특징

먼저 MSA는 "문제를 얼마나 잘 분해하였는가"에 따라 애플리케이션의 품질이 정해진다는 특징을 가진다.

MSA의 각 Component들은 결합도가 낮게 분리되어 있어야 한다. 만약 결합도가 높을 경우 MSA의 장점을 살리지 못하게 되고 Monolithic보다 생산성이나 관리 측면에서 낮은 만족도를 가지고 올 수 있다.

따라서, 모든 요구사항을 최대한 의존성 없는 작은 문제들로 분해하는 것이 MSA의 첫 시작이라고 할 수 있겠다.

두 번째로 수직 분할 원칙(Vertical Slicing)을 따른다는 것이다.

Monolithic은 1개의 Application에서 전체 서비스를 다루기 때문에 1개의 공통된 DB와 개발 언어, 기술 Stack을 활용하게 된다.

하지만 MSA에서 Component는 다른 Component에 영향을 주지 않거나 최소한의 영향을 줘야 하며, 오로지 REST API를 통해 데이터 통신만 수행해야 한다. 즉, Component의 독립성을 지키기 위해 동일한 DB를 공유하는 것이 아닌 서비스별로 다른 DB를 사용해 Component 독립성을 높이는 것이 좋다.

이렇게 Component별로 다른 DB를 활용할 때 Component 사이의 결합도가 줄어들며 Component 입장에서 다른 Component들은 오로지 데이터를 통신하는 대상으로만 취급할 수 있게 된다.

즉, MSA는 각 Component가 독립성을 지니고 있기 때문에 Component별로 다른 DB, 개발 언어, 기술 Stack을 활용할 수 있게 된다.

마지막 특징은 Component의 좁은 영향 범위이다.

계속해서 강조했듯 MSA에서는 Component가 다른 Component에 영향을 크게 줄 수 없다.

따라서 특정 기능에 문제가 발생하였더라도 전체 Application에 영향을 주기는 매우 어려워진다.

Component의 독립성은 1개의 에러가 전체 Application에 영향을 주는 위험성을 크게 줄일 수 있어 안정성을 높일 수 있다.

모놀리식 아키텍처와 MSA 비교

모놀리식과 MSA는 Traffic 문제가 발생하였을 경우 Application을 실행하는 서버를 추가하는 Scale-out 방식으로 수평적 확장을 실행한 이후 Load Balancer를 통해 트래픽을 관리한다는 공통점을 가진다.

Scale-out과 Scale-up, Load Balancer의 뜻은 아래와 같다

  • Scale-out : Server가 더욱 원활히 일을 처리할 수 있도록 Server 개수를 늘리는 방식을 채택하는 것
  • Scale-up : Server가 더욱 원활히 일을 처리할 수 있도록 HW 성능을 올리는 방식을 채택하는 것
  • Load Balancer : 여러 대의 Server에게 균등하게 Traffic을 분산시켜주는 역할을 담당

하지만 둘 모두 Scale-out을 통해 Traffic 문제점을 해결하지만, 확장 방식에는 약간 차이가 존재한다.

Monolithic에서는 모든 서비스가 1개의 Application에 포함되어 있으므로 서비스를 확장시킬 때 전체 Application을 배포해야 한다.

하지만 MSA의 경우 Traffic이 많은 Component만 복제하여 배포하면 되기 때문에 코드 무결성 검사를 위해 진행해야 할 테스트가 줄어들며 자원의 낭비를 줄일 수 있게 된다.

MSA가 뜨는 이유

MSA가 뜨는 이유는 Cloud 환경이 유명세를 타는 것과 큰 연관성이 있다.

MSA는 Cloud 환경과 매우 찰떡궁합인 Architecutre이다.

Monolithic은 1개의 Application을 배포시킴으로써 시스템을 구축하는데, Application의 사용량이 적다고 하더라도 전체 시스템이 필요로 하는 HW Spec은 변하지 않기 때문에 사용량 단위로 과금을 해야 하는 Cloud 환경에서는 비효율적이다.

하지만 MSA에서는 서비스 단위로 기능을 분리하였기 때문에 사용하지 않는 기능이나 사용량이 적은 기능은 최소한으로 서버에 배포시켜 Application 자체를 효율화시킬 수 있다.

따라서 Monolithic과는 다르게 필요로 하는 HW Spec을 최대한 효율화시킬 수 있으며, 이는 Cloud에서의 과금에 대해서도 최대한 효율화시킬 수 있다는 것으로 이어진다.

물론 아래에서 설명하듯 MSA도 많은 단점이 존재하지만, Cloud 환경에 적합한 Architecture라는 점이 MSA의 인기가 급부상한 가장 큰 이유가 아닐까 싶다.

그렇다면 MSA가 무조건 좋은 것일까?

SW를 공부하다 보면 항상 느끼는 점이 있다.

"무조건 좋은 것은 없다"

아무리 최근에 유행하는 Trend 기술이든 뭐든지 말이다.

실제로 구글에 "don't use microservice"라는 엄청난 검색 결과가 나옴을 볼 수 있다.

물론 글을 읽어보면 필요하지 않다기보다는 "굳이 억지로 활용할 필요는 없다"라는 것을 말하고 있는 글들이지만, 이 글들을 읽어보면 상황에 맞춰 Architecture를 선택하는 것이지 굳이 MSA를 활용할 필요는 없다는 것을 느낄 수 있다.

개인적으로 가장 흥미 있게 읽었던 글은 아래에 기입한 사이트 글이다.

When Microservices Are a Bad Idea

글이 길지만 꽤 재밌으니 한 번 읽어보기를 추천한다.

간단히 정리하자면 아래와 같다.

MSA라는 Architecture는 초기 디자인이 매우 중요시되는 Architecture로써 Monlithic보다 MSA가 Service Refactoring이 더 힘들기 때문에 기업이 MSA로 개발하는 데에 있어 잔뼈가 굵고 경험이 많아 초기 디자인을 잘 수행할 수 있을 경우 활용해야 하는 Architecture이다.

개인적으로는 재밌는 말이었는데, MSA를 처음 도입하기 위해서는 말 그대로 "경력 있는 신입"이어야 한다는 것이다. 새로운 기술이어서 도입하려고 하는 건데, 제대로 활용하려 하면 경험이 필요한 약간 모순된 상태가 되는 것이다.

두 번째로 사내에서는 MSA를 확실하게 활용할 수 있지만, 외부에서도 MSA 방식으로 개발한 시스템을 사용할 수 있을지 모호하다는 것이다. 이는 특히 SI 기업에서는 MSA를 잘 활용하지 않는 이유와 연결되는 것 같다.

실제로 필자가 다닌 기업에서 Container와 MSA를 통해 서비스 개선을 생각해보았으나 SW 개발을 맡긴 업체에 Docker나 Kubernetes를 설치할 수 있는지 여부, 그리고 Docker Image 사용 여부 등 보안적으로 의견 차이가 있을 점들에 대한 논의가 이뤄져야 한다. 즉 사내에서 MSA를 통해 완벽히 활용했다 하더라도 Component를 외부 서비스에 그대로 이식할 수 있을지에 대해서는 미지수인 것이다.

세 번째로는 Monolithic도 충분히 경쟁력이 있다는 것이다.

먼저 Shopify라는 회사는 Monolithic Architecture를 활용했지만 시간이 지나며 시스템이 너무 켜졌고 개발자들은 거대한 시스템에 대하여 수정 및 기능 추가를 하는 것에 대하여 큰 부담감을 느꼈다.

하지만 이 회사는 MSA로 서비스를 전환하는 대신 모듈화를 통해 기능을 분리함으로써 시스템을 정리하였다.

1개의 예시지만 MSA가 유일한 답이 아니라는 것을 보여주는 예시라고 볼 수 있겠다.

추가로 위 그림을 살펴보자면 MSA는 개발 초기에는 오히려 생산성이 떨어지는 Architecture라는 것을 알 수 있다.

이후 시간이 지나고 계속해서 기능을 추가해야 하는 경우에만 Monolithic의 생산성이 점차 떨어지는 것을 확인할 수 있다.

이를 반대로 생각하면 초기 요구사항에서 변동될 가능성이 거의 없는 SW 같은 경우 Monolithic의 생산성이 MSA 생산성보다 낮아지는 지점까지 개발이 진행되지 않으므로 오히려 MSA가 비 생산적인 Architecture가 될 수 있는 것이다.

이를 한꺼번에 정리하자면 기업측면에서 실제로 MSA로 전환을 간절히 원하고, 이 과정에서 발생하는 손실을 감당하면서 전환할 의지가 있는가, 또한 기업이 개발할 SW의 성질은 무엇인가 등 많은 점들을 고려하여 MSA를 활용할지 Monolithic을 그대로 활용할지 결정해야 함을 알 수 있다.


MSA의 장점

공통 기능 처리(Cross Cutting Function Handling)

위에서 말했듯 MSA에서는 기능을 최대한 독립적으로 분리하는 것이 중요하다.

이는 공통 기능에서도 동일하다.

여러 Component에서 활용하는 기능들도 독립적으로 분리되어 Component로 만들어졌기 때문에 다른 Component들은 REST API를 통해 공통 기능에 대한 Component와 통신함으로써 공통 기능을 처리할 수 있게 된다.

따라서 공통 기능에 대한 로직을 여러 Component에서 중복으로 구현하지 않아도 되기 때문에 구현이 훨씬 쉽고 빨라지며 공통 기능에 대한 관리 및 사용이 쉬워진다.

유연한 배포

MSA에서는 필요한 Component만 배포하면 기능 수정 및 추가를 수행할 수 있다.

Monolithic에서는 자그마한 수정 사항이 발생했더라도 전체 Application을 재기동시켜야 했으나 MSA에서는 오로지 수정이 필요한 Component만 다시 배포함으로써 빠르고 쉬운 기능 수정을 수행할 수 있다.

또한 Component가 전체 Application에 영향을 줄 가능성이 낮기 때문에 기능에 대한 수정을 하거나 추가하는 과정에서 문제가 발생한다고 하더라도 전체 Application에는 영향을 주지 않는 선에서 빠르게 기능 복구가 가능해진다.

이를 위해 MSA에서는 Component에 대한 Version Up을 시킬 때 에러가 발생하는 상황을 대비하여 롤백 메커니즘을 두는 것이 추천된다.

이러한 쉬운 배포 및 안정성 있는 배포라는 장점은 개발자들의 생산성과 개발 속도를 크게 증가시키며 최신 기술을 접목하는 데에 있어 부담감이 줄어든다는 부가적 장점을 가지고 온다.

뛰어난 확장성

X축 : 복제

같은 Microservice를 여러개 복제하여 배포함으로써 과도한 트래픽에 최소한의 비용으로 대처할 수 있다는 장점을 지닌다.

만약 A, B, C 기능이 존재할 때 B 기능만 Traffic이 폭발적으로 많을 경우 Monolithic Architecture에서는 전체 애플리케이션을 새로운 서버에 배포하여 확장시키는 방법밖에 존재하지 않는다. 즉, A와 C 기능에 대한 확장은 필요 없음에도 불구하고 B 기능 때문에 Server를 확장해야 하는 자원의 낭비가 발생하는 것이다.

하지만 MSA에서는 이런 자원의 낭비를 최소화시킬 수 있다.

결국 B 기능에 대한 Component만 복사하여 서버에 배포시킨다면 Load Balancer가 알아서 Traffic을 여러 Component로 분배하여 과도한 Traffic을 처리할 수 있게 되는 것이다.

즉, 효율적인 Scale-out을 통해 과도한 Traffic을 처리할 수 있게 되는 것이다.

Y축 : 분리

기능을 여러 개로 분리하였기 때문에 필요한 기능들만 확장이 가능하다.

X축과 매우 유사한 장점이라고 보면 된다. 단지 X축에서의 "복제"는 Cloning을 통한 Scale-out에 대한 장점이라고 보면 되고, Y축은 기술적으로 분리되어 있기 때문에 "필요한 기능"들에 대해서만 확장하여 트래픽을 처리할 수 있다는 장점이라고 보면 되겠다.

즉, 엄밀히 따지자면 과도한 트래픽을 단순히 Component의 복제로 해결할 수 있다는 장점은 X축(복제)에 대한 장점이며, 이런 Scale-out을 "필요한 기능"에 대해서만 수행하여 효율적인 확장이 가능하다는 것은 Y축(분리)에 대한 장점이라고 보면 되겠다.

Z축 : Data Partioning

데이터를 나눠서 분리한다는 것이다. 위에서 말한 각 Component는 개별의 DB를 가지고 있다는 것과 동일한 의미이다.

Monolithic에서는 Application을 복제할 때 DB 전체를 복사해야 했기 때문에 DB를 복사하는 데에도 부담이 존재했다.

하지만 MSA에서는 복제할 Component에 대한 DB만 복사하면 되기 때문에 손쉽고 부담 없는 DB 복제가 가능하여 더욱 뛰어난 확장성을 가지게 되는 것이다.

Conway's Law(컨웨이의 법칙)

SW 구조와 SW를 만드는 조직의 구조가 일치할 수 있음

MSA는 Component별로 팀을 배치할 수 있게 된다.

이 경우 각 팀별로 책임 소재가 명확해지며 개발 및 관리해야 하는 기능들에 대해 파악하기가 더욱 수월해진다.

관리자 입장에서는 책임 소재가 명확하기 때문에 문제가 발생한 Component를 관리하고 있는 팀에 바로 수정 요청을 할 수 있어 관리가 쉬워진다. 특히 Component가 독립적으로 존재하기 때문에 발생한 문제가 전체 Application에 확장되지 않으며, 이는 문제가 되는 Component를 찾기 더 쉬워진다는 장점을 가지고 온다.

팀 입장에서는 Component가 다른 기능들과 독립성을 띄고 있기 때문에 다른 팀과의 의존성을 줄이며 개발을 진행할 수 있고 팀에서 알아야 하는 기능들이 독립적이기 때문에 책임져야 할 기능에 대한 파악이 쉬워지며 이는 개발 및 관리가 쉬워진다는 장점을 가지고 온다.

추가적으로 Component 하나를 팀에 할당시키는 방식으로 개발이 진행되기 때문에 팀별로 자율성을 가진다는 장점도 있다.

즉, Component에 가장 적절하다고 생각하는 기술 및 DB, 개발 언어를 활용할 수 있게 되어 팀별로 조금 더 자유롭게 개발을 진행할 수 있다.


MSA 단점

속도(성능)

MSA에서는 Component별로 REST API를 통해 통신하게 된다.

이런 방식을 활용할 경우 POJO 객체에 저장된 Data를 JSON이나 XML로 변환하고, 반대로 JSON이나 XML을 POJO 객체에 저장하는 Marsharing 오버헤드가 발생하게 된다.

이런 오버헤드와 다른 Component 호출을 위한 Network 전송 시간 또한 추가로 소요되게 된다.

즉, Monolithic에서는 Call-by-reference 방식으로 메서드의 주솟값 호출을 통해 바로 기능을 활용할 수 있었으나 MSA에서는 원하는 Component와 통신하기 위하여 데이터의 형태를 변경하고 Network를 통해 데이터를 전송하는 시간까지 추가로 들기 때문에 속도 측면에서 손해가 발생할 수밖에 없다.

메모리 낭비

Server라는 것이 모듈 하나만 배치한다고 바로 구동시킬 수 있는 간단한 시스템이 아니다.

서비스 지속을 위한 메모리도 필요하고 Tomcat 운영을 위한 메모리도 필요할 것이며 Docker 등의 특수한 기술을 활용할 경우 기술 설치에 필요한 메모리도 소모될 것이다.

즉, Component뿐만이 아닌 Component가 제대로 실행되기 위한 부가적인 메모리가 필요하게 된다.

테스팅의 어려움

사실 위 2개의 단점은 최근 컴퓨팅 파워 자체가 발달하였고 Network Infra도 큰 발전이 있었으므로 어느 정도 상쇄되는 면이 존재한다.

추가로 OS의 가용 메모리 용량도 늘어났고 비동기 Pattern이나 Caching 등을 활용하여 성능에 대한 문제도 최대한 해결할 수 있다.

하지만 이 문제와 아래에 설명할 운영적인 문제는 기술의 발전으로는 해결이 어려운 문제들이다.

Application 측면에서 모든 서비스들은 분리되어 있다. 하지만 어떤 기능이든 1개의 Component를 통해서만 수행되지는 않는다. 다른 Component와의 통신을 통하여 데이터를 주고받음으로써 실제 기능이 구현되게 된다.

예를 들어 Payments(지불)에 대한 기능을 수행할 때 당연히 개인 인증이라던가 지불 기능을 활용하고 싶은 Componet와의 통신이 필수적일 것이다.

결국 다른 Component와의 통신을 통해 실행되는 사용자 시나리오에 대한 테스트를 진행할 경우 여러 서비스에 걸쳐 테스트를 진행해야 한다.

즉 테스트 환경 구축이 어려우며, 다른 Component에 테스트가 의존적이게 되고 테스트에 문제가 발생하였을 경우 해당 Component 이외에도 통신하는 다른 Component들까지 동시에 확인해야 하므로 테스팅 복잡도가 올라가게 된다.

운영 관점의 문제

관리가 쉽다는 것과 운영이 쉽다는 것은 전혀 다른 문제이다

MSA에서는 운영 측면에서 매우 어렵다는 단점을 가진다.

MSA에서는 Component별로 다른 기술을 활용할 수 있는데 이는 통합적인 운영 보수의 난이도를 높인다.

운영 측면에서는 Component별로 다른 기술을 활용하기 때문에 알아야 하는 기술의 범위가 넓어지게 된다. 또한 시스템이 잘게 나뉘어 있기 때문에 운영을 해야 할 Server의 수가 늘어나게 되며, Server별로 활용하는 기술 또한 달라져야 하기 때문에 운영 측면에서 난이도가 매우 높아지게 되는 것이다.

따라서 MSA를 활용할 경우 사실상 운영과 개발을 분리하는 Waterfall 방식을 활용하기란 거의 불가능하며 DevOps 개발 방법론을 활용해야 한다는, 개발 방법론이 한정된다는 단점과도 이어진다.

데이터 정합성 관리의 어려움

MSA에서는 Component별로 DB가 나누어져 있다.

그렇다면 과연 DB에 저장되는 데이터마저 독립적이냐라고 물어보면 사실 아니라고 답하는 게 맞을 것이다.

예를 들어 차를 빌리는 Application을 생각해보자.

이때 "차를 빌리는 User Component"와 "차를 관리하는 Component"가 존재할 것이다.

이때 User가 차를 빌렸을 경우 차를 관리하는 Component에서는 해당 차가 빌려져 있다는 것을 명시해야 하고 User 입장에서는 빌린 차에 대한 정보가 저장되어야 한다.

그런데 DB 자체가 분리되어 있기 때문에 사실상 Query문 2개를 실행시켜야 하는데, 분리된 DB이므로 제약 조건이 사실상 없는 것과 동일하다.

즉, 서비스가 동작하면서 다른 DB에 중복되는 데이터가 저장되어 메모리 상의 낭비를 가져오기도 하고 1개의 DB에서 Update 된 내용이 다른 DB에서는 Update 되지 않는 데이터 정합성의 문제가 발생할 수도 있다.


SOA와 MSA

개인적으로 SOA와 MSA는 알아두면 좋지만 굳이 알지 않아도 괜찮은 개념이라고는 생각한다.
따라서 이 부분은 Skip 하고 다음 Section으로 넘어가도 무관하다고 생각한다.

SOA는 애플리케이션이 해결해야 하는 전체 문제를 Service 단위로 나누어 ESB라는 중앙 서비스를 활용해 SOAP 기반 통신으로 서비스끼리 통신하는 형식으로 애플리케이션을 구성하는 Architecture를 말한다.

설명만 들어도 MSA와 유사함을 알 수 있는데, 결국은 "Service"라는 작은 단위로 큰 문제를 나누며, MSA에서는 REST API를 활용했지만 SOA에서는 SOAP 기반 통신으로 Service끼리 통신하는 방식으로 전체 애플리케이션이 구성된다는 것도 그러하다.

단지 현재 트렌드인 MSA와는 달리 유사한 개념인 SOA는 사실상 사장된 상태이다. 왜 그러까?

이는 SOA에서 활용하는 "ESB"라는 미들웨어 때문이다.

ESB는 성능상 문제도 많았고 중앙 집권적 미들웨어다 보니 ESB에 문제가 발생했을 경우 서비스 전체에 영향을 미쳐 서비스 작동이 안 되며 통신도 불가능해지게 된 것이다.

ESB를 관리하는 것이 대형 벤더들이라는 것들도 SOA의 인기가 시들해진 이유 중 하나였다.

MSA는 REST API를 통해 통신하므로 Component끼리 연결하는 데에 있어 정해진 솔루션이 없으며 초기 비용도 크게 들지 않는다. 하지만 ESB 기술은 벤더들이 제공하는 형식을 활용해야 했으므로 SOA에 대한 솔루션과 장비들의 가격이 비싸졌다.

당연히 이런 비싼 SOA의 솔루션과 장비는 SOA 구성에 큰 부담을 느끼게 하였고, 이런 부담감과 ESB의 불안정성은 결국 SOA의 쇠락으로 이어졌다.

MSA는 ESB라는 중앙 집권적 미들웨어가 필요하지 않아 서비스 전체에 영향을 미치는 Component가 적어 서비스 전체에 영향을 주는 에러가 거의 없으며 경량화된 메시지(JSON, XML 등)를 통해 Component끼리 통신하므로 초기 비용이 적게 든다는 장점도 가진다.

이런 점 이외에도 SOA가 중요시한 원칙 또한 SOA가 쇠락한 이유 중 하나라고 생각한다.

SOA는 Service 사이의 공유가 중요하다는 원칙을 가지고 있었기 때문에 여러 서비스 사이의 리소스 공유를 중요시하였다.

이를 위해 ESB에서 Orchestartion이라는 기능을 많이 활용하였는데, 이는 서비스 간의 결합도를 증가시키며 ESB의 성능을 떨어뜨리는 데에도 큰 영향을 끼쳤다.

또한 Service 사이의 공유를 중요시하였기 때문에 Monolithic Architecture처럼 1개의 DB를 모든 서비스가 공유하는 방식을 활용하였다.

결국 Service 간 결합도를 낮춰 개발을 진행하기 위해 작은 Service로 분할하였는데 ESB가 분할한 Service를 합쳐 결합도를 다시 높인다는 점에서 큰 메리트가 느껴지지 않았으며, MSA는 결합도를 낮춘 Component들을 결합도가 낮은 상태로 그대로 활용했기 때문에 각광받고 있다고 생각한다.

ESB vs API Gateway

사실 MSA에서도 ESB와 비슷한 역할을 수행하는 미들웨어를 활용할 수 있다. 바로 API Gateway이다.

그렇다면 이 둘에 대해서 잠깐 알아보고 가자.

SOA 프로젝트의 실패 중의 하나가 ESB로 꼽히는 경우가 많은데, ESB를 Proxy나 Gateway처럼 가벼운 연산만이 아니라 여러 개의 서비스를 묶는 로직(Orchestration)에 활용함으로써 무겁게 사용했기 때문이다.

거기에다 ESB는 메시지를 XML로 변환하여 처리하는데 XML로 데이터를 처리할 때 파싱에 대한 오버헤드가 매우 크다. 또한 ESB를 다른 시스템과 통합하기 위한 EAI적인 역할까지 수행하도록 활용함으로써 많은 실패 사례를 만들어냈다.

(EAI : 다양한 애플리케이션을 연결해주는 것)

API Gateway는 이러한 ESB의 문제점을 해결하기 위해 MSA에 도입된 미들웨어 제품군이다.

ESB와 기본적인 특성은 유사하나 기능을 낮추고 EAI의 통합 기능을 제거하여 API 처리에만 집중한 제품군들이다.

API Gateway는 MSA에 도입할 경우 내부적인 잡음이 많이 발생할 수 있고 초기 설계나 구현이 잘못되었을 경우 도입했을 때 실패 가능성이 높은 모듈이라는 특징을 가진다.

API Gateway는 MSA의 여러 단점을 보완해줄 수 있는 Component이지만, 안정적인 도입을 위해서는 팀적으로 상당한 수준 높은 기술적 이해와 개발 능력이 요구되는 미들웨어인 것이다.

API Gateway 역할

Endpoint 통합 및 topology 정리

Microservice로 분할된 Componenet는 분리된 URL을 활용하는데, blog 같은 경우 blog.naver.com, cafe 같은 경우 cafe.naver.com 등으로 URL을 분리하는 형식이다.

사용자 입장에선 웬만하면 naver.com은 동일하고 naver.com/blog, naver.com/cafe로 처리하는 것이 UI/UX적으로 좋을 수 있다. 특히 MSA는 컴포넌트를 최대한 업무 단위로 잘게 자르기 때문에 Component별로 URL을 할당할 경우 URL 수는 많아질 것이고 나중에는 sportsnewsletter.naver.com 같이 URL 자체가 너무 길어져 직관적이지 않을 수 있다.

또한 Component 사이에 직접 통신을 통해 사용자 시나리오가 수행된다고 가정해보자.

이 경우 REST API를 통해 통신하는 Comonent가 다양해지게 되며 이는 거미줄 모양의 복잡한 서비스 컴포넌트 간 호출 구조가 만들어질 것이다.

아래 사진과 같이 복잡한 거미줄 모양의 호출 구조를 가질 경우 훗날 관리의 문제가 발생할 수 있는데, 1개의 End Point를 변경하였을 때 연결된 Component와의 관계를 생각하지 않아 문제가 발생하거나 제대로 관리가 이뤄지지 않을 수 있게 되는 것이다. 이는 Component의 수정이나 추가가 쉽다는 MSA의 장점을 깎아먹는 커다란 단점으로 이어진다.

API Gateway는 위 2개의 단점을 한 번에 해결할 수 있는 미들웨어 솔루션이다.

API Gateway는 Hub&Spoke 방식을 활용하여 Topology를 변형시킴으로써 서비스 간 호출을 단순화시키고 중간에서 요청을 모두 관리하기 때문에 Endpoint 통합을 가능하게 하여 거미줄 모양의 복잡한 컴포넌트 간 호출 없이도 정상적으로 사용자 시나리오가 수행될 수 있게 만들어준다.

Orchestartion

ESB가 실패한 이유 중 하나로 꼽은 Orchestration은 API Gateway에서도 수행할 수 있는 기능이다.

Orchestration이란 기존 Open API의 Mash Up과 같은 개념으로 여러 개의 서비스를 묶어 하나의 새로운 서비스를 만드는 것이다. 예를 들어 물품 구매와 포인트 적립이라는 서비스가 존재할 때, "물품 구입 시 포인트 적립"이라는 새로운 서비스를 만들 수 있는 것이 Orchestartion 기능이다.

MSA는 서비스가 잘게 쪼개졌기 때문에 이런 서비스 간 통합이 가능하다.

이런 Orchestartion은 사실 API Gateway 계층에 매우 부담을 주는 작업이다.

실제로 SOA 시절 많은 ESB 프로젝트가 실패한 것이 Orchestartion 로직을 너무 과도하게 넣어 성능 문제가 발생하는 이유도 한몫했기 때문이다.

따라서 이 Orchestartion을 활용하기 위해서는 MSA에 대한 높은 이해와 API Gateway 자체에 대한 높은 수준의 기술적 이해가 선행되어야 한다.

공통 기능 관리

API에 대한 인증이나 Logging 같은 모든 프로세스에서 적용되어야 하는 개념들은 Orchestration으로 처리하기 위해선 너무나 많은 Orchestartion 로직이 생성되고, 이는 ESB처럼 낮은 성능 문제로 이어질 것이다.

따라서 애초에 API 인증이나 Logging 같은 공통 기능을 중간 단계인 API Gateway에서 처리하게 함으로써 API 자체는 비즈니스 로직에만 더욱 집중해 개발을 진행할 수 있게 할 수 있다.

위 사진에서 볼 수 있듯 API Gateway는 UX, 즉 User가 보는 환경과 로직을 처리하는 Component 사이에 위치해있기 때문에 User의 이벤트 처리를 위해서는 무조건 API Gateway를 통과하게 되어 있으며 무조건 통과하는 계층이라면 차라리 공통 기능 관리를 API Gateway에서 처리하는 것이 효율적일 것이다.

API Gateway가 공통 기능을 관리한다면 개발자는 공통적인 기능의 중복 개발과 공통 코드의 반복을 줄일 수 있을 것이다

profile
혹시 틀린 내용이 있다면 언제든 말씀해주세요!

0개의 댓글