MSA와 API GATEWAY의 개념

Monolitich Architecture

먼저 MSA를 알기위해서는 모노리틱 아키텍쳐를 알아야해!!

모노티릭 아키텍쳐란?

기존의 전통적인 웹 시스템 개발 스타일이고 하나의 어플리케이션 내에 모든 로직들이 모두~ 들어가있는 그런 통짜구조라고 생각하면 돼.

이런 느낌인거지!! 각 컴포넌트들은 call by reference 구조를 통해 개발툴 등에서 커다란~ 하나의 어플리케이션만 개발하면 되기에 배포가 간편하고 테스트를 할 때에도 하나의 어플리케이션만 수행하면 되니까 편해!!

하지만 임마는 시스템이 커져가면서 대형시스템으로 가면 문제점이 발생해.


Monolitich의 문제점

대형시스템으로 갈수록 크기가 커지기 때문에, 빌드 및 배포시간, 서버의 기동시간이 오래걸리게 되고 프로젝트를 진행하는 관점에서도, 한 두 사람의 실수가 전체 시스템의 빌드 실패를 유발할 수 있기에 협업개발이 아주 그지 같아져.

그리고 각 컴포넌트들이 call by reference 기반으로 연결되어 있으니까 전체 구조를 파악해야 개발이 가능해지게 되지.

더욱 우엑 같은건 특정 컴포넌트를 수정하면 전체를 재배포 해야한다는 거야. 그럼 다른 기술을 도입하고자 할 때 매우 귀찮은 일이 벌어지겠지??

뭐 그래도 무조건 나쁜건 아니야! 규모가 작은 어플리케이션은 유용할 수 있꼬 call by reference에 의한 호출은 성능에 있어 제약이 덜하지. 그리고 하나의 구조로 되어있으면 트렌젝션 관리가 편하다는 점도 있어.

자~~ 이래서 생겨난게 뭐다? 바로 MSA 라는 놈이야.



마이크로 서비스 아키텍쳐

그렇게 흐름에 맞춰 대용량 웹 서비스가 많아짐에 따라 정의된 아키텍쳐인데 그 근간은 SOA라는 놈에 있어.

SOA가 뭐냐? Service Oriented Architecture야.

말그대로 서비스기반의 구조를 정의한거지. 이 구조는 나온지 꽤나 됬는데 오케스트레이션이나 뭐 기타 문제가 많아 사라져버린놈이야.

무튼 마이크로 서비스 아키텍쳐에서는 각 컴포넌트를 서비스라는 개념으로 정의해.

예를들어서 어떤 쇼핑몰관련 시스템이라면 사용자 관리, 상품 관리, 주문관리와 같이 각 업무별로 서비스를 나눠서 정의하는거지!! 사용자/상품 관리처럼 업무를 동시에 묶어서 하나의 서비스로 정의하진 않는다는거야.

그럼 결과적으로 그 구조는

이런 형태가 되게 되는거지. 각 컴포넌트는 서비스라는 형태로 구현되고 API를 통해 타 서비스와 통신하는거야.

데이터 저장관점에서 생각해볼까?

중앙집중화된 하나의 통짜 디비를 사용하는게 아니라 서비스 별로 별도의 데이터베이스를 사용해.

그림 보니까 바로 차이가 보이지?

이렇게 하면 뭐가 좋은지 아마 감이 잡힐거야.

MSA처럼 서비스를 독립적으로 개발 및 배포,운영 할 수 있다는 장점을 가지게 되는거지. 하지만 이렇게 진행할 경우 API를 통해서만 데이터를 주고받고 할 수 있고 성능상 문제를 야기할 수 있다는거지. 그리고 데이터베이스 간 트렌젝션을 묶을 수 없는 문제점이 있어.

자~ 그럼 저~위에 MSA 그림에서 만약 서비스들이 엄청나게 증가하고 클라이언트와 서버간 API 통신 뿐만 아니라 서버간의 API 통신이 많이 이루어진다고 생각해봐. 그때 토폴로지가 어떻게 될 거 같애?? 줜나 엉망이겠지??

그래서 이거에 대한 솔루션을 등장한게 있어

바로~~ API GATEWAY라는 놈이야!



API GATEWAY 개념

