• 검색 결과가 없습니다.

표준프레임워크 MSA 적용 개발 가이드 Version 1.2.0

N/A
N/A
Protected

Academic year: 2022

Share "표준프레임워크 MSA 적용 개발 가이드 Version 1.2.0"

Copied!
110
0
0

로드 중.... (전체 텍스트 보기)

전체 글

(1)

표준프레임워크

MSA 적용 개발 가이드

Version 1.2.0

(2)

Index

1. 개요 ... 4

1.1 배경 ... 4

1.2 가이드의목적과구성 ... 4

2. 마이크로 서비스 아키텍처 (MSA) ... 5

2.1 MSA정의 ... 5

2.2 MSA목적 ... 6

2.3 12-FACTOR APP 방법론 ... 7

2.4 SERVICE MESH ... 9

2.4.1 Service Mesh의 주요 기능 ... 9

2.4.2 Service Mesh 적용 방안 ... 10

2.4.3 Spring Cloud를 활용한 MSA 구축 가이드 ... 11

2.4.4 Spring Cloud와 Kubernetes의 기술 요소 매핑 ... 11

2.5 MSA적용시고려사항... 14

3. SPRING CLOUD기반 마이크로서비스 이해 ... 15

3.1 배경 ... 15

3.2 SPRING BOOT ... 15

3.2.1 Spring Boot Starters ... 17

3.3 SPRING CLOUD ... 19

3.3.1 Spring Cloud 컴포넌트 ... 20

4. SPRING CLOUD 기반 마이크로 서비스 활용 ... 22

4.1 SPRING BOOT을활용한MSA애플리케이션제작 ... 22

4.1.1 Catalogs 서비스 ... 23

4.1.2 Customers 서비스 ... 30

4.1.3 Catalogs & Customers 서비스 연동 및 테스트 ... 36

4.2 SPRING CLOUD의컴포넌트활용 ... 37

4.2.1 Circuit Breaker – Hystrix ... 38

4.2.2 Client Load Balancer – Ribbon ... 40

4.2.3 Service Registry – Eureka ... 42

4.2.4 API Gateway – Zuul ... 50

4.2.5 Config 서버 ... 55

4.2.6 Polyglot Support – Sidecar ... 73

4.2.7 Centralized Logging – ELK (Elastic Search, Logstash, Kibana) ... 79

4.2.8 Centralized Metrics – Prometheus, Grafana ... 86

4.2.9 Distributed Tracing – Sleuth, Zipkin ... 93

5. 마이크로 서비스 배포 ... 97

5.1 컨테이너 ... 97

5.2 도커(DOCKER)의개념과구성요소 ... 98

5.2.1 도커 엔진 ... 98

(3)

5.2.2 도커 아키텍처 ... 99

5.2.3 도커 설치 ... 101

5.3 SPRING BOOT 애플리케이션도커이미지변환 ... 101

5.3.1 도커라이징 ... 101

5.3.2 Dockerfile ... 101

5.3.3 도커 이미지 변환 ... 104

5.4 클라우드컨테이너플랫폼으로의배포 ... 108

5.4.1 Cloud Foundry ... 108

5.4.2 Kubernetes ... 110

(4)

1. 개요

1.1 배경

전자정부 표준프레임워크는 공공사업에 적용되는 개발프레임워크의 표준 정립으로 응용 소프트웨어의 표준화, 품질 및 재사용성 향상을 위해 꾸준히 발전해 왔다. 또한 전자정부 서비스는 민첩성과 유연성을 장점으로 하는 클라우드 플랫폼에서 개발, 실행, 운영, 관리될 수 있도록 발전해 가고 있으며, 이러한 클라우드의 분산환경을 완벽히 지원하는 차세대 프레임워크로의 도약을 위해 노력해왔다.

이에 전자정부 표준프레임워크는 웹서비스를 개발하는 공통기반으로서의 사용자관점을 유지하면서도, 전자정부 서비스를 클라우드 기반에서 개발, 배포, 그리고 안정적이고 탄력적으로 운영할 수 있도록 새로운 버전 4.0(실행환경)을 출시하게 되었다.

표준프레임워크 4.0(실행환경)은 기존 핵심기능은 유지하면서, 엔터프라이즈급 자바 기반의 REST 지향 마이크로서비스 프레임워크를 제공하고 있으며, 스프링부트의 가벼운 구조로 클라우드 환경에 적용하기 적합하다. 하지만, 아무리 뛰어난 개발자라 할찌라도 단시간에 이를 배우고, 활용하여 프로젝트를 완료하기엔 무리가 있다. 이에 전자정부 표준프레임워크를 클라우드 플랫폼에 적용하는 프로젝트에서 탄력적이고 분산된

방식으로 동작하는 클라우드 네이티브 애플리케이션을 쉽게 이해하고 개발할 수 있도록 개발 가이드를 작성하게 되었다.

1.2 가이드의 목적과 구성

본 가이드는 전자정부 클라우드 플랫폼 또는 개방형 클라우드 플랫폼 등의 클라우드 환경에서 표준프레임워크 4.0 을 활용하여 클라우드 네이티브 애플리케이션을 개발할 때 참조하도록 작성되었다.

클라우드 네이티브 애플리케이션을 개발하기 위해서는 DevOps, CI(Continuous Integration)/CD(Continuous Delivery), Container 등 고려할 것이 많지만 본 가이드에서는 탄력성을 높이고 스케일링 용이성을 제공하는 마이크로서비스 개발에 집중할 것이다.

마이크로서비스는 작게 나누어진 서비스와 인스턴스 수만큼 관리 대상이 급격히 증가할 수 있으며, 클라우드 분산 환경에서 서비스 간 복잡한 연결 구조로 인해 장애 추적이 어렵고, 장애 전파 현상이 나타날 수 있다. 이러한 문제점을 해결하기 위해

마이크로서비스 간 직접 통신하지 않도록 Service Discovery, Service Routing, Failure Recovery, Load Balancing 등의 비즈니스 로직과 분리된 네트워크 통신 인브라인

서비스 메쉬(Service Mesh)를 도입하여야 하는데, 이는 컨테이너 종류에 따라

기술스택이 다르다. 이에 본 가이드에서는 어느 클라우드 플랫폼에도 원활히 작동하는 Spring Cloud 를 사용하여 설명하였고, 이를 대체할 Service Mesh 는 MSA 관심사별로 요소기술을 매핑 하였다.

본 가이드는 차세대 전자정부서비스 실현 및 변화방향에 맞추어 지속적으로 업그레이드해 나갈 것이다.

(5)

2. 마이크로 서비스 아키텍처 (MSA)

2.1 MSA 정의

마이크로서비스를 위키백과에서는 아래와 같이 정의하였다.

“마이크로서비스(microservice)는 애플리케이션을 느슨히 결합된 서비스의 모임으로 구조화하는 서비스 지향 아키텍처(SOA) 스타일의 일종인 소프트웨어 개발 기법이다.

마이크로서비스 아키텍처에서 서비스들은 섬세(fine-grained)하고 프로토콜은 가벼운 편이다. 애플리케이션을 더 조그마하나 여러 서비스로 분해할 때의 장점은 모듈성을 개선시키고 애플리케이션의 이해, 개발, 테스트를 더 쉽게 해주고

애플리케이션 침식에 더 탄력적으로 만들어 준다. 규모가 작은 자율적인 팀들이 팀별 서비스를 독립적으로 개발, 전개, 규모 확장을 할 수 있게 함으로써 병렬로 개발할 수 있게 한다. 또, 지속적인 리팩토링을 통해 개개의 서비스 아키텍처가 하나로 병합될 수 있게 허용한다. 마이크로서비스 기반 아키텍처는 지속적인 배포와

전개(디플로이)를 가능케 한다.” 1

즉, 전통적인 애플리케이션은 단일 플랫폼(시스템)에 여러 서비스를 모놀리식

