Design Patterns

마이크로서비스(Microservice?) 란?

FreeEnd 2022. 4. 16. 16:21
반응형

이번 블로그는 보편적인 IT지식을 가지고 있지만 시스템 설계구조에 대해서는 그렇치 않은 IT담당자들을 대상으로, 마이크로서비스가 어떤 것인지에 대해 간략하게 설명 하고자 한다.

 

마이크로 서비스 (Microservice)

  마이크로서비스, 혹은 마이크로서비스 아키텍처는 독립적으로 수행되는 소규모의 시스템들이 명확하고 절대적으로 분리된 인터페이스 정의에 의해 긴밀하게 통신하는 아키텍처 기반의 접근, 구현 방식이다.

 

 좀 어렵게 들리겠지만, 간단히 말해 서비스를 작은 단위로 쪼개고, 그 작게 쪼갠 서비스는 독립적으로 수행되며, 독립적으로 수행되는 서비스끼리 정해놓은 규칙으로 인터페이스 하며 하나의 대규모 서비스를 제공한다 라고 이해하면 된다.

 

 

 기존 시스템들은 하나의 시스템 자원을 공유하며 하나의 덩어리안에서 서비스를 제공 하는 모놀리스(Monolith) 기법으로 구현되었다. 예를 들어, 한 서버에서 동일한 프레임워크로, 같은 DATABASE 를 이용해 한꺼번에 서비스를 제공하는 했던 것이다.  그러나 마이크로 서비스는 이와는 반대로, 여러개의 서버에서 각기 다른 프레임워크로, 개별적 DATABASE 를 이용해 독립적으로 서비스를 한다. 

Microservice? (AWS)

 마이크로서비스의 핵심은 독립적인 서비스 수행에 있다. 개별 서비스는 다른 서비스가 없이도 혼자 수행 가능한 완전 독립적인 시스템이여야 한다. 때문에 다른 시스템의 장애등의 부정적 영향이 없고, 배포에서도 자유롭다. 또 인터페이스만 명확하게 정의하면 다양한 기술 스택을 적용 할 수 있다. 게다가 서비스를 작은 단위로 쪼갰기때문에 신규 요건에 대응이 빨리지게 된다. 때문에 CI/CD(지속적통합/지속적 제공) 이 가능하다. 

 

 하지만 작은 단위로 서비스를 분리한것에 대한 단점도 존재 한다. 우선 작은 단위의 서비스로 분리가 되었기때문에 모놀리식서비스 보다 더 많은 서버와 인력, 비용이 필요하고, 각 서비스를 담당하는 팀/인력 끼리의 커뮤니케이션이 느려질 수 있다. 

 

 

모놀리식 아키텍처

  모놀리식 아키텍처 (Monolithic Architecture) 는 마이크로서비스 개념의 반대대는 말로, 전통적 아키텍처를 뜻하는 의미로 생겨난 단어이다. 

 

모놀리식 아키텍처

 기존 모놀리식 아키텍처는 그림과 같이 하나의 모든 구성요소가 거대한 하나의 시스템에 통합되어 있는 형대로 설계, 구현된다. 또 배포, 실행도 한 서비스 내에서 이루어 진다. 말 그대로 하나의 어플리케이션에 모두 통합되어있는 형태이다.

 

 

모놀리식 서비스의 장점

 모놀리식 서비스는 다음과 같은 장점을 갖는다.

 

개발이 쉽고 빠르다.

 모놀리식은 단일 서버와 단일 환경에서 서비스가 개발된다. 단일 개발언어를 사용하기때문에 하나의 코드컨벤션만 유지 하면 되므로, 단순히 코딩만 봤을 경우에 코드의 품질 이 좋아질 수 있다. 

 또, 개별 서비스 영역이 단일 어플리케이션에 존재 하므로, 영역간 데이터가 필요할때 빠르게 참조관계를 만들어 낼 수 있다. 게다가 DATABASE 도 단일로 이루어져 필요한 데이터는 영역간 구분 없이 바로 조회, 사용할 수 있다.

 

