본문 바로가기
MSA/마스터링 스프링 클라우드

마스터링 스프링 클라우드 chap.2

by devwari 2019. 1. 21.

02_마이크로서비스를 위한 스프링

이번 장에서 다룰 주제는 다음과 같다.
  • 프로젝트에 부가적인 기능을 활성화하기 위한 스타터(starter) 사용하기
  • REST API 메소드를 노출하는 서비스를 구현하기 위한 스프링 웹 라이브러리 사용하기
  • 속성과 YAML 파일을 활용해 서비스 컨피규레이션 사용자 정의하기
  • 상태 점검 및 모니터링 기능 구성하기
  • 애플리케이션이 다른 모드에서 동작하도록 스프링 부트 프로파일 사용하기
  • 내장되거나 원격의 NoSQL 데이터베이스와 상호작용하기 위해 ORM 기능 사용하기

1. 스프링 부트 소개

  • 스프링 부트는 독립 실행형 애플리케이션을 java -jar 명령으로 실행
  • 스프링 부트가 표준 스프링 컨피규레이션과 비교해 간단한 이유
    1. 스타터

      • 프로젝트 의존성에 포함될 수 있는 아티팩트(artifact)

        1. 아티팩트란? https://www.lesstif.com/pages/viewpage.action?pageId=18219542

      • 기대하는 기능을 구현하기 위해 애플리케이션에 포함해야하는 다른 의존성을 제공하는 역할

      • 스타터 방식으로 제공된 패키지는 즉시 사용할 수 있어 동작을 위해 별도의 설정을 할 필요가 없음

      • 공식 명명 패턴은 spring-boot-starter-*

      •  이름

         설명

         spring-boot-starter

         자동 컨피규레이션 지원, 로깅, YAML을 포함하는 핵심 스타터

         spring-boot-starter-web

         RESTful과 스프링 MVC를 포함하는 웹 애플리케이션 개발

         톰캣(Tomcat)을 기본 컨테이너로 내장

         spring-boot-starter-jetty

         기본 내장 서블릿 컨테이너로 제티(Jetty)를 프로젝트에 포함

         spring-boot-starter-undertow

         기본 내장 서블릿 컨테이너로 언더토우(undertow)를 프로젝트에 포함

         spring-boot-starter-tomcat

         내장 서블릿 컨테이너로 톰캣을 프로젝트에 포함

         spring-boot-starter-web에 사용되는 기본 서블릿 컨테이너

         spring-boot-starter-actuator

         애플리케이션 모니터링 및 관리 기능을 제공하는 스프링 부트 액추에이터 프로젝트를 포함

         spring-boot-starter-jdbc

         Tomcat Connection pool을 포함하는 스프링 JDBC를 포함

         특정 데이터베이스의 드라이버는 직접 제공해야 함

         spring-boot-starter-data-jpa

         JPA 또는 Hibernate를 이용해 관계형 데이터베이스에 상호작용하기 위해 필요한 모든 아티   팩트를 포함

         spring-boot-starter-data-mongodb

         몽고디비와 상호작용하고 로컬 호스트의 몽고에 대한 클라이언트 연결을 초기화하기 위한 모든 아티팩트를 포함

         spring-boot-starter-security 프로젝트에 스프링 시큐리티를 포함하고 애플리케이션에 기본 시큐리티를 활성화
         spring-boot-starter-test

         JUnit, 햄크레스트(Hamcrest), 모키토(Mockito)와 같은 라이브러리를 활용한 단위 테스트의  생성을 허가

         spring-boot-starter-amqp

         스프링 AMQP를 프로젝트에 추가하고 기본 AMQP 브로커로서 래빗엠큐를 시작

    2. 자동 컨피규레이션(auto-configuration)

      • 스타터에 포함된 아티팩트는 기본 설정이 있고 속성이나 다른 유형의 스타터로 쉽게 재정의할 수 있음
      • 예를 들어 spring-boot-starter-web을 포함하면 애플리케이션의 기본 웹 컨테이너(톰캣)를 내장해 기본 포트(8080)로 시작
      • 포트는 애플리케이션 속성 파일에 지정된 필드를 선언해 쉽게 변경할 수 있고 spring-boot-starter-jetty 또는 spring-boot-starter-undertow를 프로젝트 의존성에 포함해 웹 컨테이너 변경 가능
  • 표준 스프링 컨피규레이션과 스프링 부트의 차이점
    1. 표준 스프링 컨피규레이션은 애플리케이션을 WAR 형태로 웹 컨테이너에 배포
    2. 스프링 부트는 애플리케이션에 웹 컨테이너를 포함
  • 위의 차이점이 스프링 부트가 마이크로서비스 아키텍처에 배포된 애플리케이션을 생성하는 데 사용되는 가장 중요한 이유중 하나임
  • 마이크로서비스의 가장 대표적인 기능 중 하나는 다른 마이크로서비스와의 독립성임
    1. 데이터베이스나 웹 컨테이너와 같은 공통 자원을 공유하지 않아야 함
    2. 하나의 웹 컨테이너에 여러 WAR 파일을 배포하는 것은 마이크로서비스에서 피해야 할 패턴
      • 마이크로서비스의 경우 스프링 부트가 명백히 옳은 선택
  • 자바 프레임워크의 인기를 보여주는 다이어그램