이 api gateway란 놈은 마치 프록시 서버처럼 api들 앞에서 모든 api에 대한 endpoint를 통합하고 몇가지 추가적인 기능을 제공하는 미들웨어야. SOA의 ESB의 경량화 버전이래. SOA에 관심있으면 추가로 보면 나쁘진 않을 거 같애. 근데 좋지도 않을 거 같기도..? ㅎㅎ..

얘가 하는일은 다음과 같애.


Endpoint 통합 및 토폴로지 정리

MSA 구조의 문제점 중 하나는 위에도 말했듯이 각 서비스가 다른 서버에 분리 배포 되기 때문에, API의 Endpoint 즉 서버의 url이 각기 다르다는거야!

그리고 클라이언트에서 서버간 API통신이나, 서버간의 API통신의 경우 P2P형태로 토폴로지가 복잡해진다. 이는 향후 관리 문제를 유발할 수 있어. 여까지는 느낌 왔자나?

자~ 그래서 이렇게 해결하자는거지.

→ 중앙에 서비스 버스와 같은 역할을 하는 채널을 배치 시켜서 전체 토폴로지를 P2P에서 HUB&SPOKE 방식으로 변환 시켜 단순화시킨거야.

요롷게 말이야! 확 괜찮아졌찌?

다음으로는


Orchestration

기존의 api의 mash up 과 같은 개념으로 즉 여러개의 서비스를 묶어서 하나의 새로운 서비스를 만드는거야.

이러한 orchestation을 api gateway를 통해서 구현할 수 있어! 하지만 이렇게 되면 api gateway 입장에서는 존나 부담이 되겠지??

실제로 MSA가 SOA를 기반한다 했짜나? 그리고 SOA가 실패했다했었지? 이때 실패했던 이유가 API GATEWAY의 근간인 SOA의 ESB 프로젝트가 과도하게 Orchestartion로직을 쳐넣어서 성능문제가 발생한거야.

그렇기에 이 orchestration 서비스의 활용은 msa에 대한 높은 이해와 또 api gateway 자체에 대한 높은 수준이 있을 때 적절히 사용하면 조아.

다음으로는


Cross cutting function handling

즉 공통 기능 처리야!!. 생각해봐. 뒷단에 저렇게 기능별로 서비스들을 뒀을 때 분명 서비스마다 공통적으로 처리되는 놈이 있을 거 같지??

예를 들어 api에 대한 인증이나, logging과 같은 기능들이 있겠지. 이러한 공통 기능에 대해서 서비스 컴포넌트 별로 중복개발하여야하는 비효율성이 유발될 수 있는데 이런 부분들을 만약

api gateway에서 공통적으로 처리해준다면? api 자체는 비지니스 로직에만 집중할 수 있겠지? 그러기 위한 기능이야.

그 다음으로는


배포

내가 생각할 때에는 이게 가장 큰 장점이거등.

유연하게 배포할 수 있따는 거지. 각 서비스가 다른 서비스에 물리적으로 완벽하게 분리되어있기 때문에 변경이 있는 서비스 부분만 부분 배포가 가능해지는거지.

다음으로


확장성

서비스 별로 구분 지어 놈으로써 부하가 많은 서비스에 대해서만 확장을 하는게 가능해져 조금 더 유연한 확장 모델을 가질 수 있는거지.

반대로 모노로틱 아키텍쳐의 경우 특정 서비스의 부하가 많아 성능확장이 필요하면 뭐 서버수를 늘리거나 혹은 각 서버의 cpu를 늘려야하지만, msa 같은 경우 부하를 많이받는 서비스 컴포넌트만 확장시켜주면 되는거야!

그럼 다 완벽하냐?? 그건 아니지. 모노로틱의 단점을 보완한다는 장점이 있지만 반대로 모노로틱의 장점에 있어서는 오히려 msa에게는 단점이 될 수 있는거야.

먼저 성능에 대해 생각해보자. msa 는 서비스간의 호출을 api 통신을 이용하기 때문에 값을 뭐 json이나 xml 데이터 모델로 변환하는 오버헤드가 발생하고 호출을 위해서 이 메시지들이 네트워크를 통해서 전송되기 때문에 추가적인 시간이 소요되는거야.

그리고 트렌젝션같은 경우에서도 단점이 있어. api 기반의 여러 서비스를 하나의 트렌젝션으로 묶는 것은 힘들어. 그래서 일부 트렌젝션이 중요한 금융쪽에서는 모노리틱 구조로 되어있는 경우도 있는거지.