배포, 운영하기 쉽다.

 단일 서비스를 구현하기때문에 한꺼번에 모든 영역이 동시에 배포가 가능하다. 전체 영역간에 연관관계가 있는 개발 건일경우 시스템이 나누어져 있으면 각각 시스템별로 배포 시간을 맞춰 동시에 배포해야 하지만, 모놀리식의 경우 단일 시스템만 배포하면되므로, 상대적으로 배포가 쉽다.

 

운영 비용이 적게 든다.

 서비스가 단일 시스템에서 동작 하므로 단일 시스템을 위한 서버, 네트워크, DATABASE 등만 유지하면된다. 마이크로 서비스의 경우 개별 서비스가 나누어져 있고 네트워크를 이용한 인터페이스를 해야 하므로 추가적인 많은 비용이 발생하지만, 단일 시스템에서 모든 영역이 합쳐져 있는 모놀리식은 상대적으로 운영비용이 적을 수 밖에 없다.

 

확장하기 쉽다.

 시스템의 사용량이 늘어 서비스를 확장 해야할 경우, 단일 시스템만 병렬로 추가 투입 (scale-out) 하면 되므로, 별도의 고민과 정성이 필요하지 않다.

 

 

 모놀리식 서비스는 일반적으로 거의 대부분의 시스템이 처음 개발 할때 선택하게 된다. 서비스 규모가 작고, 운영 인력이 작으며, 비용이 충분하지 않을 때 이 모놀리식 서비스 방식의 설계는 불가결하다.

 

 

 모놀리식 서비스의 단점

 하지만 서비스가 점점 커지면서 다음과 같은 단점들이 들어나게 된다.

 

개발이 느리고 어렵다.

 모놀리식서비스는  단일 시스템에 모든 서비스 영역이 모두 포함되어 있다. 때문에 필요한 데이터를 다른 영역에서 쉽게 참조할수 할 수 있는 장점이 있지만, 시간이 지나 참조영역이 많아지면 그만큼 의존성 (Dependency) 가 늘어나게 되여 이해할수 없을 정도로 영역간 코드 참조관계가 뒤섞이게 된다. 이렇게 되면 추가적인 기능을 개발, 수정하기 위해선 참조관계를 모두 다시 파악해야 하고, 그만큼 개발 생산성이 떨어지게 된다. 

  또, 개발을 위한 개발 툴 (IDE) 도 문제다. 단일 서비스가 구현된 거대한 단일 어플리케이션을 운영서버 성능의 반도 안되는 개발자 PC에 올리게 되면 구동 속도는 말할것도 없고 컴파일도 쉽지 않다.

 

배포가 자유롭지 못하다

 요즘은 GIT, SVN 등 다양한 브랜치 전략을 이용할 수 있지만, 이 브랜치 전략에도 한계가 있다. 제일먼저 브랜치 소스 병합 (MERGE) 작업은 두말할것도 없고 단일 어플리케이션에서 구동되는 모놀리식 서비스는 코드의 연관성이 복잡하기 때문에 브랜치 버젼으로도 배포 소스의 안정성을 보장하기 쉽지 않다. 때문에 하나의 수정건이라도 관련 영역은 항상 영향도 테스트를 이루어야 하고, 배포도 정해진 시간에 규칙적으로 배포해야 한다.

 

기술 스택에 한계가 있다.

 하나의 단일 어플리케이션은 당연하게도 하나의 언어, 정해진 DATABASE 만 사용해야 한다. 한번 개발 된 시스템은 몇년, 길게는 십수년 운영해야 하는데, IT업계의 기술은 하루만에도 최신 기술이 쏟아져 나온다. 새로운 기술, 혹은 언어를 도입하고 싶어도 영향범위가 어플리케이션 전반에 있기 때문에 결정부터가 어렵다.

 