2. 스프링 부트를 이용해 애플케이션 개발하기

  • 메이븐(Maven)과 그래들(Gradle)을 활용해 의존성을 관리할 수 있음

  • 그래들의 경우, 부모 의존성을 정의할 필요가 없음

  • 메이븐을 사용하는 경우,  spring-boot-starter-parent POM에서 상속받지 않고 의존성 관리시스템 사용 가능

  • @SpringBootApplication = @Configuration + @EnableAutoConfiguration + @ComponentScan

  • 개발 IDE의 경우 메인 클래스 실행, 그렇지 않다면 애플리케이션 빌드 후 표준 자바 애플리케이션처럼 java -jar 명령어로 실행

  • pom.xml에 정의한 spring-boot-maven-plugin은 애플리케이션을 빌드하는 동안 모든 의존성을 실행 가능한 JAR(종종 팻(fat) JARs라고 부름)에 포함하는 일을 담당하는 컨피규레이션을 제공함


3. 컨피규레이션 파일 사용자 정의하기

  • 많은 작업 없이 애플리케이션을 빠르게 생성하는 것뿐 아니라 기본 설정을 쉽게 재정의하거나 무시하는 것도 중요한 역량

  • 스프링 부트는 애플리케이션 JAR에 추가된 컨피규레이션 파일을 이용해 편리하게 설정을 관리할 수 있는 메커니즘 제공

  • 스프링 부트는 application으로 시작하는 컨피규레이션 파일을 자동으로 찾음

  • .properties와 .yml 타입 지원

  • applicaiton-prod.properties  또는 application-dev.yml처럼 특정 프로파일을 지정하는 설정 파일 생성 가능

  • 운영체제 환경변수와 커맨드라인 입력값을 사용해 컨피규레이션을 외부 추출 가능

  • .properties와 .yml 파일 위치

    1. 애플리케이션의 현재 디렉터리의 /config 하위 디렉터리

    2. 애플리케이션의 현재 디렉터리

    3. 클래스 경로 /config 패키지(ex. JAR 내부)

    4. 클래스 경로 root

  • 설정 파일명으로 application 또는 application-{profile} 이외의 특정한 이름을 부여하려면 애플리케이션이 시작할 때 spring.config.name 환경변수를 제공해야함

  • spring.config.location 설정에 콤마로 분리된 설정 디렉토리 경로와 컨피규레이션 파일 경로 목록을 설정할 수 있음

  • 컨피규레이션 파일 내부에 두 종류의 설정 지정 가능

    1. 하위 클래스(주로 spring-boot-autoconfiguration 라이브러리)에서 사용되는 공통 설정, 미리 정의된 스프링 부트 설정의 그룹이 있음

      • 외부 컨피규레이션 파일을 지정할 필요가 없음 ex) 로깅 컨피규레이션을 위해 log4j.xml 또는 logback.xml 등을 설정할 필요 없음

    2. 자신만의 컨피규레이션 속성을 지정하면 @Value 또는 @ConfigurationProperties 애노테이션을 통해 애플리케이션에 주입됨

      • 사용자 정의 컨피규레이션도 같은 properties 파일 또는 YAML 파일에 위치해야함


