1) X축 확장 :: 다중 인스턴스에 고루 요청 분산
일반적인 모놀리식 애플리케이션 확장 수단, 부하 분산기 뒷면에 애플리케이션 인스턴스 N개를 띄워 놓고 부하 분산기는 들어온 요청을 인스턴스에 고루 분배합니다. 애플리케이션 능력과 가용성을 개선할 수 있습니다. 

2) Y축 확장 :: 요청 속성별 라우팅
인스턴스 앞면에 위치한 라우터는 요청의 속성에 알맞은 인스턴스로 요청을 라우팅 합니다. 애플리케이션을 확장해서 증가하는 트랜잭션 및 데이터 볼륨을 처리하기 좋습니다. 

3) Z축 확장 :: 기능에 따라 애플리케이션을 서비스로 분해
위 과정을 거치면 X축/Z축 확장을 하면 애플리케이션 능력과 가용성 개선, 애플리케이션이 복잡해지면 문제는 해결되지 않는다. 모놀리식 애플리케이션을 여러 서비스로 쪼갠다. 

Y축 확장, Z축 확장

마이크로 아키텍처는 하나의 애플리케이션을 여러 서비스로 기능을 분해하는 아키텍처 입니다. 
마이크로서비스는 서로 느슨하게 결합되어 있고 오직 API 통해서만 통신 느슨하게 결합된 서비스는 각각 자체 DB를 갖고 있습니다. 각자 디비를 따로 가지고 있으면 서비스 개발자와 일일이 협의하지 않고 개발자 본인이 담당한 서비스 스키마를 변경할 수 있습니다. 

*모놀리식 애플리케이션 : 프로그래밍 언어 구성체(자바 패키지) 그리고 빌드 아티팩트(자바 JAR 파일) 조합한 단위로 모듈을 정의합니다.

마이크로서비스는 독립적으로 X축(복제)/Z축(파티셔닝) 확장을 진행할 수 있습니다. 서비스마다 상이한 리소스 요건에 맞춰서 하드웨어에 배포할 수 있습니다. 또한, 신기술 시험하고 도입하기 쉽습니다. 단, 단점이 존재하면 최적화된 서비스 찾기가 쉽지 않은점, 분산 시스템이 복잡하기 때문에 개발, 테스트, 배포가 어렵습니다. 그리고, 마이크로서비스 아키텍처 도입 시점을 결정하기 어렵습니다. 

마이크로서비스 아키텍처는 테스트 속도가 느리고 수작업이 동반되는 단점이다. 개발 도중 실행 가능한 자동화 테스트를 작성하는것이 좋습니다. 자동화 테스트를 하는 목적은 SUT(System Under Test) 동작을 확인합니다. SUT는 작게는 클래스부터 크게는 전체 애플리케이션까지 다양하게 적용됩니다. 자동화 테스트는 JUnit 등의 테스트 프레임워크로 작성합니다. 

SUT은 대부분 디펜던시를 갖고 있습니다. 디펜던시 때문에 테스트가 복잡하고 느려집니다. 해결 방법은 디펜던시를 테스트 더블(대역 테스트) 대체하는것입니다. 테스트 더블에는 Stub, Mock 두개가 있습니다. 
1. Stub : 값을 반환하는 테스트 더블
2. Mock : SUT가 정확하게 디펜던시를 호출했는지 확인하는 테스트 더블
( Mock은 Stub의 일종입니다. )

IPC(프로세스간 통신)은 모놀리식보다 마이크로서비스에 많은 비중을 둡니다. 마이크로서비스 기반의 애플리케이션은 팀별로 각자 맡은 서비스를 개발하고 꾸준히 API를 발전하는 분산 시스템입니다. REST, gRPC등의 프로토콜을 이용해서 요청/응답하는 서비스도 있고, 요청/비동기 응답 또는 비동기 메시징을 으용해서 발행/구독 스타일로 통신하는 경우가 존재합니다. 

REST 클라이언트 ⇢ 서비스 : API게이트웨이는 서비스로 요청을 라우팅하고 API를 조합합니다.
도메인 이벤트 컨슈머 ⇢ 구독기 : 주문 이력 서비스는 주문 서비스에서 발행된 이벤트를 소비합니다.
커맨드 메시지 요청자 ⇢ 응답자 : 주문 서비스는 여러 서비스에 커맨드 메시지를 전송하고 응답을 소비합니다.  

통합테스트 작성시 서비스는 대부분 다른 서비스와 상호 작용합니다. 주문 서비스의 REST API는 API 게이트웨이가 소비되고, 도메인 이벤트는 주문 이력 서비스등 다른 서비스가 소비됩니다. 

통합테스트를 통해 서비스가 클라이언트, 디펜던시와 통신 가능하다는 사실은 확인할 수 있지만 서비스를 통째로 테스트하지 않고 통신 기능이 구현된 어댑터 클래스를 따로 테스트를 수행합니다. 

마이크로서비스 섀시 프레임워크는 1)외부화 구성, 2)헬스 체크, 3)애플리케이션 지표, 4)서비스 디스커버리, 5)회로 차단기, 6)분산 추적을 수행합니다. 애플리케이션단에서 기능 구성할때 스프링 부트를 이용해서 외부화 구성 기능을 수행하고 스프링 클라우드를 사용해서 회로차단기를 구성합니다. 서비스를 개발하는 언어/플랫폼 조합에 따라서 마이크로서비스 섀시가 하나씩 필요하기 때문에(Spring으로 작성된것에는 유용하지만 Node.js 기반 서비스는 아무 소용이 없습니다.) 마이크로서비스 섀시의 네트워크 관련 기능은 서비스 메쉬라는 서비스 외부에서 실행되는 인프라 계층에서 처리됩니다. 

패턴 : 서비스 메시는 회로 차단기, 분산 추적, 서비스 디스커버리, 부하 분산, 룰 기반 트래픽 라우팅 등 여러 관심사가 구현된 네트워킹 계층을 통해 서비스를 드나드는 모든 네트워크 트래픽을 라우팅합니다.

공통 기능 일부를 서비스 외부에 위치한 서비스 메시로 구현합니다. 서비스 메시는 서비스와 서비스간의 소통을 조정하는 역할을 수행하는 인프라입니다. 서비스로 들어오는 네트워크 트래픽은 모두 회로 차단기, 분산 추적, 서비스 디스커버리, 부하 분산, 룰 기반 트래픽 라우팅 등 여러 관심사가 구현된 서비스 메시를 통과하게 됩니다. 추가적으로 서비스 메시는 TLS기반의 IPC로 서비스간 IPC를 보안합니다. 따라서, 특정 기능을 서비스에 직접 구현할 필요가 없습니다.

마이크로서비스 섀시로 외부화 구성, 헬스 체크 등 애플리케이션 코드와 결합된 관심사만 구현하면 되기 떄문에 훨씬 단순합니다. 
여기서 마이크로서비스 섀시는 분산 추적 정보를 전파해서 분산 추적을 할 수 있도록 지원해야 합니다. 

-. 서비스 메시를 구현한 제품 : 이스티오(Istio), 링커드(Linkerd), 콘듀이트(Conduit). 가장 성숙한 제품은 링커드입니다. 

서비스 메시는 개발자가 여러 횡단 관심사를 신경 쓸 필요가 없습니다. 트래픽을 라우팅하는 능력도 있어서 배포와 릴리즈를 분리할 수 있습니다. 새 버전의 서비스를 프로덕션에 배포하고 내부 테스터 등 특정 사용자에게 릴리즈하는 일을 수행합니다. 

*ref : 마이크로서비스 패턴