경제적으로 서비스를 확장 할수 없다.

 확장하기 쉬운게 모놀리식이였지만, 그 반면에 경제적인 확장은 불가능 하다.

어떤 로직은 많은 CPU 를 사용해야 하고, 어떤 로직은 많은 메모리가 필요할 경우, 작은 단위의 확장은 SCALE-UP 으로 해결 되지만, 서버의 SCALE-UP 한계 상황에서 서버를 SCALE-OUT 해야 할 경우, 불필요하게 동일한 모든 장비 (CPU, SSD, 네트워크 등) 을 구매해 서버를 구성 해야 하기때문에 경제적으로 확장이 쉽지 않다.

Monolithic Scale-out

 

 모놀리식 서비스가 장점도 있고, 단점도 있지만, 사실 전혀 필요없는 설계기법은 아니다. 장점때도 언급 했지만, 소규모 단위의 서비스를 제공하는 입장에서는 단점을 커버할 수 있을 만큼 장점이 도움이 되기때문에 시스템 설계시에 적절히 선택 해야 한다.

 

 

마이크로 서비스 아키텍처

 마이크로 서비스는 이런 모놀리식 아키텍처를 개선하고자 등장했다. 모놀리식 서비스가 서비스 규모가 늘어나면서 갖은 단점들이 나타나게 되면서, 서비스 분리에 대한 필요성이 발생 하게 되었다. 

 

 사실, 마이크로서비스 등장 이전에 SOA (Service Oriented Architecture) 라는 개념이 있었지만 ESB 를 이용한 개별 서비스 제공으로 마이크로서비스는 조금 다르다. SOA 는 서비스를 각 모듈로 분리하고, SOAP 등 의 표준화된 인터페이스를 이용해 재사용성성을 높인 소프트웨어 설계 유형이다. 사실 독립적인 유형이라고는 하나 사용하기 위해서는 제공된 인터페이스 스펙대로 코드를 고정해야 하고, 데이터베이스도 공유하고 있어 서비스 단위는 명확하게 분리되어 있으나 의존성은 해결되지 않았다. 

 

 

 마이크로서비스는 이완 다르게 서비스끼리 완전히 독립된다. 각 시스템 별로 비지니스로직은 물론 Database 까지 분리되어있는 SOA 에서 한발 더 나아간 분리 구조로 이루어져 있다. 각 서비스는 완전한 개별 서비스로 서로의 인터페이스는 오직 각기 정한 인터페이스로 통신한다. 

 각 영역간의 의존성이 낮은 대신 독자적으로 수행 가능한 단위로 업무가 쪼개져 있으므로 운영인력, 팀도 분리가 가능하다. 대신 커뮤니케이션이 어렵다. 하지만만 서비스 분리 단계에서 업무에 대한 의존성도 최대한 분리를 고려 하므로 큰 문제는 되지 않는다.

 

 마이크로 서비스는 모놀리식을 개선하기 위한 방식으로, 모놀리식 서비스와 비교하여 특징을 알아보자.

 

마이크로서비스의 장점

소규모 서비스 : 민첩하게 대응 가능하다.

 모놀리식 서비스는 업무간의 경계가 모호하고, 특정 영역은 다양한 업무를 한꺼번에 이루고 있는 경우가 많다. 때문에 특정 영역에 대한 집중도가 떨어질수 있으며,  업무 분석 범위가 넓기 때문에 많은 시간이 소요 된다.

 마이크로 서비스는 소규모 업무로 나눈 소규모 조직, 업무영역으로 이루어져 있다. 때문에 모놀리식 구조보다 업무에 대한 집중도가 높아 신속한 대응이 가능하다. 또 다른 영역에 관계없이 독립적인 업무가 가능하므로, 개발시간과 일정에서 보다 자유롭다.

 

업무가 서로 분리된다

 

 

