[MSA] Spring Cloud ( Config, actuator refresh )

이민우·2024년 1월 4일
1

Spring Boot

목록 보기
18/20
post-thumbnail

참고 : Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)

Spring Cloud Config

  • 분산 시스템에서 서버, 클라이언트 구성에 필요한 설정 정보(application.yml)를 외부 시스템에서 관리
  • 하나의 중앙화 된 저장소에서 구성요소 관리 가능
  • 각 서비스를 다시 빌드하지 않고, 바로 적용 가능
  • 어플리케이션 배포 파이프라인을 통해 DEV-UAT-PROD 환경에 맞는 구성 정보 사용

Local 저장소, Git저장소 등에서 관리를 할 수 있다.

우선 Spring Cloud Config 프로젝트를 생성보자!

프로젝트를 생성후 아래 dependency를 추가해주자!

      <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>

메인 클래스에 @EnableConfigServer를 등록해준다.

  • application.yml 파일 (포트번호 8888)
server:
  port: 8888

spring:
  application:
    name: config-service
  profiles:
    active: native
  cloud:
    config:
      server:
        native:
          search-locations: file:///Users/imin-u/study/native-file-repo
        git:
          uri: https://github.com/LminWoo99/SpringCloudConfig.git

여기서 local 저장소를 사용할 것인지 git저장소를 사용할 것인지 등을 설정 할 수 있다.

profiles.active: 를 통해 지정 할 수 있으며

이번 예제로는 local 저장소를 사용할 것이다.

active : native로 해주면 local저장소로 사용할 수 있다. 설정 정보가 들어있는 폴더의 위치를 작성해준다.

(default 로 하면 git 설정이 사용됨)

설정파일을 임의로 일단 만들어보자(위에 yml파일에서 등록하 파일 경로에 설정파일이 위치해야한다!)

이제 config-service를 실행해고 해당 주소로 접속해보자.

localhost:8888/application/default

localhost:8888/[yml 파일 이름]/default

다른 yml파일이름을 넣어도 설정파일을 확인 할 수 있다!

이제 각각의 마이크로서비스에(apigateway, user, order, catalog) configuration 정보를 읽어오기 위해 추가해보자

모든 서비스에 해당 디펜던시를 작성해준다.

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>

또한 각 서비스에 application이 위치한 같은 경로에 bootstrap.yml파일을 추가해준다.

이는 application.yml파일보다 우선순위가 높은 설정파일이 생긴다.

여기에 읽어오고자 하는 config 정보를 등록한다.

spring:
  cloud:
    config:
      uri: http://127.0.0.1:8888
      name: config-service

uri 에는 config 서버의 주소

name 에는 설정파일로 지정하고싶은 파일의 이름을 작성하면된다. 즉, 외부에 만들었던 ( test, application 등) yml파일의 이름을 넣어주면된다.

만약에 user-service.yml 파일을 따로만들어서 관리하고싶다면 user-service프로젝트에 이 yml파일의 이름을 등록하여 해당 설정 파일을 외부에서 변경하여 따로 프로젝트를 재시작하지 않고 값들을 변경할 수 있다.

bootstrap.yml파일을 사용하는 이유는 원레 application.yml파일에 있던 정보를 빼서 외부에서 관리하기위함이다. 때문에 application.yml파일보다 먼저 읽혀야 한다.

설정을 맞추고 테스트 해보자.(postman 이용)

user-service 의 health_check에서 해당 설정 값을 가져와보자.

  • UserController 코드

외부에 있는 설정파일의 값을 잘 가져오는 것을 확인할 수 있다!!

그러면 외부의 설정파일 값을 변경해보자!
바로 적용되는지 확인보도록 하자

yml의 파일에서 token secret 값을 변경 해보겠다.

우선 config-server에는 바꼈는지 확인해보자.

token secret이 #4로 바뀌었다.

하지만 마이크로서비스에서 불러오면 그대로 이다.

이를 바꾸기 위해서는 해당 서비스를 재실행 해야 한다.

