마이크로서비스 개념이 발전하기 전, 대부분의 웹 기반 애플리케이션은 모놀리식 아키텍처 형태로 개발되었다. 여기에서 애플리케이션은 배포 가능한 단일 소프트웨어 산출물로 전달된다. 문제는 모놀리식 애플리케이션이 크고 복잡해지면서 애플리케이션을 담당하는 각 팀의 의사소통과 조정비용이 증가한다는 것이다. 또한, 각 팀에서 변경이 있을 때마다 앱 전체를 다시 빌드하고 테스트해서 배포해야 한다.
마이크로서비스 개념은 2014년경 소프트웨어 개발 커뮤니티에서 인식되기 시작했고, 대형 모놀리식 애플리케이션을 기술 및 조직적으로 확장하려고 할 때 생기는 많은 난제에 대한 직접적인 대안이었다.
마이크로서비스 아키텍처의 특징은 다음과 같다.
1. 애플리케이션 로직을 각자 책임이 명확한 작은 컴포넌트들로 분해하고 이들을 조합해서 솔루션을 제공한다.
2. 각 컴포넌트는 작은 책임영역을 담당하고 완전히 상호 독립적으로 배포된다. 마이크로서비스는 비즈니스 영역의 한 부분에서만 책임을 담당한다. 그리고, 여러 애플리케이션에서 재사용할 수 있어야한다.
3. 마이크로서비스는 몇 가지 기본 원칙에 기반을 두며, 서비스 소비자와 서비스 제공자 사이의 데이터 교환을 위해 HTTP와 JSON 같은 경량 프로토콜을 사용한다.
4. 애플리케이션은 항상 기술 중립적 프로토콜을 사용해 통신하므로 서비스 구현기술과는 무관하다.
5. 작고 독립적미여 분산된 마이크로 서비스를 사용해 조직은 명확히 정의된 책임 영역을 담당하는 소규모 팀을 보유할 수 있다. 이 팀들은 애플리케이션 출시처럼 하나의 목표를 향해 일하지만, 자기가 개발하는 서비스만 책임진다.
스프링 부트는 일반적인 REST 마이크로서비스의 작업을 추상화 하고 개발자가 서비스 비즈니스 로직에 집중할 수 있게 한다.
@SpringBootApplication
@RestController
@RequestMapping(value="hello")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@GetMapping("/{firstName}/{lastName}")
public String hello(
@PathVariable("firstName") String firstName,
@PathVariable("lastName") String lastName
) {
return String.format(
"{\"message\":\"Hello %s %s\"}", firstName, lastName);
}
}
고객은 조직의 모든 부분이 자신을 인식하기를 기대한다. 단 하나의 DB와 통신하고 다른 앱과 통신하지 않는 단절된 앱은 더이상 표준이 아니다.
고객은 더 이상 소프트웨어 패키지를 연단위로 릴리즈하거나 버전을 올리기를 기대하지 않는다. 대신 제품 기능이 따로 번들링되어 전체 제품의 릴리즈를 기다리지 않고 새로운 기능이 몇 주나 며칠 안에 빨리 릴리즈 되기를 기대한다.
글로벌 앱은 처리해야할 트랜잭션 양과 유입될 시점을 예측하기 매우 어렵다. 앱은 여러 서버로 신속히 확장한 후 확장이 필요 없다면 다시 축소해야 한다.
앱의 한 부분에서 에러나 문제가 있어도 전체가 다운되어서는 안된다.
새로운 기능을 신속하게 제공하도록 분리된 서비스를 구성하고 재배치할 수 있다.
실패는 앱의 작은 부분에 국한되어 전체 장애로 확대되기 전에 억제된다. 또 회복불능 에러가 발생했을 때도 원활하게 기능이 저하될 수 있다.
분리된 서비스를 여러 서버에서 수평적으로 쉽게 분산할 수 있어 기능 및 서비스를 적절히 확장할 수 있다.
클라우드 기반 컴퓨팅에는 다음 세 가지 기본 모델이 존재한다.
이 개념을 더 잘 이해하기 위해 식사를 준비하는 일상적인 작업을 여러 클라우드 모델에 매핑해보자. 식사때 다음 네가지를 선택할 수 있다.
1. 집에서 직접 해먹는다.
2. 식료품점에서 냉동 음식을 사 먹는다.
3. 배달음식을 먹는다.
4. 차를 타고 식당에 가서 먹는다.
선택사항별 차리는 음식을 요리할 책임자와 요리 장소다.
각 모델에서 요점은 통제에 관한것이다. 즉 누가 인프라를 유지보수하고 애플리케이션 구축을 위해 어떤 기술을 사용할지 하는 점이다.
마이크로서비스 기반 아키텍처의 핵심 개념은 각 서비스를 독립된 개별 산출물로 패키징하고 배포한다는 것이다. 서비스 인스턴스를 신속하게 시작할 수 있고 서비스 인스턴스는 서로 차이가 없어야 한다. 마이크로서비스를 작성하는 개발자는 서비스를 다음 중 어디에 배포해야할 지 조만간 결정해야 할 것이다.
사용하는 조직이 거의 없다. 용량을 빠르게 늘릴 수 없고 여러 물리적 서버로 마이크로서비스를 수평확장하는 데 상당한 비용이 든다.
마이크로서비스의 주요 이점 중 하나는 확장하고 실패 이벤트를 받을 때 신속하게 인스턴스를 시작하고 종료할 수 있다는 것이다. 가상 머신은 주요 클라우드 공급자의 마음이자 정신이다. 마이크로서비스를 가상 머신 이미지에 패키징 할 서비스의 여러 인스턴스를 신속하게 IaaS 형 사설 및 공용 클라우드에 배포하고 시작할 수 있다.
가상 컨테이너는 가상 머신 이미지 기반의 마이크로서비스 배포를 자연스럽게 확장한것이다. 서비스를 완전한 가상머신에 배포하는 대신 많은 개발자가 도커 컨테이너로 자기 서비스를 클라두으에 배포한다. 가상 컨테이너는 가상 머신 안에서 실행된다. 가상 컨테이너를 사용하면 하나의 가상 머신을 같은 가상 머신 이미지를 공유하는 완전 자립형 프로세스로 분리할 수 있다.
마이크로서비스에서 사용되는 일반적인 배포 토폴로지
개별 마이크로서비스 구축에 관련된 개념은 이해하기 쉽지만 견고한 마이크로서비스는 애플리케이션을 실행하고 지원하는 것은 서비스 코드를 작성하는것 이상이 필요하다.
이러한 질문에 답하기 위해 패턴 기반의 접근 방법을 사용한다. 패턴에 기반을 둔 방법은 서로 다른 기술 구현 방식에 사용할 수 있는 일반적인 설계를 제시한다.
마이크로서비스 라우팅 패턴을 마이크로서비스를 사용하려는 클라이언트 애플리케이션 서비스의 위치를 발견하고 라우팅하는 방법을 다른다. 클라우드 기반 애플리케이션에서는 수백 개의 마이크로서비스 인스턴스가 실행중일 수 있다. 서비스의 물리적 IP주소를 추상화하고 서비스 호출에 대한 단일 진입점을 만들어야 모든 서비스 호출에 대한 일관된 보안과 콘텐츠 정책을 보장할 수 있다.
마이크고서비스 아키텍처는 고도로 분산되어 있어서 1개의 서비스 문제가 서비스 소비자에게 연쇄적으로 발생하지 않도록 방지하는데 매우 민갑해져야 한다. 이를 위해 네 가지 클라이언트 회복성 패턴을 다룰 것이다.
마이크로서비스 아키텍처의 장점은 모놀리식 애플리케이션이 작은 기능 단위로 분해되어 독립적으로 배포된다는 것이다. 마이크로서비스의 단점은 앱과 서비스 안에서 어떤 일이 일어나고 있는지 디버깅과 추적이 훨씬 더 어렵다는 것이다. 이러한 이유로 세 가지 핵심 로깅 및 추적 패턴을 살펴본다.