자~ 이제 전체적인 느낌은 잡았을 거고 api gateway에 대해 조금 더 자세하게 들어가보자.


API GATEWAY 주요기능

API Gateway의 주요기능은 다음과 같애.

1) 인증/인가 관련된 기능

api gateway의 가장 기본적인 기능은 api에 대한 인증과 인가 관련된 기능이야. 아까 위에서 잠깐 언급했는데 서비스 마다 공통된 기능들을 api gateway가 맡게되면 좋다는 내용이 있었지?

그거야! 인증,인가가 그런 느낌이지.

인증은 api를 호출하는 클라이언트에 대한 identity 즉 신분을 확인해 주는 거구 인가는 클라이언트가 api를 호출할 수 있는 권한이 있는지를 확인해줘

다음으로

2) api 토큰발급

인증/인가를 거칠 때 마다 매번 사용자의 인증/인가 절차를 거치는 거는 매우 불편하지. 사용자로부터 매번 id 비밀번호를 받기는 번거롭고 또 이걸 저장하고 있자니 해킹의 빌미가 될 수 있어.

그래서 사용하는 것이 바로!! 토크으으은!!!

사용자 인가가 끝나면 사용자가 api를 호출할 수 있는 토큰을 발급해줘.

api 서버는 이 토큰으로 사용자의 identity와 권한을 확인 후 api 호출을 허락해 주는거지!

그리고 여기서 api gateway는 클라이언트를 인증 후 이러한 api 토큰을 생성 및 발급해주는거야.

그림으로 보면

이런 구조라고 볼 수 있어.

여기서 조금 더 들어가보자.

인증에도 여러가지 방법이 있는데 크게 두가지야. 바로 권한 정보를 토큰 자체에 저장하느냐, 서버에 저장하느냐에 따라서 나뉜거야.

그럼 먼저

2.1) 클레임 기반의 토큰

토큰 자체가 그러한 정보들을 가지는거지.

JWT(Json Web Token)이나 SAML 토큰이 이에 해당해.

뭐 다들 알겠지만 느낌 살려서

1
2
3
4
5
{
"name": "Terry",
"role": ["admmin", "enduser"],
"org": "petstore"
}

요런 느낌이다 보면되지.

JWT가 이런 형식이지. 이런 Claim 방식이 좋은 점이 뭘까? 조금만 생각해보면 알 수 있는데

서버의 입장에서 한번 생각해봐. 이 서비스를 호출한 사용자에 대한 추가정보가 이미 토큰안에 있기에 다른 곳에서 가지고 올 필요가 없다는거야! 여기서 오는 이점들이 생기는거지.

그럼 이 jwt 방식에서 누군가 토큰을 변조하면 엌하냐??

→ HMAC 방식을 사용해서 이를 막아. 원본 메시지에서 해쉬 값을 추출하고 이를 비밀키를 이용해 복호화 시켜서 토큰의 뒤에 붙이는거지. 만약 변조가 일어나면 변조된 메시지에서 생성한 해쉬값과 토큰 뒤에 있는 HMAC 값이 다르게 되겠지?

이걸로 구분하는거야.

그럼 이와는 대조적으로

2.2) 서버에 저장하게 되는 경우에는

이 경우에는 유니크한 스트링만을 리턴해줘.

이런 느낌인거지.

정보가 서버에 저장되기 때문에 안전하고, 많은 정보를 저장할 수 있으며 또 토큰에 대한 정보를 수정하기가 용이해. 하지만 서버에 별도의 저장공간을 만들어야하니 구현에 노력이 더 들어가겠지. 토큰은 매 api 호출마다 정보를 가지고와야하기에 dbms 보다는 redis,memcached와 같이 메모리 기반의 고속스토리지를 이용하는것이 좋아.

Claim기반 토큰은 이러한 토큰 저장소가 필요없어서 구현에 용이하지만 한번 발급된 토큰의 변경이 어렵지. 그래서 통제하기가 어려워지고 그렇기에 반드시 강제적으로 유효기간을 둬서 재발급하게 해줘야해.