소규모 서비스 : 관리하기 용이하다.

 서비스가 작기때문에 개발자가 코드를 이해하기 쉽다. 서비스가 크다면 특정 소스나 비지니스가 어디에 산재되어 있을지 예상하기 어렵고, 찾기도 힘들다. 마이크로서비스는 서비스가 작기때문에 복잡한 로직이 많치 않다. 

 

소규모 서비스 : 서비스 단위 테스트도 쉽다.

 서비스가 작고 대부분이 지정된 인터페이스에 의해 구성되므로, 기능 테스트는 인터페이스 단위의 테스트에 집중하면된다. 또 서비스 자체가 작기도 하고, 인터페이스로 인한 의존성도 적기때문에 인터페이스 스펙이 바뀌지 않는 이상 테스트 양과 범위가 상대적으로 적을 수 밖에 없다.

 

 

서비스끼리 의존도가 낮다

 

낮은 의존도 : 쉽게 배포가 가능 하다.

모놀리식서비스는 하나의 어플리케이션이기 때문에 배포 업무는 항상 연관되어 있을 수 밖에 없다. 그래서 정기 배포일을 만들고, 특정기간 동안 개발을 진행한다.

 정기배포 일을 지키지 않고, 배포건을 미리 묶어 놓았을 경우, 다른 영역에서 긴급 배포해야 하는 일이 발생했을때 미리 묶어놓은 배포버젼을 함께 배포하던지, 롤백 해야 한다. 어플리케이션 소스가 긴밀하기 때문에 특정영역에서 먼저 개발을 했다 하더라도, 해당 소스를 수정해야 하는 다른 영역의 개발기간을 지킬수 밖에 없는 것이다.

 

 그에반해 마이크로 서비스의 경우 영역끼리의 의존도는 인터페이스 밖에 없다. 어플리케이션 자체가 분리되어 있어, 연관성이 있는 인터페이스의 스펙만 지키면 언제 어느 시점에 배포하던지 상관 없이 개별 영역 일정에 맞게 배포하면 된다. 

 

낮은 의존도 : 장애에서 자유롭다.

 시스템이 분리되어 있는것의 가장 큰 장점은 장애에서 자유롭다는 점이다. 특정서비스가 장애났을 경우 해당 시스템만 중단 될뿐, 물리적으로 분리되어 있는 다른 영역으로는 장애가 전파 되지 않는다. 

 

서비스의 확장/개선 : 경제적이고 정확한 시스템 확장이 가능하다.

 기존 모놀리식 서비스는 장비를 확장하기 위해서는 단일 시스템을 그대로 N개로 확장 해야 했다. 덕분에 불필요한 리소스까지 함께 확대 되므로 리소스가 낭비되는 경제적이지 못한 확장밖에 할 수 없었다.

 마이크로 서비스에서는 업무가 이미 쪼개져 있어 특정 서비스만 확장 하면된다.

예를 들어, 상품등록, 주문, 배송에 대한 유입은 그대로인데, FRONT 인입만 늘어나는 상황이라면 FRONT 시스템만 SCALE-OUT 하면 된다. 또 주문영역도 주문영역내에서 주문내역 파일 다운로드 기능에 대한 요청이 늘어나면 해당 기능만 별도 시스템으로 구성해 SCALE-OUT 하면된다. 

Microservice Scale-out

 

 

서비스의 확장/개선 : 신기술 도입

 쉽게 새로운 기술을 적용 할 수 있다. 서비스 규모가 작아진 만큼 특정 영역의 코딩 양이 줄어들며 새로운 언어, 패턴 등에 대한 적용이 상대적으로 더 쉽다. 

 모놀리식 서비스는 다른 영역, 어플리케이션 전체를 수정해야 함으로 쉬운 결정이 아닐 수 있다. 때문에 더 쉽고 빠르게 시스템을 개선 해 나갈 수 있다. 

 

 

마이크로서비스의 단점

