이 글은 인프런 Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA) 강의를 듣고 쓴 글입니다.
Software Architecture의 진화 - Cloud Native Architecture
IT System은 초기에 하드웨어 중심의 깨지기 쉬운 (Fragile) 특징을 가지고 있었다.
이후, 분산을 거쳐 안정된 (Robust) 특징을 가지다가, 2010년대부터 탄력적이고 깨지지 않는 (Resilieent/Anti-Fragile) 특징을 지닌 Cloud Native Architecture로 진화했다.
여기서 Antifragile 이란 다음의 특징을 갖고 있다.
- Auto scailing : 이벤트 등으로 수요가 많아지면 서버를 늘리고 비수기에는 줄인다
- Microservices : 큰 서비스를 작은 서비스로 쪼개서 관리한다. Netflix가 대표적인 선두주자이다.
- Chaos engineering : 여러 불확실성이 있어도 안정적인 서비스를 구축한다.
- Continuous deployments : CI/CD (Continuous Integration / Continuous Deployment) 즉, 계속적인 통합 / 배포를 통해 자동으로 과정이 이어지도록 파이프라인을 구축한다.
Cloud Native Architecture 는 다음의 특징을 가지고 있다.
- 확장 가능 : 시스템의 수평적 확장, 즉 Scale out ( 하드웨어의 개수를 늘리는 것)에 유연하다. (다른 시스템 확장에는 Scale up - 하드웨어의 사양을 높이는 것이 있다)
- 탄력적 : 각 서비스 등의 종속성을 최소로 하고, CI/CD를 구축해 환경 변화의 대응시간을 단축한다. 또 서비스의 추가와 삭제를 discovery service 라는 곳에 등록하고 삭제하면서 자동으로 감지하고 처리한다.
- 장애 격리 : 종속성이 최소이므로 특정 서비스에 오류가 발생해도 다른 서비스에 영향을 주지 않는다.
Cloud Native Application
다음 4개의 키워드가 앞으로 굉장히 중요할 것이다.
Microservices, CI/CD, DevOps, Containers
CI/CD
지속적인 통합을 의미하는 CI (Continuous Integration) 는 여러 개발자의 코드를 통합해주고 빌드, 테스트해준다. Jenkins, Travis CI 등이 있다.
지속적인 배포를 의미하는 CD는 Continuous Delivery와 Continuous Deployment 두 가지를 포함한다. 운영자나 관리자의 개입이 필요하도록 수동으로 반영되는 것을 Continuous Delivery, 반대로 필요 없는 것을 Continuous Deployment라 한다.
이렇게 배포를 할 때 기존 시스템과 같이 운영하면서 이질감을 최소로 하기 위해 전략을 사용한다.
- 카나리 배포 : 소규모 사용자 그룹에 변경 사항을 처음으로 릴리스하는 배포 전략. 광산에서 미리 위험을 알아채기 위한 새인 Canary 에 어원을 두고 있다.
- 블루그린 배포 : 구 버전을 블루, 신 버전을 그린이라 한다. 블루와 그린을 동시에 구성해둔 상태로 배포 시점에 로드 밸런서가 트래픽을 블루에서 그린으로 일제히 전환시킨다.
DevOps
Development와 Operation 즉, 개발과 운영의 통합이다. 시스템은 요구사항의 변경, 에러 등 수많은 변경이 자주 일어난다.
이럴 때 미리 구축해둔 파이프라인으로 바로바로 반영되도록 해야 한다.
Container 가상화
Cloud Native Architecture의 핵심이다. 로컬에서 하던 것들을 Cloud로 옮길 수 있게 했다.
전통적인 배포와 달리 Virtualized Deployment에서는 Host OS위에 Hypervisor를 놓고, 그 위에 각자의 OS를 가진 가상 머신을 통해 배포를 한다. 하지만 이 방식은 Host OS에 부담을 가게 한다.
따라서 Container Deployment에서는 공통적인 라이브러리나 리소스를 공유하고 그 위에 가볍고 빠르게 운영할 Container를 두어 운영해서 단점을 보완한다.
12 Factors
12-Factor는 Heroku 플랫폼을 통해 방대한 앱의 개발, 운영, 확장 등을 관찰한 많은 사람들이 고안해낸 Cloud Native application 개발 방법론
- Base Code : 각 microservice의 단일 코드 베이스
- Dependency Isolation(독립성) :각 서비스는 자체 종속성을 갖고 있어 전체 서비스에 영향을 주지 않는다.
- Configurations : 코드 외부에서 구성관리도구를 통해 작업들을 제어
- Linkable Backing Services(서비스 지원) : 보조 서비스 (캐시, 데이터베이스 등)을 이용해 각 서비스의 기능을 지원
- Stages of Creation (Build, Release and Run) : 빌드, 릴리즈, 실행환경 3개는 완벽히 분리 되어서 각각 id를 가지고 롤백도 가능해야 한다.
- Stateless Processes (무상태 프로세스) : 각 마이크로 서비스들은 다른 서비스와 분리된 상태로 운영
- Port Binding (포트 바인딩) : 각 마이크로 서비스들은 자체 포트를 가지고 그에 맞는 기능을 가진다
- Concurrency (동시성) : 하나의 서비스가 여러 인스턴스에서 동시에 실행되며, 부하를 분산시킨다.
- Disposability : 인스턴스는 쉽게 삭제, 확장, 종료가 가능해야 한다. 도커 등을 사용하면 쉽다.
- Development & Production Parity : 개발/프로덕션 단계는 각각 분리되어서 진행되어야 한다
- Logs : 로그는 어플리케이션과 상관없이 따로 처리 가능해야 한다
- Admin Processes for Evectual Processes : 어떻게 진행되는지 파악하기 위해 적절한 관리도구가 필요
현재에 와서 3가지가 더해졌다.
- API first : 먼저 API 형태로 개발되어야 한다.
- Telemetry : 모든 지표는 수치화/시각화되어서 관리되어야 한다.
- Authentication and Authorization : 인증/인가는 필수
Monolithic vs MSA
Monolith(모놀리스) 는 하나의 커다란 소프트웨어 안에서 모든 것들이 있다.
모든 업무 로직이 하나의 어플리케이션 형태로 패키지되어 서비스 되고, 일부 기능만 수정해도 전체 애플리케이션이 빌드,배포 되어야 한다.
반면 MSA는 다음과 같이 다음과 같이 정의할 수 있다.
Small autonomous services that work together -Sam Newman
함께 동작하는 작은 규모의 서비스들
Monolith vs Front&Back vs MSA
Monolith는 하나의 팀에서 모든 서비스를 제공한다.
Frontend와 Backend로 나누어진 형태는, 현재도 굉장히 많이 사용하고 있는 MSA와 Monolith 형태의 중간 정도이다. Frontend와 Backend가 독립적으로 팀을 나누어 서비스하고, 서로가 HTTP 등으로 통신하며 동작한다.
MSA는 모든 서비스가 따로 마이크로 서비스로 나누어진 형태로, 각 서비스가 서로에게 종속되지 않고 독립적으로 서비스된다. 특히, 최근에는 스마트워치, 태블릿, 웹 등 다양한 디바이스를 통해 서비스를 제공해야 하므로 이런 것들은 Frontend에 맡기도 서비스 로직과 필요한 기능들은 그 밑에서 따로 동작한다.
Microservice
특징
- Challenges : 기존 서비스에서 많은 것을 바꿔야 한다.
- Small Well Chosen Deployable Units : 잘 알려진 작은 단위의 서비스들로 배포된다.
- Bounded Context
- RESTful : 각 서비스들은 RESTful한 HTTP 로 통신하는 것이 권장된다.
- Configuration Management : 환경설정 정보는 따로 관리한다. 예를 들어 IP 주소 등을 코드 안에 하드 코딩하지 않고 따로 관리해 동적으로 수정할 수 있게 한다.
- Cloud Enabled
- Dynamic Scale Up And Scale Down : 서비스마다 인스턴스를 얼마나 쓸 것인지 동적으로 관리한다.
- CI/CD
- Visibility : 각 서비스들은 관리하기 쉽게 시각화할 수 있어야 한다.
그렇다고 모든 서비스들을 microservice로 바꾸는 것이 좋은 것은 아니다. 너무 많은 변화와 독립적인 사이클, 스케일 등이 필요하기 때문에 잘 판단해서 사용해야 한다.
SOA vs MSA
SOA 는 Service Oriented Architecture의 약자로, 서비스의 재사용을 통한 비용 절감을 지향하는 구조이다. 여기서 서비스들은 EBS 라는 서비스 채널에 올라와 서비스를 공유하고 재사용한다.
반면 MSA는 서비스를 공유하지 않고 독립적으로 실행하며 RESTful하게 통신한다. 서비스간에 결합도를 낮추어 변화에 능동적으로 대응하는 데 지향점을 둔다.
그럼 이 RESTful 한 것을 좀 더 알아보자.
RESTful Web Service
LEVEL0에선 간단하게 리소스만 매핑하고, LEVEL1에선 목적에 맞게 uri를 설계하지만 HTTP method가 없다. LEVEL2에 와서야 HTTP 메소드를 사용한다.
LEVEL3는 HATEOAS 라는 것을 함께 사용한다. 이것은 응답과 함께 그 때 뭘 할 수 있는지, 즉 상태 전이를 가능하도록 하는 것이다. RESTful과 HATEOAS의 더 자세한 내용은 다음 게시글을 참고하자.
또한, HATEOAS를 무조건 사용하는 게 좋은가에 대한 것은 다음 게시글을 참고하자.
https://soobindeveloper8.tistory.com/646
좋은 RESTful API 설계를 위해선 몇 가지 유념할 것이 있다.
- 먼저 사용자가 (실제 소비자가 아니라 API 사용자) endpoint만 보고도 알 수 있게 설계를 해야 한다.
- 또한 /user 라는 설계보다는 /users와 같이 복수 형태가 더 적절하다.
- API Gateway 를 통해 일반적인 진입점을 만드는 것도 중요하다.
- 각 응답에 적절한 상태 코드를 보내는 것도 중요한데, 예를 들어 /users/10 을 요청했는데 실제 그러한 데이터가 없다면 응답에 어떤 상태 코드를 반환해야 할까? 500이라 생각하기 쉽지만, 서버에서 오류가 난 게 아니기 때문에 400번대 코드를 반환하거나, 혹은 이것도 틀리지 않는 요청이라고 생각해 200번대 코드를 반환하는 게 적절하다.
Microservices Architecgtur Structures
지금까지 공부했던 것들을 위 사진에서 한 눈에 볼 수 있다. 이 강의가 끝난 후 이 그림에 있는 모든 요소의 구성과 흐름을 설명할 수 있는 게 목표일 것이다.
클라이언트와 다른 서비스가 Gateway를 통해 서비스에 접근하고 Router를 통해 Discovery에 등록된 것들을 탐색해 어떤 가상 컨테이너로 갈지 Load Balaner로 이동한다. 각 컨테이터는 각자의 환경과 프레임워크들을 독자적으로 가지고 있고, 인스턴스도 여러 개 가질 것이다. Backing Service라는 마이크로 서비스를 지원하는 저장장치등을 사용하고, 시각화 등을 해서 모니터하고 진단하는 Telemetry도 있다. 자동으로 빌드하고 관리하는 CI/CD 기능도 필요하고, 이는 다른 데브옵스 운영자 등이 접근할 수 있어야 한다.
이 중 Service Mesh라고 보이는 곳은 MSA의 내부 통신을 도와주는 가상의 네트워크 계층이다. 프록시, 인증, 암호화, 로드 밸런싱 등을 하며 마이크로 서비스가 효율적이고 간편하게 자동으로 작동되도록 도와준다.
정리해보면 다음의 기술을 공부할 것이다.
- Gateway : 서비스로의 진입을 관리
- Service Mesh : 직전에 언급했던 MSA의 내부 통신을 도와주는 계층
- Runtime : 서비스의 운영환경을 관리
- Frameworks : 서비스의 틀을 잡아주는 기술
- Backing Services : 각 서비스들을 지원해주는 저장장치 등
- Automation : 빌드 등을 자동으로 도와주는 기술
- Telemetry : 서비스를 진단하고 모니터링
Spring Cloud
Spring에서 환경설정 관리, 라우팅, 프록시 등에 빠르게 접근할 수 있도록 지원한다
이는 스프링부트의 버전에 따라 호환이 안되는 경우도 있으므로 주의해야 한다.
여기서 사용할 기술들은 다음과 같다.
- Centralized configuration management - 환경설정 관리
- Spring Cloud Config Server
- Location transparency - 위치 정보 확인, 검색 등
- Naming Server (Eureka)
- Load Distribution (Load Balancing)
- Spring Cloud Gateway
- Easier REST Clients
- FeignClient
- Visibility and monitoring
- Zipkin Distributed Tracing
- Netflix API gateway
- Fault Tolerance
- Hystrix
'[MSA] Spring Cloud로 개발하는 마이크로서비스 애플리케이션' 카테고리의 다른 글
섹션 5 : Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA) (0) | 2023.07.28 |
---|---|
섹션 4 : Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA) (0) | 2023.07.28 |
섹션 3 : Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA) (0) | 2023.07.21 |
섹션 2 : Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA) (2) | 2023.07.21 |
섹션 1 : Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA) (0) | 2023.07.20 |