# MSA(Micro Service Architecture) 서비스 간 통신

2020. 5. 19. 00:47 개발 이야기/아키텍처

 

 

안녕하세요. 정말 오랜만에 글을 쓰는 해커의 개발일기 입니다.

 

 

오늘은 쿠버네티스의 소개OpenTracing - Jaeger의 소개 때

언급했던 MSA에 대해서 다시금 고뇌하는(?) 시간을 갖도록 하겠습니다.

 

 솔직하게 얘기를 하자면 MSA를 위한 솔루션을 개발하고 있지만, 어렴풋이 이해만 하고 있는 수준의 MSA 이해도를 가지고 있었습니다. 그러다가 불현듯이 어떤 생각이 들어 조금 더 깊은 이해를 하게 되었는데요. 제 머릿속에 떠오른 질문은 이랬습니다.

"MSA(Micro Service Architecture)에서 서비스를 별도 프로세스 혹은 별도 서버에 띄우게 된다고 하는데, 그래서 gRPC를 쓰는 건가?"

왜 gRPC가 떠올랐냐면, 저는 Jaeger라는 OpenTracing 기술을 커스터마이징 하고 있는데 계속해서 눈에 보이는 것이 gRPC였습니다. 그리고 gRPC가 있는 곳에는 항상 보였던 시계열 데이터를 수집하고 저장하는 시계열 데이터 DB인 프로메테우스에서 사용되는 .proto와 .pb.go 파일들에 대한 궁금증도 계속해서 가지고 있었는데요.

도대체 이 .proto 파일은 뭐고, .pb.go 파일은 뭘까? 궁금해하면서도 이래저래 시간에 쫓겨 찾아볼 생각은 못했었는데요. 그러다가 사내 세미나를 해야 하는 시간이 와서 준비를 하는 김에 찾아봤습니다.

먼저 MSA를 이해하고 gRPC를 왜 사용하는지 알아보도록 하겠습니다.

왜 자꾸 MSA, MSA 하는 것일까? 도대체 뭐길래?

쉽게 풀이하자면 MSA는 하나의 웹서비스에 있는 기능들을 하나씩 쪼개서 각각의 서비스로 올려놓은 것입니다. 이미지로 표현해봤습니다.

 

 

이렇게 각 포트 별로 혹은 각각 다른 서버에 서비스를 각각 올려서 하나의 큰 웹서비스가 되는 구조가 있다고 생각을 해봅시다. 이렇게 잘게 잘라서 각각의 서비스로 띄운 구조를 바로 Micro Service Architecture라고 합니다.  도대체 왜 이런 구조를 사용할까요?

예를 들어 설명해 보겠습니다.

우리는 웹 쇼핑몰을 운영하고 있습니다. 다행히 우리의 서비스를 고객이 많이 찾아주어서 우리의 웹서비스를 효율적으로 서버를 증축하려고 합니다. 우리의 웹서비스의 고객 사용 추이를 봤을 때, regist나 select는 정말 많이 사용되지 않는 api입니다. 그리고 정말 많이 사용되는 api는 pay와 shopping입니다. 

 

MSA 장점 - 확장성

이런 경우 MSA구조가 아닌, Monolithic 구조를 가지고 있다면 큰 서버를 증축해 잘 사용하지 않는 api에게도 리소스가 분배되도록 합니다. 하지만 MSA구조를 가지고 있다면 pay와 shopping 서비스만 늘려주면 됩니다. 클라우드 환경에서 사용 시 아주 손쉽게 서비스를 복재해 scale-out 할 수 있는데요. AWS의 autoscale과 연결된다면 아주 큰 효율을 보여주겠죠?

MSA 장점 - 배포의 용이성

각각의 서비스로 운영이 되기 때문에 만약 위 그림에서 board 서비스만 수정을 했을 경우 board 서비스만 새로운 이미지로 변경하면 되기 때문에 빠르고 간편한 배포를 할 수 있습니다. 불법 어선 하나를 잡고자 항공모함을 띄울 수는 없겠죠?

MSA 장점 - 장애 처리 용이

서비스에 장애가 발생한 경우 Monolithic 구조를 가진 서비스보다 확실히 장애처리가 수월할 수 있습니다. MSA 구조의 경우 각각 서비스가 돌고 있기 때문에 특정 서비스에서 장애가 발생한다고 모든 서비스에 영향을 끼칠 확률이 더욱 낮을 수밖에 없겠죠?

 

그럼 어떤 단점이 있을까요?