업무를 정확하게 분리 하기 어렵다.

 마이크로서비스의 근간은 분리된 서비스로, 각 영역을 어떻게 분리할것인지부터 난관이다. 또 분리된 서비스는 향후 절대적인 분리 기준으로 네트워크 인터페이스를 이용해 통신해야 하기때문에 신중히 분리 해야 한다. 

 마이크로서비스를 업무 영역을 분리하기 위해선 업무를 도메인, 핵심 도메인으로 나누고, 바운디드 컨텍스를 설정하는 DDD (도메인주도 설계) 기법을 주로 활용한다. 

 

분산 시스템 설계가 어렵고, 코딩이 복잡하다.

 개별 서비스가 나누어져 있기때문에 각 서비스간에 데이터를 주고 받으면서 이루어져야할 트랜잭션 관리부터 난관이다. 여러개의 서비스에 동시에 요청하는 프로세스를 수행시에 모든 서비스의 요청이 성공해야 완료할수 있는 프로세스라면, 하나의 서비스가 실패했을때 이미 요청한 서비스의 롤백을 해야 한다. 모놀리식 같은 경우, 같은 트랜잭션 내에서 롤백이 가능하지만, 서비스가 나누어져 있는 마이크로 서비스에서는 보상 트랜잭션 (성공한 서비스를 취소하는 추가적인 요청) 이 필요하다.

 기존 모놀리식 아키텍쳐에 익숙한 개발자는 이런 로직에 대해 익숙해지는데 상당한 시간이 소요될 것이다. 

 

 

서비스 인터페이스시 네트워크 홉(단계) 가 늘어나며 지연 / 장애율이 올라간다.

  모놀리식 서비스는 각 영역간 인터페이스시 네트워크를 거치지 않는다. 그에 반해 마이크로 서비스의 경우 서비스끼리 기본적으로 네트워크를 동한 인터페이스가 이루어 져야 하므로 네트워크를 이용한 요청, 응답시간이 네트워크 단계마다 추가된다.

 서비스 안정성 면에서도 모놀리식보다 떨어질 수 있다. 한 서버의 서비스 정상 서비스 비율이 98 % 라고 가정했을때, 이런 서비스를 두개만 거쳐야 한다고 했을때 0.98 * 0.98 = 약 0.96 로 해당 서비스의 정상 비율은 96%로 떨어진다. 서비스를 거치면 거칠수록 이 비율은 계속 떨어질 수 밖에 없다.

 

여러 서비스에 걸쳐진 프로세스의 경우 영향도 파악이 힘들다

 서비스 영향도 파악도 문제다. 모놀리식의 경우 하나의 어플리케이션 내에서 모든 프로세스가 단일 로직으로 이루어져있을 가능성이 크지만, 마이크로 서비스는 각 서비스를 개별 호출 해야 하기도 하고, 각 서비스에서 제공하는 API 는 어떤 다른 서비스가 어떤 상황에서 사용되는지 관계성을 파악 하기 힘들기 때문이다.

 그래서 한번 정해진 인터페이스는 변경하기 어렵고 오랫동안 동일한 스펙을 유지 해야 한다.

 

참고 : https://aws.amazon.com/ko/microservices/

 

마이크로서비스란 무엇입니까? | AWS

마이크로서비스의 경우 각 서비스가 지원하는 애플리케이션 기능의 수요를 충족하도록 해당 서비스를 독립적으로 확장할 수 있습니다. 따라서 팀은 필요한 인프라의 규모를 적절히 조절하고,

aws.amazon.com

참고 : https://www.redhat.com/ko/topics/microservices/what-are-microservices

 

마이크로서비스란?

마이크로서비스란 애플리케이션을 구축하기 위한 아키텍처 기반의 접근 방식으로 애플리케이션의 각 요소가 독립적으로 작동합니다.

www.redhat.com

참고 : https://www.ibm.com/kr-ko/cloud/learn/microservices

 

2_마이크로서비스.pptx
0.14MB

반응형