IT/개발

[Spring] Spring Cloud 개념 및 핵심 컴포넌트

Terriermon 2021. 10. 1. 23:33

Spring Cloud

https://happycloud-lee.tistory.com/207

Spring Cloud가 적용된 이상적인 마이크로서비스 환경

- MSA의 개발, 배포, 운영에 필요한 아키텍처를 쉽게 구성할 수 있도록 지원하는 Spring Boot 기반 프레임워크

- 분산 시스템 상에 필요한 여러 패턴들을 표준 패턴화 시켜 손쉽게 개발 할 수 있도록 지원

component

🔴중요 컴포넌트 : Spring Cloud Netfix의 Zull, Eureka, hystrix, ribbon EOS, Spring Config

 

 

Spring Config

Spring Cloud Config 서버를 사용하여 Spring Boot Application의 환경설정 파일을 한 곳에 저장, 해당 서버에 접근하여 환경 설정 정보를 가져옴

장점

- 모든 Application의 환경 설정 정보를 한 곳에서 관리

- 환경 설정이 변경되어도 전체를 다시 빌드하지 않아도 됨

 

 

hystrix

https://sabarada.tistory.com/52

Software 기반 Circuit Breaker, 장애 상황을 견딜 수 있도록 해주는 Spring Cloud component

Circuit Breaker
MSA에서 특정 MSA 서비스 장애로 인해 다른 MSA 서비스에도 장애를 일으킬 수 있는 가능성을 방지하는 것

특징

- 다른 서비스 실패에 따른 서비스 지연 또는 실패 방지

- 분산 시스템의 복잡한 연쇄 실패 방지

- 빠르게 실패하고 빠르게 복구

- Fallback과 Gracefully degrade(완벽한 마무리)

- real-time에 유사한 모니터링과 알람

 

기능

- Container(Tomcat 등)의 thread 직접 사용X

- Queue로 대기열을 사용하지 않고 빠르게 실패

- 실패로부터 서비스 보호 ▶️ fallback 제공

- Thread timeout, 장애 등을 설정해 장해 시 정해진 루트를 진행

- 미리 정해진 임계치를 넘으면 장애가 있는 로직을 실행하지 않고 우회

 

적용방법

1. build.gradle 파일의 dependencies에 모듈 추가

dependencies{
    ...
    implementation('org.springframework.cloud:spring-cloud-starter-netflix-hystrix')
    ...
}

 

2. main이 있는 Application Class에 @EnableCircuitBreaker Annotation 추가

@EnableCircuitBreaker
public class ExampleApplication{
    public static void main(String[] args){
        SpringApplication.run(ExampleApplication.class, args);
    }
}

 

3. Circuit Break를 사용할 Method에 @HystrixCommand Annotation 추가

//commandKey: 상세 제어, 필수 속성X
//fallbackMethod: 실패 시 실행되는 로직 함수
@HystrixCommand(commandKey = "commandKeyExample", fallbackMethod = "fallbackMethodExample")
public String hystirxExample(){
    ...
}

// 실패 시 실행되는 로직
//@HystrixCommand의 fallbackMethod와 이름이 같아야 실행
public String fallbackMethodExample(){
    return "hystrixExample Error"
}

 

4. (필수X) application.yml에 commandKey 제어 추가

hystirx:
    command:
        commandKeyExample:
            execution:
                isolation:
                    thread:
                        timeoutlnMilliseconds: 10000

- @HystrixProperty도 사용 가능

 

 

Ribbon Client

https://supawer0728.github.io/2018/03/11/Spring-Cloud-Ribbon-And-Eureka/

- Netfix OSS 라이브러리

- 클아이언트 측 로드밸런서

- Load Balancer를 대신해 L7 Layer에서 Client Side Load Balacer 역할을 담당

  > 여러 서버를 라운드로빈 방식의 부하 분산 기능 제공

- RestTemplate 대신 FeignClient를 사용하여 Riboon 기능 사용

 

장점

- REST API를 호출하는 서비스에 탑제되는 SW 모듈

- 매우 다양한 설정 가능(ex. 서버 선택, 실패시 Skip 시간, Ping 체크 등)

- Retry 기능 내장

- Eureka와 사용 시 매우 강력

 

단점

- 새로운 서버가 추가되고 제거되는 것이 재빌드/배포 필요 -> 무중단 적용 시 Eureka와 함께 사용

 

적용방법

1. build.gradle 파일에 dependencies 추가

dependencies{
    implementation('org.springframework.cloud:spring-cloud-starter-ribbon')
}

 

2. application.yml에 로드밸런싱 할 서버 추가

xample:
    ribbon:
        listOfServer:
            - localhost:8081
            - localhost:8082

 

3. @LoadBalance annotaiton 추가

