Spring Cloud Gateway

반영환·2023년 7월 8일
0

springCloud

목록 보기
4/4
post-thumbnail

Spring Cloud Gateway

API Gateway?

API Gateway 는 마이크로 서비스별로 공통적으로 처리되는 로직에 대해서 하나의 포트에서 처리할 수 있도록 클라이언트와 서비스들 사이에 위치하는 Proxy Server이다.

클라이언트는 각 서비스에 요청을 보내는 것이 아니라 API Gateway에게 요청을 보내고, API Gateway는 서비스에게 설정에 따라 요청을 전달하고 응답을 받은 뒤 해당 내용을 다시 클라이언트에게 전달한다.

다시 말해서 MSA로 구성된 서비스에서의 단일 진입점 역할을 한다.

무엇을 할 수 있는가?

인증/인가 및 토큰 발급

각 서비스마다 인증/인가를 하는 로직을 넣는 것은 매우 비효율적이기에 모든 트래픽이 통과하는 API Gateway에서 처리할 수 있다.

또한 토큰 발급도 인증 서버를 두고 자격을 위임할 수 있다.

로드밸런싱

각 서비스에 트래픽을 전달할 때 설정을 통해 균등하게 전달할 수 있다.

메디에이션

메디에이션 기능 중 Message Exchange Pattern이 있는데, API Gateway를 사용하면 동기 호출을 비동기 호출로 바꿀 수 있다.

Spring Cloud Gateway ( SCG )

SCG 는 상용화된 API Gateway중 하나로 Route Predicate Filter 세가지 요소로 이루어져 있다.

Route

서비스 고유의 id를 통해 트래픽 전달 주소를 파악하며, 요청된 uri의 조건이 predicate와 일치하는지 확인 후 경로로 매칭시켜준다.

Predicate

API Gateway로 들어온 요청이 주어진 조건을 만족하는지 확인하는 구성요소이다. 하나 이상의 조건을 설정할 수 있으며 조건에 맞지 않으면 404 에러 응답을 반환한다.

Filter

API Gateway로 들어오는 요청에 대해 Filter를 적용해 선처리/후처리 작업을 할 수 있게 해준다.

이 기능으로 토큰검사 등을 진행할 수 있다.

실습

실습 환경은 spring cloud config server , eureka server 를 사용한다.

서비스 생성

스프링 부트 프로젝트를 생성해준다.

depencency

여기에 추가로 actuatorbootstrap 을 추가해준다.


dependencies {
	...
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap'
    ...
}

bootstrap.yml

config server 에서 해당 서비스의 설정 파일을 가져올 수 있는 설정 파일을 만든다

spring:
  cloud:
    config:
      uri: http://localhost:8888
      name: service-name
      profile: default

config server repository에 설정 파일 추가

config server 가 바라보고 있는 레포지토리에 우리 서비스의 설정 파일을 커밋 해준다.

이 설정 파일엔 유레카 서버에 서비스를 레지스트리 하는 코드도 포함된다.

# 같은 종류의 다양한 서비스가 컨테이너로 배포되는 상황을 위해 포트는 랜덤 설정
server:
  port: 0

spring:
  application:
    name: service-name

# 유레카 레지스트리 코드
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka
  instance:
    instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}}

# Actuator 사용해서 설정 파일을 갱신하기 위한 코드
management:
  endpoints:
    web:
      exposure:
        include: health, refresh

서비스 실행 후 확인

  1. config 서버 실행
  2. 유레카 서버 실행
  3. 서비스 서버 실행

유레카 서버에 잘 등록된 것까지 확인 후 게이트웨이 서버 작업 시작

Gateway Server 생성

dependency

추가로 actuatorbootstrap 을 넣어준다.


dependencies {
	...
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.cloud:spring-cloud-starter-bootstrap'
    ...
}

bootstrap.yml

config server 에서 해당 서비스의 설정 파일을 가져올 수 있는 설정 파일을 만든다

spring:
  cloud:
    config:
      uri: http://localhost:8888
      name: gateway
      profile: default

config server repository에 설정 파일 추가

config server 가 바라보고 있는 레포지토리에 우리 서비스의 설정 파일을 커밋 해준다.

이 설정 파일엔 유레카 서버에 서비스를 레지스트리 하는 코드도 포함된다.

server:
  port: 80

# 유레카 레지스트리 코드
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka
  instance:
    instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}}

# SCG 설정 코드
spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        - id: first-service
          uri: lb://FIRST-SERVICE
          predicates:
            - Path=/first-service/**
          filters:
            - RemoveRequestHeader=Cookie
        - id: second-service
          uri: lb://SECOND-SERVICE
          predicates:
            - Path=/second-service/**
          filters:
            - RemoveRequestHeader=Cookie
            
# Actuator 사용해서 설정 파일을 갱신하기 위한 코드
management:
  endpoints:
    web:
      exposure:
        include: health, refresh

cloud.gateway.routes.id.uri : lb 인 이유 : http://localhost:7777/first-service/** 이런 식으로 적어주어도 되긴 하지만 유레카 서버를 통해 도메인을 등록해서 서버는 도메인 네임만으로 서비스들을 찾을 수 있게 해 동적 포트 할당을 원활하게 하기 위함이다.

추후 POD단위로 배포할 때에 POD는 언제든 버릴 준비를 하고 있어야 하는 배포 자원이므로 항상 새로 띄울 준비를 해야하는데 이 때 포트가 계속 변하게 된다. 따라서 유레카 서버에 등록한 도메인 네임으로 서비스를 찾는다.

유레카 서버는 로드벨런싱을 진행할 때 라운드 로빈 방식으로 서비스의 트래픽을 분산해준다고 한다. 서비스 A에 인스턴스 a, b, c 가 있다면 순차적으로 a, b, c 로 트래픽을 분산하는 것.

gateway 도메인으로 서비스 호출하기

원래였다면 서비스의 포트로 기입을 해주어야 하지만 게이트웨이의 도메인으로 각 서비스의 route로 접근할 수 있게 됐다.

profile
최고의 오늘을 꿈꾸는 개발자

0개의 댓글