이건 여담이지만 이렇게 api token으로 인증하는 방법이 일반적인 방법이긴한데 서버대 서버간의 통신은 내부 서버의 경우 별도의 인증없이 api를 제공하는 경우도 있고, 외부 서버와의 통신은 특정 ip주소와 통신을 허용하거나 높은 보안을 요구하는경우 양방향ssl등의 인증방식을 사용하기도해. 그래서 api 토큰없이도 인증하는방법이 있기는해.

그리고 한가지 더 얘기해보자면

토근 권한을 주는 방식에는 두가지가 있는데 각 개별권한을 토큰에 부혀하는것과 역할(role)기반으로 권한을 관리하는 2가지 방식이있어.

보통 role기반으로 권한관리방식을 많이 사용해. 역할별로 권한을 부여하고 이 역할을 토큰에 부여하는거야. 이를 RBAC라고 Role Based Access Control이라해.

다음 기능으로는

3) API 라우팅

여기에는 조금 더 세부적으로 나눌 수 있어.

3.1) 백엔드 API 서버로의 로드 밸런싱

가장 기본적인 기능으로는 로드밸런서 기능이야. api gateway 뒷단에 다수의 api 서버가 있다고 할 때, 여러개의 api 서버로 부하를 분산하는 기능을 해. 단순하게 round robin방식으로 부하를 분산할 수도 있으나 각 서버 하드웨어에 따라 부하를 가중치를 줘서 분산하는 기능도 고려가능해. 그리고 특정 서버에 장애가 발생했을 시 이 부분에 대해 로드밸런싱 리스트에서 빼고, 복구되었을때 다시 로드밸런싱 기능에 넣는 기능들이 필요하겠지.

쓰레드 수, 응답 시간등으로 서버의 상태를 파악하고 해당 기능을 해주면 좋겠네.

( 이런 부분들을 활용해서 면접때 대용량 데이터 처리 관련 네트워크 질문에서 좋은 평가 받은적이 많아 )

3.2) 서버 및 클라이언트 별 엔드포인트 제공

같은 API를 여러개의 앤드포인트를 통해서 서비스를 제공할 수 있다면 완전 편리하겠지? 위의 API GATEWAY 구조를 보면 알겠지만 API GATEWAY는 이를 가능하게 해줘. 하나의 시스템이 다양한 서비스나, 다양한 클라이언트들에게 서비스를 제공할 때 , 각각 다른 서비스 별 또는 클라이언트 별로 다른 엔드포인트를 제공할 수 있어.

이렇게 말이야!

어떤 시스템에는 이 방법이 솔루션이 될수도 있겠지?.

api gateway는 api서버가 공통적인 api를 가지더라도, 각 서비스나 클라이언트 타입에 따라서 각각 다른 api를 선별적으로 서비스 할 수 있도록 해주는거야.

3.3) 메시지 또는 헤더기반 라우팅

이거는 먼저 그림을 보고 들어갈게

이것처럼 http 헤더에 country code가 있을 경우, country code에 따라서 유럽에 있는 api를 하거나 또는 미국에 있는 api를 호출할 수 있어.

메시지 기반의 라우팅에서는 만약 메시지가 body에 있을경우 이 정보를 추출하기 위해서 api gateway가 매번 http body에 있는 json을 파싱해서 열어봐야하고 이는 api gateway에 많은 부담을 주게 되버려. 그래서 가능하다면 http url이나 http header에 라우팅 필드를 넣는것이 좋겠지.

만약 부득이하게 body에 있는 내용으로 라우팅을 해야하는 경우에는 호출 빈도가 적은 api는 gateway가 담당하더라도 그렇지 않은 경우에는 별도의 게이트웨이 인스턴스로 분리하거나 뒷단의 api 서버에서 라우팅하도록 하는것이 하나의 방안이야.

3.4) 공통로직 처리

이거는 위에서 한번 언급하고 넘어갔으니 그림과 간단하게만 설명할게

모든 api가 공통적으로 처리해야하는 공통 기능이 필요할 경우 이러한 공통 기능을 api게이트웨이로 옮기게 되면 별도로 api 서버에서 그러한 기능을 개발할 필요가 없으니 비지니스 로직 자체 구현에만 집중할 수 있게 되는 구조야.

3.5) Mediation 기능

A. 메시지 포멧 변환