4. RESTful 웹서비스 생성하기

  • JSON 메시지를 직렬화하고 역직렬화하는 잭슨(Jackson) 라이브러리는 spring-boot-starter-web과 함께 자동으로 클래스 경로에 포함됨

  • 스프링 웹은 RESTful 웹서비스를 생성하기 위한 몇 가지 애노테이션 제공

    1. @RestController: 유입되는 HTTP 요청을 처리하는 컨트롤러 빈(controller bean) 클래스에 설정

    2. @RequestMapping: 컨트롤러 메소드와 HTTP를 대응하는 데 주로 사용

    3. @GetMapping, @PostMapping, @PutMapping, @DeleteMapping: 특정 HTTP 메소드를 지정하는 애노테이션으로 @GetMapping = @RequsetMapping(method=RequestMethod.GET)

    4. @RequestParam: 요청의 경로와 입력값을 Object로 바인딩

    5. @RequsetBody: 입력 JSON을 잭슨 라이브러리를 사용해 Object로 바인딩

  • REST는 SOAP 처럼 모든 서비스의 정의가 기술된 WSDL(Web Service Description Language) 파일을 클라이언트에게 제공할 수 있는 표준 표기법이 없음
    1. SOAP(Simple Object Access Protocol)이란? https://ko.wikipedia.org/wiki/SOAP
  • 클라이언트가 API를 호출하도록 하는 두 가지 방법
    1. API 사용법을 설명한 문서 제공
    2. API 클라이언트를 자동으로 생성하는 메커니즘 제공


5. API 문서화

  • 스웨거(Swagger)는 RESTful API를 설계하고 빌드하고 문서화나는데 가장 많이 사용되는 도구

  • 스마트베어(SmartBear)가 만들었는데, 이 디자인 회사는 SOAP 웹서비스와 SoapUI를 위한 인기 있는 도구를 제공

  • 스웨거는 API 사용법을 설명한 문서를 제공하거나 API 클라이언트를 자동으로 생성하는 메커니즘을 제공함

  • 스웨거를 통해 표기법을 활용한 API를 설계하고 소스코드를 생성하거나 소스코드로 시작해 스웨거 파일을 생성하는 방법이 있는데 스프링 부트는 두 번째 방식 선택함


6. 스웨거 2를 스프링 부트와 같이 사용하기

  • 스프링 부트와 스웨거 2의 통합은 스프링폭스(Springfox) 프로젝트에서 구현됨

  • 애플리케이션이 실행될 때 스프링 컨피규레이션, 클래스 구조, 자바 애노테이션 기반으로 API의 의미를 추론함

  • 스프링과 함께 스웨거를 사용하려면 다음의 의존성 두 개를 메이븐 pom.xml에 추가하고 @EnableSwagger2 애노테이션을 추가함

  • 애플리케이션이 시작될 때 스웨거 라이브러리에 의해 API 문서가 소스코드로부터 자동으로 생성됨

  • 메인 클래스에 선언된 Docket 빈에 의해 조절됨

  • 메이븐의 pom.xml로부터 API의 버전을 얻는 것은 좋은 방법으로 maven-model 라이브러리를 클래스 경로에 추가하고 MavenXpp3Reader 클래스를 이용해 얻을 수 있음

  • 기본적으로 스웨거는 스프링 부트에 의해 상성되는 정보를 포함한 모든 REST 서비스에 대해 문서를 생성함. 특정 패키지를 국한할 수 있음


7. 스웨거 UI를 통한 API 테스트

  • 애플리케이션이 시작된 후 API 문서 대시보드는 http://localhost:{port}/swagger-ui.html에 제공됨

  • 사용자 중심의 스웨거 JSON 정의 파일도 자동으로 생성돼 http://localhost:{port}/v2/api-docs의 경로에서 제공됨.  해당 파일은 SoapUI 같은 다른 REST 도구에 임포트할 수 있음

  • 모든 오퍼레이션은 요구하는 입력값이나 JSON 입력을 제공하고 Try it out!을 클릭해 테스트할 수 있음

  • Swagger vs Spring Rest Docs: https://devwari.tistory.com/3


