MSA(마이크로 서비스 아키텍처)에 대해서 생각해보기

 

마이크로 서비스는 지난 몇년 동안 매우 인기 있는 주제였다.

마이크로 서비스는 왜 그렇게 인기가 있을까?

아래는 가상 비디오 공유 플랫폼이 Monolithic 형태로 구현 된 후에 마이크로 서비스 형태로 구현되는 방식이다.

image

위의 시스템의 차이점은 하나의 큰 덩어리와 작은 단위라는 점이다.

  • 독립 개발: 작고 독립적인 구성 요소는 그에 맞춰진 작고 독립적인 팀으로 구성할 수 있다.
  • 독립 배포: 각 구성 요소는 독립적으로 확장 할 수 있다. 새로운 서비스가 출시 되면 모든 구성 요소를 배포하지 않고 해당 구성 요소만 배포가 가능하다.
  • 재사용성: 구성 요소들은 작고 특정한 기능을 수행한다. 다른 서비스 또는 제품에 쉽게 적용할 가능성이 높다.

대단한 것 같은데, 왜 이전에는 사용하지 않았나?

컨테이너 기술의 인기가 폭발적으로 증가함에 따라 MSA는 기술적 관점에서 구현하기에 훨씬 실용적으로 되었다. 과거에는 컨테이너 기술의 인기가 높지 않았기에 그러지 않았을까?

마이크로 서비스의 문제점은 무엇인가?

마이크로 서비스가 너무 방대해지게 된다면 어떤 문제점들이 발생하는지 알아보자.

개발자의 복잡성 증가

일반적으로 개발자는 로컬 PC에서 개발을 진행하기에 Monolith 처럼 단일 프로그램을 실행하는 것 보다 훨씬 복잡해진다. Docker Compose를 이용하여 부분적으로 완화 될 순 있지만, 시스템을 구성하는 서비스가 증가할수록 개발자가 직면하게 될 문제는 늘어나게 된다.

운영자의 복잡성 증가

서비스를 유지 관리하는 팀의 경우 복잡성이 증가한다. Monolith의 방식처럼 몇 개의 실행중인 서비스를 관리하는 것 대비 수십, 수백 또는 수천 개의 실행중인 서비스를 관리해야 한다. 많은 서비스와 연동 경로로 인해 운영 복잡성이 증가하게 된다.

Devops 복잡성 증가

문제는 많은 조직이 여전히 분리된 개발 및 운영팀으로 운영되고 있다는 사실이다. 이런 조직은 마이크로 서비스 채택에 어려움을 겪을 가능성이 훨씬 높다는 것이다.

이런 단점을 극복하고자 Devops를 채택한 조직도 어렵긴 마찬가지다. 컨테이너 오케스트레이션 시스템 관점에서 진화하는 시스템을 이해하는 것은 매우 어렵다. 개발자와 운영자가 좋은 소프트웨어를 만드는 마음이 강하더라도 말이다.

전문 지식이 필요

전문가가 해당 프로젝트를 수행하면 그 결과는 훌륭할 것이다. 효과적인 자동화, 모니터링, Orchestration등을 통해 모든 것이 가능하다. 그러나 이런 도전은 기술이 아니다. 가장 중요한 점은 효과적으로 사용할 수 있는 사람들을 찾는 것이다.

이런 Skill set은 현재 시장에서 수요가 많기 때문에 찾기가 어려울 수 있다.

실제 시스템은 경계가 잘못 정의된 경우가 많다

마이크로 서비스의 이점을 설명하기 위해 사용한 많은 자료에는 독립 구성 요소에 대한 이야기가 많다. 하지만 대부분의 경우 구성 요소들은 단순히 독립적이지 않다.

경계가 잘 정의되어 있지 않으면, 이론적인 관점에서 서비스를 독립적으로 배포 할 수 있다고 해도 서비스간의 상호 종속성으로 인해 결국 서비스 집합을 하나의 그룹에 배포해야 하는 상황이 발생한다.

즉, 새 기능을 배포하려면 여러 서비스를 동시에 배포해야 하기 때문에 실제로는 독립적으로 배포할 수 있는 시스템은 거의 없다.

의사 소통의 복잡성

서로에 의존하는 대규모 서비스를 구축할때에는 많은 서비스간 의사 소통이 발생 할 수 있다. 그리고 이로 인해서 몇 가지 문제가 발생한다.

첫째, 네트워크 호출이 실패 할 것을 예상해야 한다. 즉, 하나의 서비스가 다른 서비스를 호출 할때 최소한 여러번은 재시도를 해야하는 것을 의미한다. 이제는 서비스가 잠재적으로 많은 서비스를 호출해야 하기에 복잡한 상황에 처하게 된다.

사용자가 비디오 공유 서비스에서 비디오를 업로드한다고 가정하자. 업로드 서비슬르 실행하고, 데이터를 Transcode 서비스에 전달하고, Subscription을 업데이트하고, 권장 사항을 업데이트해야 할 수 있다. 이 모든 호출에는 일종의 Orchestration이 필요하다.

해당 작업이 실패하면 다시 시도해야 한다.

위의 재시도 논리는 관리하기가 어려울 수 있다. 동기적으로 일을 시도하는 것은 종종 끝나지 않고 많은 실패 지점이 존재하기 때문이다. 이 경우에 보다 안정적인 솔루션은 비동기 통신을 사용하여 통신을 처리하는 것이다. 비동기 패턴은 본질적으로 시스템을 stateful 상태로 만든다. 분산 처리에서 Stateful 시스템을 만드는 것은 어렵다.

버전 관리는 어려울 수 있다.

노드 모듈, Java 모듈, C 라이브러리등 소프트웨어 시스템의 종속성 관리는 매우 어렵다. 독립 구성 요소간의 충돌 및 여러 문제를 처리하기가 매우 어렵다.

분산 트랜잭션

트랜잭션 무결성이 필요한 상황에서 마이크로 서비스는 매우 고통스러울 수 있다.

분산 상태는 매우 다루기가 어렵기에 이 문제를 해결하기 위해서는 마이크로 서비스 모델에서 구현하는데 드는 비용이 매우 클 수 있다.

네트워킹 악몽

마이크로 서비스를 사용할 때 일반적으로 많은 노드에 분산 된 많은 서비스가 존재하고 이는 일반적으로 훨씬 복잡한 네트워킹 배치가 될 것이라는 것을 의미한다. 서비스 간 로드 밸런싱, DNS가 더 많이 사용되는 것, 가상 네트워킹 계층 등이 네트워킹의 복잡성을 숨기기 위해 시도한다.

결론, 마이크로 서비스와 아키텍처를 혼동하지 말자

마이크로 서비스는 구성 요소의 또 다른 패턴 또는 구현일 뿐이며 그 이상은 아니다. 마이크로 서비스가 시스템에 존재한다고 해서 시스템의 아키텍처가 해결되었다는 것을 의미하지 않는다.

마이크로 서비스는 시스템 고유의 설계가 아니라 패키징 및 운영과 관련된 기술 프로세스와 관련이 있다. 구성 요소에 대한 적절한 경계는 시스템에서 가장 중요한 과제 중 하나이다.

Docker 컨테이너 여부 및 서비스 크기에 관계없이 항상 시스템을 함께 배치하는 방법에 대해 신중하게 생각해야 한다. 이에 대한 정답은 없으며 어려운 점을 해결하기 위한 많은 옵션은 존재한다.

잠깐, 글이 유익했나요?

Donate!