바뀐 설정 정보를 적용하기 위해서는

  • 서비스 재기동

  • Actuator refresh

  • Spring cloud bus

이렇게 3가지가 있는데 서비스를 재기동하는 것은 그냥 값을 바꾸고 재기동하는 것과 다르지 않다. 때문에 이는 비효율적인 방법이다.

Actuator refresh

Actuator refresh 방법을 먼저 알아보자.

우선 config 서버와 연결해준 마이크로 서비스 즉, 아래와 같은 값을 추가해준 서비스에

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

actuator dependency를 추가해 주자!

또한 내부 application.yml파일에 아래와 같은 옵션(refresh, health, beans)을 설정을 감지하고자 하는 서비스에 추가해준다.

management:
  endpoints:
    web:
      exposure:
        include: health, refresh, beans

이제 작동하는지 확인해보자.

8761포트로 들어가서 user-service를 클릭해서 들어가면

eureka에 등록해 놓은 마이크로 서비스를 확인할 수 있다.
user-service의 health를 확인해보면

작동중인 것을 확인할 수 있다. 또한 beans를 확인하면 spring에 등록된 beans를 확인할 수 있다

우리는 설정 변경값을 적용해야 할려고 했으니

우선 기존값은 config test이다.

yml에 값을 바꾼다음에
postman을 통해 post방식으로 해당서비스의 주소로 refresh를 해주고 확인해보자!

서비스를 재실행 하지 않아도 값이 바뀐 것을 볼 수있다.

refresh는 api gateway를 통해서도 할 수 있다.

그런데 이를 위해서는 routes정보에 filters를 추가해줘야한다.

        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/user-service/login
            - Method=POST
          filters:
            - RemoveRequestHeader=Cookie
            - RewritePath=/user-service/(?<segment>. *) , /$\{segment}
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/user-service/users
            - Method=POST
          filters:
            - RemoveRequestHeader=Cookie
            - RewritePath=/user-service/(?<segment>. *) , /$\{segment}
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/user-service/**
            - Method=GET
          filters:
            - RemoveRequestHeader=Cookie
            - RewritePath=/user-service/(?<segment>. *) , /$\{segment}
            - AuthorizationHeaderFilter
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/user-service/actuator/**
            - Method=GET,POST
          filters:
            - RemoveRequestHeader=Cookie
            - RewritePath=/user-service/(?<segment>. *) , /$\{segment}

⭐️ 여기서 주목할점은 RewritePath이다

RewritePath쓰는 이유는 예를 들어 포트 번호가 60000이라 한다면
http://127.0.0.1:6000/user-service/health_check
처럼 마이크로 서비스를 인식해주는 식별자로서 "user-service"라는 prefix가 필요했다.
그런데 마이크로서비스 입장에서는 "user-service"라는 prefix는 redundant하다.
서두의 주소를 나타내는 uri에서 이미 해당하는 마이크로서비스의 주소를 나타내고 있기 때문에
http://127.0.0.1/60000/login 만으로도 충분한 의미전달이 되기 때문이다.

그런데 기존의 방식으로 gateway에서 호출시엔
http://127.0.0.1/60000/user-service/ -> 이후 추가 uri 탐색
으로 진행이 되기 때문에 user-service가 필요했었는데
filter의 rewrite 문법을 통해 이를 지워주었고, 결과적으로 uri의 불필요한 중복을 제거할 수 있다.

RewritePath를 작성하면 api gateway를 통해 refresh또한 할 수있다.

재부팅 하지않고 설정정보를 적용시키는 방법을 알아봤다. 하지만 Actuator refresh는 어플리케이션 서버가 한두개면 문제가 되지 않지만 수백개의 서비스가 있을경우 각각의 어플리케이션마다 다 refresh를 수동으로 해줘야 하기 때문에 번거롭다. 이를 해결 하기 위해 Spring Cloud Bus를 사용할 수 있다. 다음 포스팅에선 Spring Cloud Bus 알아보도록 하겠습니다

profile
백엔드 공부중입니다!

0개의 댓글

관련 채용 정보