8. 스프링 부트 액추에이터의 기능

  • 하나의 관리되는 환경을 구성하는 수많은 독립적인 엔티티가 존재하는 마이크로서비스에서 애플리케이션의 모니터링과 메트릭 수집은 중요함

  • 메트릭과 상태 점검, 애플리케이션 로그의 품질과 같은 프리즘을 통해 애플리케이션을 바라보는 것도 중요함

  • 스프링 부트 액추에이터는 애플리케이션을 모니터링하고 상호작용하기 위한 내장된 수많은 종단점을 제공

  • spring-boot-starter-actuator 의존성 추가하여 사용

  •  경로

     설명

     /beans

     애플리케이션에 초기화된 모든 스프링 빈의 목록을 표시

     /env

     스프링의 설정 가능한 환경 속성 목록을 표시. ex) OS 환경 변수 및 컨피규레이션 파일의 속성 목록 

     /health

     애플리케이션의 상태 정보 표시 

     /info

     애플리케이션의 임의 정보 표시. ex) build-info.properties나 git.properties 파일의 정보 표시 

     /loggers 

     애플리케이션의 로거 컨피규레이션 정보를 표시하고 수정 

     /metrics 

     애플리케이션의 메트릭 정보를 표시 ex) 메모리 사용량, 실행 중인 스레두 수, REST 메서드의 응답 시간 

     /trace 

     트레이스(trace) 정보 표시(기본으로 마지막 100개의 HTTP 요청)


  • Spring Boot 2.0에서 actuator에서 기본적으로 제공하는것은 /health와 /info임
  • 종단점은 스프링 컨피규레이션 속성을 사용해 쉽게 사용자 정의 가능. 프로젝트에서 모든 종단점의 보안을 활성화 하려면 application.yml에 다음 구문을 추가하면 됨 (참고: https://aboullaite.me/actuator-in-spring-boot-2-0/)


9. 애플리케이션 정보 - /info

  • 프로젝트에서 사용 가능한 모든 API 목록은 애플리케이션을 시작할 때 로그에 나타남

  • 보안을 해제한 후 웹브라우저에서 목록 확인 가능

  • /info API는 기본적으로 어떤 정보도 노출하지 않음. 이를 변경하려면 InfoContributor 빈을 변경하거나 자신만의 빈을 작성해야함


10. 상태 정보 - /health

  • /info API 처럼 /health API도 자동으로 설정되는 것이 있음

  • 디스크의 사용량, 메일 서비스, JMS, 데이터 소스, 몽고디비 또는 카산드라와 같은 NoSQL 모니터링 가능


11. 매트릭스 - /metrics

  • 자동으로 설정되는 /metrics 액추에이터 API를 통해 마이크로서비스의 힙(heap)과 힙이 아닌 메모리의 사용량 알 수 있음

  • 로딩된 클래스의 개수. 활성화된 스레드의 수, API 메서드의 평균 실행 시간 등 많은 정보를 보여줌

  • 자신만의 메트릭을 생성해야 할 경우를 대비해 스프링 부트 액추에이터는 CounterService(값의 증가와 감소, 초기화를 위한 메소드 제공)와 GuageService(단순히 현재 값을 전달)라는 두 클래스 제공

  • 호출 경로에만 근거 하기 때문에 통계 정보를 호출하는 API 메서드를 위한 기본 메트릭은 약간 불완전함

  • 스프링 부트 애플리케이션에 의해 생성되는 모든 메트릭은 분석하거나 표시할 수 있는 저장소로 전달 가능. 이런 정보는 레디스(Redis), Open TSDB, Statsd, 인플럭스디비(InfluxDB) 등에 저장할 수 있음

12. 개발자 도구

  • 스프링 부트의 spring-boot-devtools는 프로젝트의 클래스 경로상의 파일이 변경되면 애플리케이션이 변경을 감지하여 자동으로 재시작하는 기능을 제공. 변경 시 애플리케이션이 재시작하지 않도록 하려면 그러한 리소스를 제외 항목에 포함하면 됨.


13. 요약
  • 스프링 부트의 기능 및 설정 방법

    1. 프로젝트에서 스타터를 사용해 추가 기능을 활성화하는 방법

    2. 스프링 웹 라이브를 이용해 REST API 메서드를 노출하는 서비스를 구현하는 방법

    3. 속성과 YAML 파일을 이용해 서비스의 컨피규레이션을 사용자 정의하는 방법

    4. REST API를 문서로 만들고 명세를 제공하는 방법

    5. 상태 점검 및 모니터링 기능 설정

    6. 스프링 부트 프로파일을 통해 애플리케이션이 다른 모드에서 실행 가능하도록 설정

    7. ORM 기능으로 내장 및 원격의 NoSQL 데이터베이스와 연동

  • 스프링 부트에 대한 지식과 경험이 없으면 스프링 클라우드 프로잭트를 시작할 수 없음

  • 스프링 클라우드는 완전한 마이크로서비스 기반 생태계에 서비스를 배치할 수 있는 다양한 기능 제공