시지 포맷을 변환하는 기능은 JSON으로 된 요청(request) 메시지가 들어왔을때, 이를 api 서버로 보낼 때 변환해서 보내거나, 또는 api 서버에서 생성된 응답을 클라이언트에 리턴할때 변경해서 보내는 기능을 의미해.

이렇게 사용할 때 필요한거야. 구현은 가능하지만 실제 실무에서는 비추천하는 기능이래.

B. 프로토콜 변환

다양한 서비스나 클라이언트를 지원하게 되면, 클라이언트나 서비스별로 다른 통신 프로토콜을 사용해야 하는 경우가 있어. 예를들어서, 웹에서는 json기반의 rest가 많이 사용되지만, 배나 비행기에 사용되는 센서들은 바이너리 기반의 경량 프로토콜을 사용하거나 예전 시스템의 경우 xml 기반일 수도 있지.

그래서 이런경우 각 서비스들이 새롭게 구현을 하는 게 아니라

api gateway 계층에서 프로토콜 변환을 통해 같은 api를 다른 프로토콜로 서비스할 수 있도록 해줘.

이렇게 말이야!!

C. MEP(Message Exchange Pattern)

이 기능은 말그대로 메시지 호출 패턴의 변화를 지원하게 해주는거야. 이때 호출패턴이란 동기, 비동기 호출과 같은 api 호출하는 메시지 패턴을 얘기하는거지.

그림으로 보면 이해가 바로 갈거야.

위의 예제는 로그를 수집하는 시스템에 대한 구조야. 뒷단에 로그저장 api가 대용량 트래픽에 대한 대응능력이 없을 때, api 게이트웨이에서 큐를 이용해서 api요청을 받고 바로 클라이언트에 ack 메시지를 준 후에, 메시지큐 연동을 이용하여 메시지를 저장한 후, 로그저장 api 서버의 성능에 맞게 흘려주는 방식이야. 이 경우 클라이언트 입장에서는 동기호출이나 실제 메시지의 흐름은 큐를 이용한 비동기 구조로 변경하는 거지.

D. Agrregation

soa에서 orchestration이라고 부른 개념과 같나봐.

자 이 경우를 봐봐.

3개의 api 호출을 하나의 api인 post transfer(인출계좌,입금계좌,금액)으로 군현한다면 다음과 같이 구현할 수 있어.

이경우 언뜻보기에는 좋아보일 수 있으나 하나의 플로우에서 여러 api를 호출해야하고, api 메시지의 body까지 파싱 해 보아야하기에 api 게이트웨이 입장에서 부하가 크겠지?

그럼 이걸 만약에 아래처럼 한다면

이렇게 되면 그런 부분을 조금이나마 해결할 수 있는거지. 만약 클라우드형 api 게이트웨이의 경우에는 고려 해 볼수는 있어. 호출 수로 과금을 매기기에 ! 그러나 디버깅이나 테스팅이 쉽지 않기에 적절히 고민해야해.

E. 로깅 및 미터링

API 호출로깅

API GATEWAY는 API 호출시 공통적으로 호출되는 부분인 만큼 모든 로그를 중간에서 수집하기 좋아!

빅데이터 영역과 연계하면 아주 중요한 자산이 될거야.

또한 API 호출 로그는 차후 문제가 발생하였을때, 문제를 추적하기 위한 중요한 자료로 사용될 수도 있어.

API 미러링 & 차징

미러링은 과금을 위한 API 호출 횟수, 클라이언트 IP, API종류 등을 측정하는 서비스고 차징은 미터링이 된 자료를 기반으로 금액을 계산해내는 서비스

F. QoS 조정 (Quality of Service)

api 서비스를 클라이언트 대상에 따라서 서비스 레벨을 조정하는 기능이야. 예를들어 무료 사용자의 경우 1일 1000건으로 호출횟수를 제한한다거나, 전송 용량이나 네트워크 대역폭을 유료/무료 사용자에 따라 다르게 적용하는 등의 기능.

이런 기능은 클라이언트나 서비스에 따라 유용하게 쓰일 수 있지.

특정 서비스나 클라이언트가 폭주하여 api를 과도하게 사용하여 다른 서비스들이 api를
사용할 수 없게 한다던가 하는 문제를 미연에 예방가능해.







출처 : https://bcho.tistory.com/1005?category=431297

출처 : https://bcho.tistory.com/948