MSA 단점 - 트랜잭션

쇼핑몰 거래 서비스를 예로 들면 A 제품을 구매할 때 쿠폰과 적립금, 카드 세 가지를 모두 이용해 구매를 하고자 할 때 이 카드 결제만 실패를 하면 쿠폰과 적립금 모두를 롤백(ROLLBACK) 해줘야 합니다. 이런 경우에는 Monolithic 구조가 더 처리하기는 쉬운데요. 이렇게 하나의 트랜잭션으로 관리가 필요한 서비스는 MSA로 개발하기에 어려움이 있습니다. 

MSA 단점 - 성능

정말 마음 아픈 이야기만 이렇게 좋은 아키텍처를 가지고 있음에도 당연히 데이터가 한 프로세스가 아닌 다른 프로세스와의 통신을 해야 하고 다른 서버에 떠 있는 서비스와의 통신이 불가피하기 때문에 네트워크를 사용할 수밖에 없는데요. 물론 하나의 서버에서 VM으로 올리거나 container 형태로 서비스를 올린 경우에는 조금 덜 할 수 있지만 클라우드 서비스를 이용하는 경우에는 네트워크 통신이 불가피한 상황입니다. 

 

바로 이 MSA 단점 - 성능을 보완하기 위해 gRPC를 사용하고 있는데요. gRPC를 설명하기 위해 정말 많은 길을 돌아온 것 같습니다. 서비스 간에 통신을 하는데 HTTP 통신을 한다고 가정을 해보겠습니다. 서비스가 호출될 때마다 TCP 세션을 맺어 통신을 하기 때문에 서비스의 호출이 많은 경우에는 성능 저하가 발생(병목현상 등)할 수밖에 없는데요. 이런 문제를 개선해 성능 향상을 하기 위해 gRPC를 도입하는데요. gRPC에 대해 알아보겠습니다. 

 

 

gRPC는 뭘까요? 기존에 RPC를 구글에서 조금 더 손쉽게 사용할 수 있도록 구현한 것입니다. gRPC는 이진 메시지 형식인 protobuf를 사용해 직렬화하고 이를 통신하고 있는데요. 

gRPC 통신에 쓰이는 데이터 명세가 바로 .proto 파일이고 이를 protoc 바이너리를 이용해 빌드한 것이 .pb.go 파일입니다. 바로 이 protobuf로 엄격한 사양을 지켜 통신하기 때문에 거의 모든 언어에서 통신이 가능합니다. 어떤 언어로 통신을 하던 주고받는 데이터는 protobuf 형태이기 때문입니다.

 

 

gRPC는 XML 통신보다 무려 20 ~ 100배가량 빠른 통신을 자랑하고, HTTP 통신처럼 매번 세션을 맺는 것이 아닌 한 번의 TCP 세션을 맺어 짧게 짧게 데이터를 주고받아 통신에서 오는 병목현상 등의 성능 문제를 해결할 수 있습니다. 그리고 양방향 스트리밍이 지원되기 때문에 다양한 서비스에도 접목할 수 있습니다. 

정리하면, 

     1. 한번의 TCP 세션을 맺는다.

     2. HTTP, XML 보다 훨씬 빠르다.

     3. 대부분의 언어들이 호환된다.

단점은 아직 브라우저 지원이 조금 약한 점이 있습니다. 그리고... 어렵습니다.

네, 공부하기가 까다롭더군요. 사실 오늘 gRPC를 이용한 통신을 스터디해서 함께 코드도 올려보고 싶었지만, 다음을 기약해야겠습니다. 

MSA 구조로 서비스를 개발하고 서비스 간 통신을 gRPC로 구현을 한다면 상당히 성능 개선된 모습을 확인할 수 있을 것 같습니다. 더불어 서비스 간에 어디서 성능이 저하되고 서비스의 가용성이 떨어지는지 모니터링을 하려면 기존에 설명한 OpenTracing을 접목시킨다면, 정말 유용하고 간편하고 멋지게 서비스를 운영할 수 있을 것 같습니다.

이렇게 MSA 구조와 MSA 구조의 서비스간 통신에 대한 고뇌의 시간을 가졌는데요. IT는 정말 공부할 것도 많고 재밌는 것도 많은 것 같습니다. 앞으로도 재밌는 것들이 있다면 정리해서 블로그에 업로드하겠습니다. 아마 다음은 머신러닝 관련 글이 될 것 같습니다. 이상으로 MSA에 대한 고뇌(?)였습니다.