@LoadBalanced
public RestTemplate RestTemplate(){
    return new RestTemplate;
}

 

4. url

String url = "http://example/exampelapi";

 

 

Eureka

 

- 동적 서비스 등록, 발견

- MSA의 서비스들의 목록과 위치(IP, Port)가 동적으로 변화는 환경에서 서비스들을 효율적으로 관리하기 위한 Service Discovery Server/Client

- 서버 개수 동적 조절

 

등록

 

등록

> eureka-server: 자기 자신을 등록(Service Registration)하는 서버, Eureka Clientrㅏ 가용한 서비스 목록(Service Registry)를 요청하는 서버

> eureka client: 서비스들의 위치 정보를 Eureka Server로부터 fetch하는 서비스

  • 서비스 제공자 관점 프로세스
  • 새로운 서비스 시작 시 중앙 서비스 레지스트리에 등록
  • 장애 발생 시, 서비스 레지스트리 제외
  • 레지스트리는 항상 최신 정보

 

발견

발견

  • 사용자 관점 프로세스
  • 사용자가 서비스 레지스트리에 필요한 서비스를 찾아서 호출
  • URL을 정적으로 관리하는 대신 서비스 레지스트리를 통해 사용 가능한 URL 발견 가능

 

적용방법

1. build.gradle에 dependencies 추가

dependencies{
    //server
    complie('org.springframework.cloud:spring-cloud-starter-netflix-eureka-server')
    //client
    complie('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')   
}

 

2. application.yml에 설정

* Ribbon 설정이 있으면 삭제 필요

- server

server:
    port: 8761 #default port

spring:
    application:
        name: eureka-server
eureka:
    server:
        enableSelfPreservation: false #개발모드

    client:
        register-with-eureka: false #개발모드
        fetch-registry: false
        service-url:
            defaultZone: http://localhost:8761/eureka

- client

spring:
    application:
        name: eureka-client
eureka:
    client:
        service-url:
            defaultZone: http://127.0.0.0.1:8761/eureka #eureka server

 

 

3. main이 있는 Application Class에 @EnableEurekaServer Annotation 추가

@EnableEurekaServer
public class ExampleApplication{
    public static void main(String[] args){
        SpringApplication.run(ExampleApplication.class, args);
    }
}

 

 

Spring Gateway

https://lteawoo.tistory.com/29

- Spring Reactive 생테계에 구현된 API Gateway

- Gateway Handler Mapping으로 들어오는 요청들을 적절한 대상으로 라우팅

API Gateway
MSA의 각 서비스들의 IP와 Port 번호에 대한 단일화된 엔드포인트를 제공
인증, 모니터링, 오케스트레이션, 사용량  제어, 요청/응답 등의 기능을 포함한 향상된 Reverse Proxy

 

작동 방식

- 논블로킹, 비동기 방식으로 Netty Server 사용  ▶️ 서블릿 컨테이너나 WAR로 빌드 시 동작X

- 3가지 핵심 단위

  1. Route: 대상 URI, 조건부 집합(Predicates), 각종 필터들로 이루어진 요청 ▶️ 라우팅 대상
  2. Predicate: 라우팅에 필요한 조건, request header의 특정 키-값을 조건으로 사용 가능
  3. Filter: 요청 전후로 요청/응답을 추가/수정할 수 있음

기능

- Service Request 라우팅

- Service Load Balancing

- Service Request에 대한 Endpoint 단일화

- Service Mesh와 연계 ▶️ 장애 대응

- Service Fitering

- 인증, 모니터링 등

 

적용방법

1. build.gradle에 dependencies 추가

dependencies{
    implementation('org.springframework.cloud:spring-cloud-starter-gateway')
    //eureka-client 추가
}

 

2. apllication.yml에 설정 추가

spring:
    application:
        name: example-gateway
    cloud:
        gateway:
            #cors 설정
            globalcors:
                cors-configurations:
                '[/**]':
                    allow-credentials: true
            # Gateway 공통 필터
            default-filters:
                - name: GlobalFilter
                  args:
                       baseMessage: Spring Cloud Gateway GlobalFilter
                       preLogger: true
                       postLogger: true
            # MSA 라우팅 정의
            # ID, 목적지(uri), 조건(Predicate), 필터로 구성된다.
            routes:
                - id: user-service
                uri: http://localhost:8081 #목적지
                predicates:
                - Path=/example/**

 

'IT > 개발' 카테고리의 다른 글

[Spring] Spring Data JPA 사용 방법  (0) 2021.10.29
[Spring] JPA란  (0) 2021.10.29
[SpringBoot] Transaction 사용하기  (0) 2021.09.24
[SpringBoot] MyBatis 간단 기초  (0) 2021.09.22
[SpringBoot] 백엔드에서 Form 데이터 받기  (0) 2021.09.21