아키텍처로 배포가능한 단일 소프트웨어 산출물로 전달된다. 예로, UI(User Interface) 및 비즈니스 로직, 데이터베이스 엑세스 로직 모두가 하나의 애플리케이션 산출물로

패키징되어 애플리케이션 서버(WAS)로 배포되는 것이다. 이러한 구조에서는 고객의 요구조건에 맞추어 확장성 및 성능을 위한 신속한 대처가 어려워, 보다 유연성 및 작고 독립적으로 분산된 플랫폼 아키텍처가 요구되며 이를 위한 마이크로 서비스 아키텍처가 활용되고 있다. 마이크로 서비스는 대형 애플리케이션의 경계를 허물고, 시스템 내부에 논리적으로 독립적인 소형 시스템들을 구축하는데 도움을 준다.

<그림> 모놀리식과 마이크로 서비스 아키텍처 비교2

1

위키 백과 “마이크로서비스” (https://ko.wikipedia.org/wiki/마이크로서비스)

2

Microservices – Definition (https://howtodoinjava.com/microservices/microservices-definition-principles-benefits/)

(6)

위 다이어그램의 마이크로 서비스 아키텍처에서 볼 수 있듯이, 각각의 마이크로

서비스는 자체 비즈니스 계층과 데이터베이스를 가지고 있다. 그렇게 함으로써, 하나의 마이크로 서비스를 수정한다고 해서 다른 마이크로 서비스에 영향을 주지 않는다.

일반적으로 마이크로 서비스는 HTTP, REST 같은 널리 채택된 lightweight 프로토콜 또는 JMS3 또는 AMQP4와 같은 메시징 프로토콜을 사용하여 서로 통신한다. 특정 시나리오에서는 더 전문화된 프로토콜을 사용할 수도 있다.

마이크로서비스 아키텍처(MSA)의 특징은 다음과 같다.5

애플리케이션 로직을 각자 책임이 명확한 작은 컴포넌트들로 분해하고 이들을 조합해서 솔루션을 제공한다.

각 컴포넌트는 작은 책임 영역을 담당하고 완전히 상호 독립적으로 배포된다.

마이크로서비스는 비즈니스 영역의 한 부분에서만 책임을 담당한다. 그리고 애플리케이션에서 재사용할 수 있어야 한다.

마이크로서비스는 몇 가지 기본 원칙(표준이 아닌 원칙임에 유의)에 기반을 두며, 서비스 소비사와 서비스 제공자 사이의 데이터 교환을 위해 HTTP 와

JSON(JavaScript Object Notation) 같은 경량 통신 프로토콜을 사용한다.

애플리케이션은 항상 기술 중립적 프로토콜(JSON 이 가장 보편적이다)을 사용해 통신하므로 서비스 구현 기술과는 무관한다. 따라서 마이크로서비스 기반의 애플리케이션을 다양한 언어와 기술로 구축할 수 있다는 것을 의미한다.

작고 독립적이며 분산된 마이크로서비스를 사용해 조직은 명확히 정의된 책임 영역을 담당하는 소규모 팀을 보유할 수 있다. 이 팀들은 애플리케이션

출시(delivery)처럼 하나의 목표를 향해 일하지만, 자기가 개발하는 서비스만 책임진다.

2.2 MSA 목적

마이크로서비스 아키텍처(MSA)는 다음과 같은 장점들을 통해 시스템에 대한 개발 및 운영 복잡성을 효율적으로 낮출 수 있다.

Microservice 는 독립적으로 구성될 수 있으며, 상호 독립적으로 구축 및 운영될 수 있음

특정 서비스만 집중할 수 있고, 코드 규모가 작아 효율적인 유지보수가 가능 Restful API 와 같이 lightweight 한 통신을 통해 효과적인 상호 연계가 가능 독립적인 서비스 단위 확장(scale-out)을 지원하기 때문에 효율적인 시스템 자원

활용

3

Java Message Service, 자바 프로그램이 네트워크를 통해 데이터를 송수신하는 자바 API 이다.

4

Advanced Message Queuing Protocal, 메시지 지향 미들웨어를 위한 개방형 표준 응용 계층 프로토콜이다.

(7)

마이크로서비스 아키텍처는 서비스의 규모가 커지고 복잡도가 증가할수록 여러 가지

장점을 갖고 있다. 서비스가 독립적으로 구성하기 때문에 변경이 용이하고 그 변경이 서비스 간 영향이 적다. 아울러, 개별로 서비스 배포가 가능하기 때문에 수시로 필요에 따라 배포할 수 있다.

비용적인 측면에서도 부하가 많은 서비스만 확장할 수 있어 불필요한 자원의 낭비를 줄일 수 있다. 특히, 서비스의 특성에 따라서 자원(Memory, CPU)을 할당 할 수 있으며, 특정 서비스에 대한 집중적으로 요청되는 시기에 따라 가변적으로 리소스를 운영할 수 있다.

2.3 12-Factor App 방법론 6

최근 소프트웨어를 서비스 형태로 제공하는게 일반화 되면서, 웹앱 또는

SaaS(Software As A Service)라고 부르게 되었다. 12-Factor App 은 아래 특징을 가진 SaaS 앱을 만들기 위한 방법론이다.

선언적 형식으로 설정 자동화하여 새로운 개발자가 프로젝트에 참여하는데 드는 시간과 비용을 최소화한다.

OS 에 따라 달라지는 부분을 명확하게 하고, 실행환경 사이의 이식성을 극대화한다.

클라우드 플랫폼 배포에 적합하고, 서버와 시스템의 관리 부담을 없앤다.

개발환경과 운영환경의 차이를 최소화하여 민첩성을 극대화하고 지속적인 배포가 가능하다.

툴, 아키텍처, 개발방식을 크게 바꾸지 않고 서비스를 확장(scale-up)할 수 있다.

12-Factor 방법론은 어떤 프로그래밍 언어로 작성된 앱에도 적용할 수 있고 백엔드 서비스(데이터베이스, 큐, 메모리 캐쉬 등)와 다양한 조합으로 사용할 수 있다.

I. 코드베이스 (Codebase)

버전 관리되는 하나의 코드베이스로 여러 곳에 배포 II. 종속성 (Dependencies)

의존 관계를 명시적으로 선언하고 분리 환경에 의존하지 않도록 함

III. 설정 (Config)

설정 정보는 애플리케이션 코드와 분리하고 환경 변수에 저장 IV. 백엔드 서비스 (Backing services)

5

존카넬(정성권 옮김) “스프링 마이크로서비스 코딩 공작소”. 29p.

6

12-factor App 한국어 사이트 (https://12factor.net/ko/)

(8)

백엔드 서비스를 연결된 리소스로 취급

V. 빌드, 릴리스, 실행 (Build, Release, Run) 빌드, 릴리스, 실행의 3 단계를 엄격하게 분리 VI. 프로세스 (Processes)

응용 프로그램을 하나 또는 여러 개의 독립적인 프로세스로 실행 VII. 포트 바인딩 (Port binding)

포트 바인딩을 통해 서비스를 공개 VIII. 동시성 (Concurrency)

프로세스 모델에 따라 수평적 확장 IX. 폐기 용이성 (Disposability)

빠른 시작이 가능하며, Graceful Shutdown 시 서비스에 영향을 미치지 않도록 하여 안정성 극대화

※Graceful Shutdown : 정상적인 종료로써 소프트웨어 기능으로 컴퓨터를 끄거나 OS 가 프로세스를 안전하게 종료하고 연결을 해제하는 작업을 수행할 수 있는 경우이다.

X. 개발/운영 일치 (Dev/prod parity)

개발 환경과 운영 환경을 최대한 동일하게 유지

CI/CD (Continuous Integration/Continuous Delivery)환경이 갖춰져 있어야 함

XI. 로그 (Logs)

로그를 이벤트 스트림으로 취급함

중앙 집권적인 서비스를 통해 로그 이벤트를 수집하고, 인덱싱하여 분석하는 환경이 가능해야 함

XII. 관리 프로세스 (Admin processes)

관리 작업(admin/maintenance)을 일회성 프로세스로 실행

(9)

2.4 Service Mesh

MSA 를 적용한 시스템이 커지면 마이크로서비스의 인스턴스 수가 증가함에 따라 시스템 런타임 복잡성 문제가 발생한다. 보안, 로드 밸런싱, 모니터링 등 동적으로 수많은 마이크로서비스의 인스턴스간 통신이 유발하는 관심사들을 내부 네트워크에서

안정적으로 다루기 위해 새로운 기능들이 필요하다. 각 서비스 마이크로서비스 간 통신을 최적화 하고 다운 타임을 방지하며 전체 서비스를 관리하기 위한 이러한 Outer

Architecture 를 Service Mesh 라고 한다.

Service Mesh 는 복잡한 내부 네트워크를 추상화를 통해 서비스간의 통신이 빠르고, 안정적이며, 신뢰성을 보장한다.

2.4.1 Service Mesh 의 주요 기능

MSA 가 갖추어야 하는 Service Mesh 의 주요 기능은 다음과 같다.

Configuration Management

설정변경 시 서비스의 재빌드와 재부팅 없이 즉시 반영 Service Discovery

API Gateway 가 서비스를 검색하는 매커니즘 Load Balancing

서비스간 부하 분산 API Gateway

API 서버 앞단에서 API 엔드포인트 단일화 및 인증, 인가, 라우팅 기능 담당 Centralized Logging

서비스별 로그의 중앙집중화 Centralized Metrics

서비스별 메트릭 정보의 중앙집중화 Distributed Tracing

서비스간 호출 추적과 성능, 분석 관리 Resilience & Fault Tolerance

서비스간 장애 전파 차단 Auto Scaling & Self Healing

자동 스케일아웃과 복구 자동화

Packaging, Deployment & Scheduling 패키징, 빌드 및 배포 자동화

(10)

Test Automation

서비스 테스트 자동화

2.4.2 Service Mesh 적용 방안

전자정부 클라우드 플랫폼과 개방형 클라우드 플랫폼(PaaS-TA)에 채택되어 있는 Container Orchestration 는 Kubernetes 와 Cloud Foundry 의 Diego 이며, Service Mesh 적용방안은 다음과 같다.

2.4.2.1 Kubernetes 의 Istio7 솔루션을 사용하는 방안

마이크로서비스 앞단에 통신 제어를 담당하는 경량화된 프록시를 배치하는 디자인패턴을 가진 Kubernetes 의 Istio 를 적용하는 방안이다.

각 서비스 인스턴스에 사이드카라고하는 프록시 인스턴스를 제공하여 구현된다. 이 사이트카에 Envoy 가 배포되어 애플리케이션을 수정하지 않고도 서비스의 인·아웃 통신 트래픽을 제어한다.

인스턴스 간의 네트워크 트래픽과 관련 데이터들이 이동하는 영역을 Data Plane 이라 하고, Data Plane 의 동작을 제어, 구성 및 정책을 설정하는 영역을 Control Plane

이라한다. Service Discovery 수행 방식은 Control Plane 의 Pilot 이 서비스 레지스트리 정보를 가지고 있고, Envoy 가 해당 레지스트리 정보를 참고하여 다른 서비스의 엔드 포인트로 접근하게 된다. Control Plane 의 Mixer 는 접근 정책에 대한 통제와 서비스 모니터링을 위한 Metric 지표를 수집한다. Control Plane 의 Citadel 은 인증·인가의 보안을 담당하는 모듈로 TLS 인증서를 관리한다.

7

https://istio.io/latest/docs/concepts/ 참조

(11)

이러한 Istio 의 추상화된 트래픽 관리 기능으로 인해 비즈니스 마이크로서비스 개발에

집중할 수 있게 해준다.

2.4.2.1 Spring Cloud 기반 Service Mesh 직접 구축

Spring Cloud 를 Spring Boot 와 함께 사용하면 분산처리 환경의 안정적인 Service Mesh 를 직접 구현할 수 있다. Spring Cloud 는 애플리케이션 스택의 일부로 모든 MSA 관심사를 해결하도록 잘 통합된 다양한 자바 라이브러리들의 묶음으로 개발자가 분산 시스템의 공통 패턴인 구성관리, Service Discovery, Circuit Breakers, 지능형 라우팅, 프록시, 분산 세션, 클러스트 상태 등을 신속하게 구축할 수 있는 도구를 제공한다.

개발자의 PC 나 노트북에서 뿐만 아니라 PaaS-TA 의 Cloud Foundry 같은 클라우드 플랫폼에서도 원활하게 작동된다.

2.4.3 Spring Cloud 를 활용한 MSA 구축 가이드

본 가이드에서는 어떤 클라우드 플랫폼에서도 작동할 뿐 아니라, 개발자의 로컬 PC 에서도 분산처리 환경을 구축할 수 있는 Spring Cloud 를 사용하였다.

2.4.4 Spring Cloud 와 Kubernetes 의 기술 요소 매핑

스프링 클라우드와 쿠버네티스 두 플랫폼은 매우 다르기 때문에 직접적인 일대일 비교는 어렵지만, MSA 의 기술스택으로 표현한다면 다음과 같다.

MSA 관심사 Spring Cloud Kubernetes

Configuration Management Config Server, Consul, Netflix Archaius

Kubernetes ConfigMap &

Secrets Service Discovery Netflix Eureka, Hashicorp

Consul

Kubernetes Service & Ingress Resources

Load Balancing Netflix Ribbon Kubernetes Service

API Gateway Netflix Zuul Kubernetes Service & Ingress Resources

Service Security Spring Cloud Security -

Centralized Logging ELK Stack (LogStash) EFK Stack (Fluentd)

Centralized Metrics Netflix Spectator & Atlas Heapster, Prometheus, Grafana Distributed Tracing Spring Cloud Sleuth, Zipkin OpenTracing, Zipkin

Resilience & Fault Tolerance Netflix Hystrix, Turbine &

Ribbon

Kubernetes Health Check &

resource isolation

Auto Scaling & Self Healing - Kubernetes Health Check, Self Healing, Autoscaling

Packaging, Deployment &

Scheduling Spring Boot Docker/Rkt, Kubernetes

Scheduler & Deployment Job Management Spring Batch Kubernetes Jobs & Scheduled

Jobs

Singleton Application Spring Cloud Cluster Kubernetes Pods

(12)

ELK, EFK 스택, 추적 라이브러리 그리고 Hystrix 및 Spring Boot 와 같은

라이브러리등은 두 환경에서 모두 유용하게 사용될 수 있다. 기술스택을 MSA 관심사로 Spring Cloud 와 Kubernetes 를 매핑해 보았지만, 두 플랫폼은 서로 보완적이고 함께 결합하여 보다 강력한 솔루션을 만들어 낼 수 있다.

2.4.4.1 마이크로서비스 필요조건에 따른 범위

다음은 MSA 의 필요조건을 최하위 하드웨어부터 최상위 DevOps 까지를 나열하여 Spring Cloud 과 쿠버네티스 플랫폼이 관여하는 범위를 보여준다.

(13)

Spring Cloud 의 장점과 쿠버네트스가 갖고 있는 장점이 서로 다르기에 두 플랫폼은

서로 상호보완된다. 예를 들어, Spring Boot 는 상용화 수준의 단독 실행가능한 jar 애플리케이션을 제공하지만, Docker 및 쿠버네티스의 선언적인 배포와 자원 용량 설정등의 기능과 함께 어우러졌을 때 효과를 발휘한다. 또한 Spring Cloud 의

Hystrix(서킷브레이커) 탄력적이고, fault tolerant 한 애플리케이션 라이브러리를 갖고 있지만, 쿠버네티스의 Health Checks, 프로세스 재시작 기능, 자동 스케일링 기능들과 결합할 때 강력한 MSA 를 구현할 수 있게 된다.

2.4.4.2 Kubernetes 와 결합된 Spring Cloud 의 예

위에서 언급한 바와같이, 두 플랫폼은 분야별로 각가 다른 강점을 갖고 있다. Spring Cloud 는 개발자에 친숙한 플랫폼이라 할 수 있는 반면, 쿠버네티스는 DevOps

친화적이며, 러닝 커브가 높지만, 대부분의 MSA 라이프사이클에 관여한다.

Capability Spring Cloud 와 쿠버네티스

DevOps Self service, multi-environment capabilities

Auto Scaling & Self Healing Pod/Cluster Autoscaler, HealthIndicator, Scheduler Resilience & Fault Tolerance HealthIndicator, Hystrix, HealthCheck, Process Check Distributed Tracing Zipkin

Centralized Metrics Heapster, Prometheus, Grafana Centralized Logging EFK

Job Management Spring Batch, Schedulled Job Load Balancing Ribbon, Service

Service Discovery Service

Configuration Management Spring Cloud Kubernetes, ConfigMap, Secret

Service Logic 전자정부 표준프레임워크 v4.0 (Spring Framework 5.x) Application Packaging Spring Boot

Develoyment & Scheduling Deployment strategy, A/B, Canary, Scheduler strategy Process Isolation Docker, Pods

Environment Management Namespaces, Authorizations

Resource Management CPU and memory limits, Namespace resource quotes

※ Spring Cloud Kubernetes8는 쿠버네티스에서 잘 작동하도록 Spring Cloud 인터페이스 구현을 제공한다.

8

https://github.com/spring-cloud/spring-cloud-kubernetes 참조

(14)

2.5 MSA 적용 시 고려사항

디자인 패턴으로 유명한 Martin Fowler 는 모놀리식으로 관리하기에 특별히 복잡한 시스템을 운영할 상황이 아니면 마이크로 서비스 도입을 고려하지 말 것을 강조9하고 있다.

시스템 복잡도 단계 따라 아키텍처 선택 시 개발 생산성에 크게 영향을 받을 수 있기 때문이다. 특히 SW 엔지니어에게는 개발, 운영에 관한 다양한 스킬셋과 해결 방안뿐 아니라 단일 서비스가 아닌, 전체 동작에 대한 이해까지 요구될 수 있기 때문에 더욱 신중을 기하여 아키텍처를 선정해야 한다.

<그림> 시스템 복잡도와 아키텍처

마이크로서비스 기반 애플리케이션을 도입 시 다음 사항들을 고려해 볼 필요가 있다.10 MSA 를 도입할 경우 비용을 얼마나 절감할 수 있는가?

마이크로서비스를 요구할 만큼 시스템 복잡도가 높은가? 또는 복잡도를 지나치게 높인 마이크로서비스가 생산성을 저해하고 있지는 않은가?

개발팀에게 개발과 운영을 동시에 요구할 만큼 인프라가 준비되어 있는가?

9

MicroservicePremium by Martin Fowler (https://martinfowler.com/bliki/MicroservicePremium.html)

10

마이크로서비스 아키텍처가 꼭 필요한가요? (https://www.samsungsds.com/global/ko/support/insights/msa.html)

(15)

3. Spring Cloud 기반 마이크로서비스 이해

3.1 배경

응용프로그램 개발은 Spring 프레임워크의 확산 및 보급에 따라 보다 간단하고 빠른 개발이 가능한 패러다임으로의 변화가 이루어 졌다. Spring 프레임워크의 기반이 되는 의존성 주입(DI : Dependency Injection)과 관점 지향 프로그래밍(AOP : Aspect Oriented Programming) 방식은 응용 프로그램의 새로운 기준으로 자리 잡았다.

그러나 Spring 프레임워크 발전함에 따라 관련된 설정의 복잡성을 높아졌으며,

배포(deploy) 측면에서 보면 큰 변화가 없는 상태이다. 특히, 응용 프로그램의 복잡성 및 대화형에 대한 근본적인 개발 방식과 배포 방식의 변화가 필요하다.

이를 해결하기 위한 방안으로 마이크로 서비스 아키텍처(MSA : MicroServcie Architecture) 기반의 시스템 개발 및 운영 방안이 제시되었다. 이 마이크로 서비스 아키텍처는 개별적으로 운영되는 컴포넌트들로 대형 시스템을 구축하고, Spring 은 컴포넌트 레벨에서 Spring 이 항상 수행해 왔던 프로세스 레벨에서 느슨하게

결합된(loosely-coupled) 컴포넌트의 프로세스 구성을 제공한다.

본 가이드에서는 전자정부 표준프레임워크에서 다음과 같은 2 가지 Spring 프로젝트 적용을 통하여 효율적인 마이크로 서비스 개발 및 운영을 지원한다.

Spring Boot : 컴포넌트 레벨에서 마이크로 서비스 아키텍처로 설정 간소화 및 독립 서비스를 지원 (Embedded Web Server, Stand-alone application 등의 Inner Architecture 영역 지원)

Spring Cloud : 시스템 레벨에서의 마이크로 서비스 아키텍처로 컴포넌트들 간의 효율적인 분산 서비스를 지원 (Load Balancing, Service Discovery 등의 Outer Architecture 영역 지원)

3.2 Spring Boot

Spring Boot 는 표준프레임워크가 제공하는 기본적인 공통기반 영역(Foundation Layer ; Spring Core, Batch Spring Web 등)을 기반 위에 모듈 단위의 배포 및 설정 최소화를 지원하는 실행(execution) 환경의 기반을 제공한다.

Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”. We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. Most Spring Boot applications need very little Spring configuration.11

• 스프링부트는 단독 실행되는, 실행하기만 하면 되는 상용화 가능한 수준의

11

Spring Boot Overview 참조 (https://spring.io/projects/spring-boot)

(16)

스프링 기반 애플리케이션을 쉽게 만들어 낼 수 있다.

• 최소한의 설정으로 스프링 플랫폼과 third-party 라이브러리들을 사용할 수 있도록 하고 있다.

<그림> The Spring IO Platform

이는 표준프레임워크 활용 측면에서 보다 손 쉽게 설정을 구성하거나 개발 및 배포를 빠르게 지원할 수 있다. 또한, embedded 방식의 container 를 사용하여 web server 를 통한 배포가 아닌, 독립적으로 실행 가능한 웹 애플리케이션을 구성할 수 있다.

제공 기능으로는

단독 실행이 가능한 스프링 애플리케이션을 생성

내장형 Tomcat, Jetty 또는 Undertow 를 지원 (WAR 파일로 배포 시 불필요) 기본으로 설정되어 있는 ‘starter’ 컴포넌트들을 쉽게 환경 설정 (dependency,

build 등)

Library 인식을 통한 자동 환경 구성 지원

상용화 수준의 통계(metrics), 상태 점검(health check) 및 외부 설정 제공 설정을 위한 XML 코드 불필요

(17)

3.2.1 Spring Boot Starters

스타터(Starters)는 응용 프로그램에 포함 할 수 있는 편리한 종속성 관리의 집합이다.

샘플 코드와 복사-붙여넣기의 의존성 관리를 거치지 않고도 필요한 모든 Spring 및 관련 기술을 한 번에 관리를 할 수 있다. 예를 들어, 데이터베이스 액세스를 위한 Spring 및 JPA 를 사용하려면 “spring-boot-starter-data-jpa”프로젝트를 종속성에 포함 시켜 사용할 수 있다.

스타터에는 프로젝트를 신속하게 시작하고 실행하는데 필요한 많은 종속성이 포함되어 있으며 일관되게 지원 관리되는 종속성 세트를 제공한다.

다음으로 스프링 부트에는 3 가지 카테고리로 분류하여 스타터를 제공한다.12 스프링 부트 애플리케이션 스타터

이름 설명

spring-boot-starter 자동 구성 지원, 로깅 및 YAML 을 포함한 핵심 스타터 spring-boot-starter-activemq Apache ActiveMQ 를 사용한 JMS 메시징 스타터 spring-boot-starter-amqp Spring AMQP 및 Rabbit MQ 사용을 위한 스타터

spring-boot-starter-aop Spring AOP 및 AspectJ 를 이용한 Aspect 지향 프로그래밍 스타터 spring-boot-starter-artemis Apache Artemis 를 사용한 JMS 메시징 스타터

spring-boot-starter-batch 스프링 배치 사용을 위한 스타터

spring-boot-starter-cache Spring Framework 의 캐싱 지원 사용을 위한 스타터

spring-boot-starter-data-cassandra Cassandra 분산 데이터베이스 및 Spring Data Cassandra 사용을 위한 스타터

spring-boot-starter-data- cassandra-reactive

Cassandra 분산 데이터베이스 및 Spring Data Cassandra Reactive 사용을 위한 스타터

spring-boot-starter-data- couchbase

Couchbase 문서 지향 데이터베이스 및 Spring Data Couchbase 사용을 위한 스타터

spring-boot-starter-data- couchbase-reactive

Couchbase 문서 지향 데이터베이스 및 Spring Data Couchbase Reactive 를 사용하기위한 스타터

spring-boot-starter-data- elasticsearch

Elasticsearch 검색 및 분석 엔진 및 Spring Data Elasticsearch 사용을 위한 스타터

spring-boot-starter-data-jdbc 스프링 데이터 JDBC 사용을 위한 스타터

spring-boot-starter-data-jpa Hibernate 와 함께 Spring Data JPA 를 사용하기위한 스타터 spring-boot-starter-data-ldap 스프링 데이터 LDAP 사용을 위한 스타터

spring-boot-starter-data-mongodb MongoDB 문서 지향 데이터베이스 및 Spring Data MongoDB 사용을 위한 스타터

spring-boot-starter-data- mongodb-reactive

MongoDB 문서 지향 데이터베이스 및 Spring Data MongoDB Reactive 사용을 위한 스타터

spring-boot-starter-data-neo4j Neo4j 그래프 데이터베이스 및 Spring Data Neo4j 사용을 위한 스타터

spring-boot-starter-data-r2dbc Spring Data R2DBC 사용을 위한 스타터

12

스프링 부트 스타터 (https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#using-boot-

starter)

(18)

spring-boot-starter-data-redis Spring Data Redis 및 Lettuce 클라이언트와 함께 Redis 키-값 데이터 저장소를 사용하기위한 스타터

spring-boot-starter-data-redis- reactive

Spring Data Redis 반응 형 및 Lettuce 클라이언트와 함께 Redis 키-값 데이터 저장소를 사용하기위한 스타터

spring-boot-starter-data-rest Spring Data REST 를 사용하여 REST 를 통해 Spring Data 저장소를 노출하기위한 스타터

spring-boot-starter-data-solr Spring Data Solr 과 함께 Apache Solr 검색 플랫폼을 사용하기위한 스타터

spring-boot-starter-freemarker FreeMarker 보기를 사용하여 MVC 웹 애플리케이션 빌드를 위한 스타터

spring-boot-starter-groovy- templates

Groovy 템플릿 뷰를 사용하여 MVC 웹 애플리케이션 구축을 위한 스타터

spring-boot-starter-hateoas Spring MVC 및 Spring HATEOAS 로 하이퍼 미디어 기반 RESTful 웹 애플리케이션 구축을 위한 스타터

spring-boot-starter-integration 스프링 통합 사용을 위한 스타터

spring-boot-starter-jdbc DB 연결 풀에서 JDBC 를 사용하기 위한 스타터

spring-boot-starter-jersey JAX-RS 및 Jersey를 사용하여 RESTful 웹 애플리케이션을 빌드하기위한 스타터. 대안spring-boot-starter-web

spring-boot-starter-jooq

jOOQ 를 사용하여 SQL 데이터베이스에 액세스하기위한

스타터. spring-boot-starter-data-jpa 또는에 대한 대안 spring- boot-starter-jdbc

spring-boot-starter-json JSON 을 읽고 쓰는 스타터

spring-boot-starter-jta-atomikos Atomikos 를 사용한 JTA 트랜잭션 스타터

spring-boot-starter-jta-bitronix Bitronix 를 사용한 JTA 트랜잭션 스타터. 2.3.0 부터 사용되지 않음 spring-boot-starter-mail Java Mail 및 Spring Framework 의 이메일 전송 지원을 위한

스타터

spring-boot-starter-mustache 콧수염보기를 사용하여 웹 애플리케이션을 빌드하기 위한 스타터 spring-boot-starter-oauth2-client Spring Security 의 OAuth2 / OpenID Connect 클라이언트 기능을

사용하기위한 스타터 spring-boot-starter-oauth2-

resource-server

Spring Security 의 OAuth2 리소스 서버 기능을 사용하기위한 스타터

spring-boot-starter-quartz Quartz 스케줄러 사용을 위한 스타터

spring-boot-starter-rsocket RSocket 클라이언트 및 서버 구축을 위한 스타터 spring-boot-starter-security 스프링 시큐리티 사용을 위한 스타터

spring-boot-starter-test JUnit, Hamcrest 및 Mockito 를 포함한 라이브러리로 Spring Boot 애플리케이션을 테스트하기위한 스타터

spring-boot-starter-thymeleaf Thymeleaf 보기를 사용하여 MVC 웹 애플리케이션 빌드를위한 스타터

spring-boot-starter-validation Hibernate Validator 와 함께 Java Bean Validation 을 사용하기위한 스타터

spring-boot-starter-web Spring MVC 를 사용하는 RESTful 애플리케이션을 포함한 웹 구축을 위한 스타터. Tomcat 을 기본 내장 컨테이너로 사용 spring-boot-starter-web-services 스프링 웹 서비스 사용을 위한 스타터

spring-boot-starter-webflux Spring Framework 의 Reactive Web 지원을 사용하여 WebFlux 애플리케이션 구축을 위한 스타터

spring-boot-starter-websocket Spring Framework 의 WebSocket 지원을 사용하여 WebSocket

(19)

애플리케이션 구축을 위한 스타터

스프링 부트 프로덕션 스타터

이름 설명

spring-boot-starter-actuator 애플리케이션을 모니터링하고 관리 할 수 있는 프로덕션 준비 기능을 제공하는 Spring Boot Actuator 사용을 위한 스타터

스프링 부트 테크니컬 스타터

이름 설명

spring-boot-starter-jetty 내장 서블릿 컨테이너로 Jetty를 사용하기위한 스타터. 대안spring- boot-starter-tomcat

spring-boot-starter-log4j2 로깅을 위해 Log4j2를 사용하기위한 스타터. 대안spring-boot-starter- logging

spring-boot-starter-logging Logback 을 이용한 로깅 스타터. 기본 로깅 스타터 spring-boot-starter-reactor-

netty

임베디드 Reactive HTTP 서버로 Reactor Netty 를 사용하기위한 스타터.

spring-boot-starter-tomcat 임베디드 서블릿 컨테이너로 Tomcat을 사용하기위한 스타터. 에 의해 사용되는 기본 서블릿 컨테이너 스타터spring-boot-starter-web spring-boot-starter-undertow Undertow를 임베디드 서블릿 컨테이너로 사용하기위한

스타터. 대안spring-boot-starter-tomcat

3.3 Spring Cloud

Spring Cloud 는 개발자가 분산 시스템 구성에 필요한 다양한 기능(설정 관리 및 공유, 서비스 등록 및 관리, 서비스 요청 라우팅 등)을 제공한다. 분산 시스템을 구성하기 위한 복잡한 설정 및 서비스들을 효율적이고 신속하게 구현할 수 있도록 지원한다. 또한, 개발된 서비스는 작은 노트북, Bare metal 데이터 센터 및 Cloud Foundry 와 같은 클라우드 플랫폼을 포함한 모든 분산 환경에서 동작을 보장한다.

Spring Cloud provides tools for developers to quickly build some of the common patterns in distributed systems (e.g. configuration management, service discovery, circuit breakers, intelligent routing, micro-proxy, control bus, one-time tokens, global locks, leadership election, distributed sessions, cluster state). Coordination of distributed systems leads to boiler plate patterns, and using Spring Cloud

developers can quickly stand up services and applications that implement those patterns. They will work well in any distributed environment, including the

developer’s own laptop, bare metal data centres, and managed platforms such as Cloud Foundry. 13

13

Spring Cloud Overview 참조 (https://spring.io/projects/spring-cloud)

(20)

<그림> Spring Cloud 기능 구성

제공기능으로는

분산 및 버전으로 구분된 설정 관리 서비스 등록 및 조회

라우팅 및 상태 체크 서비스 대 서비스 호출

서비스 분산 로딩(Load balancing) 서비스 간 호출 분리(Circuit Breaker) 클러스터링 환경 관리

분산 메세징

3.3.1 Spring Cloud 컴포넌트

서비스 설명 컴포넌트

Config 서비스 별도의 통합된 설정 관리 서비스 제공을 통해 환경

독립적 서비스 제공 Spring Config

Service Discovery 서비스

서비스에 대한 물리적 위치 정보 대신 논리적 서비스

위치 정보 제공 Eureka (Spring Cloud Netflix)

Event Bus

서비스 분산 메세징 지원을 위한 서비스 연계 지원 Spring Cloud Bus (AMQP &

RabbitMQ) Circuit

Breaker 서비스

서비스 간 호출 시, 문제가 있는 서비스에 대한 차단 지원 서비스

Hystrix (Spring Cloud Netflix)

Client Load Balancing

서비스 호출 시에 분산 형태로 호출 할 수 있는 client

적용 서비스 library Ribbon (Spring Cloud Netflix) Service Router

서비스

서비스 호출 시, routing 을 통해 실제 서비스에 위치

제공 Zuul (Spring Cloud Netflix)

(21)

API Gateway

서비스 Microservice 에 대한 API 관리 및 모니터링 서비스 Zuul (Spring Cloud Netflix) Cluster 서비스 Service level 의 Cluster 를 지원하기 위한 서비스

제공 Spring Cloud Cluster

Security

서비스 Load balanced 환경에서의 OAuth2 인증 지원 서비스 Spring Cloud Security Polyglot 지원

서비스 non-JVM 프로그래밍 언어 지원을 위한 서비스 Spring Cloud Sidecar Kubernetes

지원 서비스

Spring Cloud 애플리케이션을 위한 쿠버네티스

Discovery 와 ConfigMaps 지원 서비스 Spring Cloud Kubernetes

(22)

4. Spring Cloud 기반 마이크로 서비스 활용

본 가이드에서는 Spring Boot 와 Spring Cloud 컴포넌트(Eco-system)을 사용하여 클라우드 네이티브한 애플리케이션을 제작하도록 하겠다.

본 예제에 사용되는 오픈소스는 다음과 같다.

OpenJDK 1.8

eGovframework 4.0.0

spring-boot-starter 2.2.6.RELEASE spring-boot-starter-test 2.2.6.RELEASE spring-boot-test 2.2.6.RELEASE

spring-boot-starter-web 2.2.6.RELEASE Spring Framework 5.2.5.RELEASE

Spring swagger 2.9.2

4.1 Spring Boot 을 활용한 MSA 애플리케이션 제작

본 가이드에서는 두 가지의 서비스를 활용하여 클라우드 네이티브한 애플리케이션을 제작하려 한다.

첫 번째는 화면의 디스플레이를 담당하는 “화면 서비스”와 두 번째인 실제 정보를 담고 있는 “커스터머 서비스”를 제작한다.

서비스의 프로세스는 다음과 같다.

화면 서비스 커스터머 서비스

서비스 Catalogs Customers

Request /catalogs/{customerId} /customers/customerId Response String Type (JSON) String Type (JSON)

(23)

4.1.1 Catalogs 서비스

카탈로그 서비스는 상품의 전시 및 화면에 대한 로직을 처리하는 서비스로서 별도의 데이터를 가지고 있지는 않지만 사용자의 입력 및 출력에 대한 서비스를 제공한다. 또한, 요청에 따라 각각의 서비스를 호출하여 요청에 응답한다.

4.1.1.1 Catalogs 서비스 프로젝트 생성

화면 Layer 를 담당하는 카탈로그(Catalogs) 서비스를 전자정부 표준프레임워크 개발환경을 활용하여 다음과 같이 생성한다.

화면 Layer 를 담당하는 카탈로그(Catalogs) 서비스를 전자정부 표준프레임워크 개발환경을 활용하여 다음과 같이 생성한다. (v3.10 기준)

New > Project > Spring Boot > Spring Starter Project 를 선택 후 아래와 같이 입력한 후 Next 를 선택한다.

Service URL : https://start.spring.io Use default location : 체크 (기본 프로젝트 경로 변경을 원하면 해제 후 지정)

Type : Maven Packaging : Jar Java Version : 8 Language : Java

Group : egovframework.msa.sample Artifact : Catalogs

Version : 1.0.0

Description : MSA Sample Project

Group Id : egovframework.msa.sample

(24)

다음 단계는 프로젝트의 Dependency 를 추가하는 단계인데 여기서는 선택하지 않는다.

(이 가이드에서는 의존관계를 pom.xml 에 직접 등록하는 방법으로 진행한다.)

Next > Finish 또는 Finish 를 바로 선택하여 프로젝트를 생성한다.

4.1.1.2 Catalogs 프로젝트 디렉터리 구조 설정 카탈로그 서비스의 디렉터리 구조는 다음과 같다.

파일명 패키지 명 구분 비고

Pom.xml / 의존성 관리 파일

Application.yml src/main/resources Resource 파일 SpringBoot 설정 파일

CatalogsApplication.java egovframework.msa.sample 클래스 파일 애플리케이션 구동 파일 CatalogsController.java egovframework.msa.sample.controller 컨트롤러 클래스

파일

Restful Api

(25)

CustomerApiService.java egovframework.msa.sample.service 인터페이스 파일 CustomerApiServiceImpl.java egovframework.msa.sample.serviceImpl 클래스 파일

4.1.1.3 Catalogs 서비스의 의존성(Dependency) 설정 아래와 같이 의존성을 추가한다.

카탈로그(Catalogs)의 Pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema- instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven- 4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.2.6.RELEASE</version>

<relativePath />

</parent>

<groupId>egovframework.msa.sample</groupId>

<artifactId>Catalogs</artifactId>

<version>1.0.0</version>

<name>Catalogs</name>

<description>MSA Sample Project</description>

<properties>

<java.version>1.8</java.version>

<org.egovframe.rte.version>4.0.0</org.egovframe.rte.version>

<spring.cloud.version>2.2.5.RELEASE</spring.cloud.version>

</properties>

<repositories>

<repository>

<id>mvn2s</id>

<url>https://repo1.maven.org/maven2/</url>

<releases>

<enabled>true</enabled>

</releases>

<snapshots>

<enabled>true</enabled>

</snapshots>

</repository>

<repository>

<id>egovframe</id>

<url>http://maven.egovframe.go.kr/maven/</url>

<releases>

<enabled>true</enabled>

</releases>

<snapshots>

<enabled>false</enabled>

</snapshots>

</repository>

</repositories>

(26)

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter</artifactId>

<exclusions>

<exclusion>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-logging</artifactId>

</exclusion>

</exclusions>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

<exclusions>

<exclusion>

<groupId>org.junit.vintage</groupId>

<artifactId>junit-vintage-engine</artifactId>

</exclusion>

</exclusions>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<!-- 표준프레임워크 실행환경 -->

<dependency>

<groupId>org.egovframe.rte</groupId>

<artifactId>org.egovframe.rte.fdl.cmmn</artifactId>

<version>${org.egovframe.rte.version}</version>

</dependency>

<dependency>

<groupId>org.egovframe.rte</groupId>

<artifactId>org.egovframe.rte.ptl.mvc</artifactId>

<version>${org.egovframe.rte.version}</version>

</dependency>

</dependencies>

<build>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

</plugin>

</plugins>

</build>

</project>

4.1.1.4 애플리케이션 설정 파일 생성

스프링 부트 및 프레임워크의 의존성(dependency)를 추가하였으면, 애플리케이션의 설정을 위한 application.yml 파일을 생성한다. application.yml 파일은

(27)

src/main/resources 디렉터리에 위치하며, yml(yaml) 파일 대신 properties 형태의

파일을 사용할 수도 있다.

application.yml 파일 소스 내용

server:

port: 8081

spring:

application:

name: catalog

4.1.1.5 각 클래스 파일 작성

MSA 애플리케이션의 구조 파일들을 모두 작성하였으면, 다음으로 실제 로직을 담고 있는 각각의 클래스 파일들을 작성한다.

4.1.1.5.1 CatalogsApplication.java 파일 작성

package egovframework.msa.sample;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.annotation.ComponentScan;

@ComponentScan("egovframework.*")

@SpringBootApplication

public class CatalogsApplication {

public static void main(String[] args) {

SpringApplication.run(CatalogsApplication.class);

} }

4.1.1.5.2 CatalogsController.java 파일 작성

package egovframework.msa.sample.controller;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import egovframework.msa.sample.service.CustomerApiService;

@RestController

@RequestMapping("/catalogs/customerinfo") public class CatalogsController {

@Autowired

private CustomerApiService customerApiService;

(28)

@GetMapping(path = "/{customerId}")

public String getCustomerInfo(@PathVariable String customerId) {

String customerInfo = customerApiService.getCustomerDetail(customerId);

System.out.println("response customerInfo : " + customerInfo);

return String.format("[Customer id = %s at %s %s ]", customerId, System.currentTimeMillis(), customerInfo);

} }

4.1.1.5.3 CustomerApiService.java 파일 작성

package egovframework.msa.sample.service;

public interface CustomerApiService {

String getCustomerDetail(String customerId);

}

4.1.1.5.4 CustomerApiServiceImpl.java 파일 작성

package egovframework.msa.sample.serviceImpl;

import org.springframework.stereotype.Service;

import egovframework.msa.sample.service.CustomerApiService;

@Service

public class CustomerApiServiceImpl implements CustomerApiService { @Override

public String getCustomerDetail(String customerId) { return customerId;

} }

4.1.1.6 Catalogs 서비스 구동 및 테스트

Catalogs 의 CatalogsApplcation.java 파일을 java application 으로 실행하면, 아래와 같이 Spring boot 를 통하여 embedded tomcat 으로 구동되는 것을 확인할 수 있다.

. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/

:: Spring Boot :: (v2.3.4.RELEASE)

2020-10-19 15:47:01.511 INFO 40527 --- [ main] e.msa.sample.CatalogsApplication : Starting CatalogsApplication on jeonghunhuiui-iMac.local with PID 40527

(/Users/EGOV3.9/workspace/Catalogs/target/classes started by hhjeong in /Users/EGOV3.9/workspace/Catalogs)

2020-10-19 15:47:01.513 INFO 40527 --- [ main] e.msa.sample.CatalogsApplication : No active profile set, falling back to default profiles: default

2020-10-19 15:47:02.187 INFO 40527 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8081 (http)

2020-10-19 15:47:02.196 INFO 40527 --- [ main] o.apache.catalina.core.StandardService

(29)

: Starting service [Tomcat]

2020-10-19 15:47:02.196 INFO 40527 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.38]

2020-10-19 15:47:02.256 INFO 40527 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/]

: Initializing Spring embedded WebApplicationContext 2020-10-19 15:47:02.256 INFO 40527 --- [ main]

w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 711 ms

2020-10-19 15:47:02.403 INFO 40527 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'

2020-10-19 15:47:02.524 INFO 40527 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8081 (http) with context path ''

2020-10-19 15:47:02.533 INFO 40527 --- [ main] e.msa.sample.CatalogsApplication : Started CatalogsApplication in 1.567 seconds (JVM running for 1.816)

2020-10-19 15:47:05.921 INFO 40527 --- [nio-8081-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]

: Initializing Spring DispatcherServlet 'dispatcherServlet'

2020-10-19 15:47:05.921 INFO 40527 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'

2020-10-19 15:47:05.925 INFO 40527 --- [nio-8081-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 3 ms

그럼, 웹 브라우저를 실행하고 아래와 같이 URL 을 입력하면 customerid 가 1234 인 내용을 확인할 수 있다.

URL : http://localhost:8081/catalogs/customerinfo/1234

(30)

4.1.2 Customers 서비스

Customers 서비스는 고객정보를 조회할 수 있는 서비스로 요청에 따라 고객정보를 반환한다. 실제 데이터베이스를 활용한 데이터 입출력을 제외하며 서비스 프로세스 절차에 집중한 가이드를 제공한다. 이후 추가로 DAO 및 DataAccess 에 해당하는 로직을 별도로 구현한다.

4.1.2.1 Customers 서비스 프로젝트 생성

전자정부 표준프레임워크 개발환경을 활용하여 다음과 같이 생성한다. (v3.10 기준) New > Project > Spring Boot > Spring Starter Project 를 선택 후 아래와 같이 입력한 후 Next 를 선택한다.

Service URL : https://start.spring.io Use default location : 체크 (기본 프로젝트 경로 변경을 원하면 해제 후 지정)

Type : Maven Packaging : Jar Java Version : 8 Language : Java

Group : egovframework.msa.sample Artifact : Customers

Version : 1.0.0

Description : MSA Sample Project

Group Id : egovframework.msa.sample

(31)

다음 단계는 프로젝트의 Dependency 를 추가하는 단계인데 여기서는 선택하지 않는다.

(이 가이드에서는 의존관계를 pom.xml 에 직접 등록하는 방법으로 진행한다.)

Next > Finish 또는 Finish 를 바로 선택하여 프로젝트를 생성한다.

4.1.2.2 Customers 프로젝트 디렉터리 구조 설정 커스터머 서비스의 디렉터리 구조는 다음과 같다.

파일명 패키지 명 구분 비고

Pom.xml / 의존성 관리 파일

Application.yml src/main/resources Resource 파일 SpringBoot 설정 파일

CustomersApplication.j ava

egovframework.msa.sample 클래스 파일 애플리케이션

구동 파일 CustomersController.ja

va

egovframework.msa.sample.controller 컨트롤러 클래스 파일

Restful Api Controller

(32)

4.1.2.3 Customers 서비스의 의존성(Dependency) 설정

아래와 같이 의존성을 추가한다.

커스터머(Customers)의 Pom.xml

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema- instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven- 4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.2.6.RELEASE</version>

<relativePath />

</parent>

<groupId>egovframework.msa.sample</groupId>

<artifactId>Customers</artifactId>

<version>1.0.0</version>

<name>Customers</name>

<description>MSA Sample Project</description>

<properties>

<java.version>1.8</java.version>

<org.egovframe.rte.version>4.0.0</org.egovframe.rte.version>

<spring.cloud.version>2.2.5.RELEASE</spring.cloud.version>

</properties>

<repositories>

<repository>

<id>mvn2s</id>

<url>https://repo1.maven.org/maven2/</url>

<releases>

<enabled>true</enabled>

</releases>

<snapshots>

<enabled>true</enabled>

</snapshots>

</repository>

<repository>

<id>egovframe</id>

<url>http://maven.egovframe.go.kr/maven/</url>

<releases>

<enabled>true</enabled>

</releases>

<snapshots>

<enabled>false</enabled>

</snapshots>

</repository>

</repositories>

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter</artifactId>

<exclusions>

<exclusion>

(33)

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-logging</artifactId>

</exclusion>

</exclusions>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

<exclusions>

<exclusion>

<groupId>org.junit.vintage</groupId>

<artifactId>junit-vintage-engine</artifactId>

</exclusion>

</exclusions>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-web</artifactId>

</dependency>

<!-- 표준프레임워크 실행환경 -->

<dependency>

<groupId>org.egovframe.rte</groupId>

<artifactId>org.egovframe.rte.fdl.cmmn</artifactId>

<version>${org.egovframe.rte.version}</version>

</dependency>

<dependency>

<groupId>org.egovframe.rte</groupId>

<artifactId>org.egovframe.rte.ptl.mvc</artifactId>

<version>${org.egovframe.rte.version}</version>

</dependency>

</dependencies>

<build>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

</plugin>

</plugins>

</build>

</project>

4.1.2.4 애플리케이션 설정 파일 생성

스프링 부트 및 프레임워크의 의존성(dependency)를 추가하였으면, 애플리케이션의 설정을 위한 application.properties 파일을 생성한다. application.yml 파일은

src/main/resources 디렉터리에 위치하며, yml(yaml) 파일 대신 properties 형태의 파일을 사용할 수도 있다.

application.yml 파일 소스 내용

Customers 서비스의 이름과 contextPath 및 접속 포트를 설정한다.

server:

(34)

port: 8082

spring:

application:

name: customer

4.1.2.5 각 클래스 파일 작성

MSA 애플리케이션의 구조 파일들을 모두 작성하였으면, 다음으로 실제 로직을 담고 있는 각각의 클래스 파일들을 작성한다.

4.1.2.5.1 CustomersApplication.java 파일 작성

package egovframework.msa.sample;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.annotation.ComponentScan;

@ComponentScan("egovframework.*")

@SpringBootApplication

public class CustomersApplication {

public static void main(String[] args) {

SpringApplication.run(CustomersApplication.class, args);

} }

4.1.2.5.2 CustomerController.java 파일 작성

package egovframework.msa.sample.controller;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

@RestController

@RequestMapping("/customers") public class CustomerController { @GetMapping("/{customerId}")

public String getCustomerDetail(@PathVariable String customerId) { System.out.println("request customerId :" + customerId);

return "[Customer id = " + customerId + " at " + System.currentTimeMillis() + "]";

} }

(35)

4.1.2.6 Customers 서비스 구동 및 테스트

Customers 의 CustomersApplcation.java 파일을 java application 으로 실행하면, 아래와 같이 Spring boot 를 통하여 embedded tomcat 으로 구동되는 것을 확인할 수 있다.

. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/

:: Spring Boot :: (v2.3.4.RELEASE)

2020-10-19 16:16:04.188 INFO 50318 --- [ main] e.msa.sample.CustomersApplication : Starting CustomersApplication on jeonghunhuiui-iMac.local with PID 50318

(/Users/EGOV3.9/workspace/Customers/target/classes started by hhjeong in /Users/EGOV3.9/workspace/Customers)

2020-10-19 16:16:04.190 INFO 50318 --- [ main] e.msa.sample.CustomersApplication : No active profile set, falling back to default profiles: default

2020-10-19 16:16:04.865 INFO 50318 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8082 (http)

2020-10-19 16:16:04.873 INFO 50318 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]

2020-10-19 16:16:04.873 INFO 50318 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.38]

2020-10-19 16:16:04.937 INFO 50318 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/]

: Initializing Spring embedded WebApplicationContext 2020-10-19 16:16:04.937 INFO 50318 --- [ main]

w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 713 ms

2020-10-19 16:16:05.077 INFO 50318 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'

2020-10-19 16:16:05.205 INFO 50318 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8082 (http) with context path ''

2020-10-19 16:16:05.213 INFO 50318 --- [ main] e.msa.sample.CustomersApplication : Started CustomersApplication in 1.532 seconds (JVM running for 1.782)

2020-10-19 16:16:10.795 INFO 50318 --- [nio-8082-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]

: Initializing Spring DispatcherServlet 'dispatcherServlet'

2020-10-19 16:16:10.796 INFO 50318 --- [nio-8082-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'

2020-10-19 16:16:10.799 INFO 50318 --- [nio-8082-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 3 ms

202x-0x-xx 22:49:26.150 INFO 10020 --- [nio-8080-exec- 1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet' 202x-0x-xx 22:49:26.157 INFO 10020 --- [nio-8080-exec-1]

o.s.web.servlet.DispatcherServlet : Completed initialization in 6 ms

그럼, 웹 브라우저를 실행하고 아래와 같이 URL 을 입력하면 customerid 가 1234 인 내용을 확인할 수 있다.

URL : http://localhost:8082/customers/1234

(36)

4.1.3 Catalogs & Customers 서비스 연동 및 테스트

각각의 서비스들의 구현 및 테스트가 끝났다면, 다음으로 두 서비스를 연동하도록 하겠다. Customer 서비스는 서비스가 호출되는 서비스로서 별도의 변경내용은 없다.

그러나 Catalogs 에서는 Customer 서비스를 호출하기 위하여 별도의 RestTemplate 을 적용하여 서비스를 호출하도록 변경한다.

4.1.3.1 Catalogs 에 RestTempate 적용

서비스를 호출하여 JSON 형태의 결과를 받기 위하여 스프링에서 제공하는 RestTemplate 을 Catalogs 서비스에 아래와 같이 변경한다.

1.

CatalogsApplication.java 파일 수정

(하이라이트된 영역이 수정사항)

package egovframework.msa.sample;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.ComponentScan;

import org.springframework.web.client.RestTemplate;

@ComponentScan("egovframework.*")

@SpringBootApplication

public class CatalogsApplication { @Bean

public RestTemplate restTemplate() { return new RestTemplate();

}

public static void main(String[] args) {

SpringApplication.run(CatalogsApplication.class);

} }

2. CustomerApiServiceImpl.java 파일 수정 (하이라이트된 영역이 수정사항)

package egovframework.msa.sample.serviceImpl;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.web.client.RestTemplate;

참조

관련 문서

이번 조사를 통해서 확인되었듯이 기업은 2019년도 클라우드 활성화 핵심 계획으로 클라 우드 관리의 효율성을 높이고 클라우드 전문인력의 확보를 계획했을 뿐만

VMware Cloud SDDC and Hybrid

또한, 본 문서에서는 Master cluster의 URL은 cluster.rhkoso36.com을 사용하며, OpenShift Origin PaaS 에서 생성되는 Docker container 의 도메인 서비스를

멀티 팀, 멀티 클라우드 상의 쿠버네티스 인프라와 모던 애플리케이션을 일관되게 운영하기 위한 통합 관리 플랫폼. 개발자가

•Oracle 클라우드 확장 지원 (베어메탈, 클라우드 서비스등 다양한 인프라 제공). •Oracle 플랫폼에 따라서 DB 서버 또는 Storage서버의

• Stylebook 템플릿을 통해 하이브리드 멀티 클라우드 환경 전반에서 일관된 보안 정책 달성.. Citrix

• 클라우드 기반의 통합 관리 솔루션인 Pure1 을 통해 전체 스냅샷의 카탈로그 관리 제공. • 클라우드로 전송 시, 퓨어스토리지의 Cloud Block Store와의

Config Connector Kubernetes를 통해 Google Cloud 리소스를 관리할 수 있는 Kubernetes 부가기능.. It’s running on GCP