MSA

[MSA] Part 7. API Gateway를 Eureka에 등록하기

cwchoiit 2023. 10. 10. 16:52
728x90
반응형
SMALL
728x90
반응형
SMALL

이전 Part 6 까지는 API Gateway Service는 Eureka에 등록하지 않았다. 이제 이 Gateway도 등록을 해야한다.

등록해서 Load Balancer를 사용해보자.

 

 

API Gateway Service의 application.yml

server:
  port: 8000
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka

spring:
  application:
    name: api-gateway-service
  cloud:
    gateway:
      default-filters:
        - name: GlobalFilter
          args:
            baseMessage: Spring Global Filter
            preLogger: true
            postLogger: true
      routes:
        - id: user-service
          uri: lb://USER-SERVICE
          predicates:
            - Path=/user-service/**
          filters:
            - name: CustomFilter

기존에 GatewayService의 application.yml 파일은 eureka.client.register-with-eureka가 false, eureka.client.fetch-registry: false였는데 둘 다 true로 변경해주었다. 그래서 eureka에 이 서비스를 등록하고 eureka에 등록되어 있는 서비스들을 실시간으로 데이터 조회하게 된다.

 

그 다음, 중요한 부분인 spring.cloud.gateway.routes에 기록되는 각각의 서비스들의 uri다.

보면 user-service의 uri가 lb://USER-SERVICE로 변경되었는데 lb는 Load Balancer의 약자로 eureka에 등록된 Named Service 기반으로 서비스를 찾겠다는 뜻이고 그 서비스의 이름이 USER-SERVICE가 된다는 뜻이다. 

 

주의

서비스의 이름에 "_"가 들어가면 안된다. 나도 이거 때문에 한참 고생했는데 만약 있다면 저렇게 USER-SERVICE로 바꾸자.

 

기존에 eureka 서버를 띄우면 application name으로 등록된 서비스들의 이름이 보였다. (아래 사진을 참고)

이렇게 eureka에 등록된 서비스들의 이름을 가지고 Gateway가 실제 서비스의 uri를 찾아간다.

 

 

UserService의 application.yml 

server:
  port: 0
spring:
  application:
    name: user-service

eureka:
  instance:
    instance-id: ${spring.cloud.client.hostname}:${spring.application.instance_id:${random.value}}
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka

server.port를 우선 0으로 지정해서 임의의 포트를 할당받게 했다. 실행할 때마다 번거롭게 포트를 새롭게 지정해 줄 필요 없이 원하는 만큼 서비스의 인스턴스를 실행할 수 있다. 실제로 서비스의 인스턴스를 두 개 정도 띄워보자. IntelliJ에서 인스턴스를 여러개 띄우는 방법은 이미 전 포스팅에서 설명했던 부분이니 넘어간다.

두 개를 띄우고 eureka 서버에 들어가보면 위 사진처럼 두개의 인스턴스가 기동되어 있음을 확인할 수 있다. 그리고 각 인스턴스의 포트를 신경쓰지 않고 Named 기반의 서비스를 Gateway에서 등록했으니 UserService로의 요청을 Gateway는 잘 전달해줄 수 있을 것이다.

 

 

Load Balancing 확인

실제로 유저 서비스는 인스턴스가 두개가 등록됐는데 외부 요청이 들어올 때마다 Gateway가 어떤 인스턴스에 요청을 보내는지 확인해보자. 그리고 어떤 방식으로 유저 서비스에 대한 요청을 Load Balancing해주는지도 확인해보자.

 

Postman으로 테스트해 볼 예정이고 그 전에 UserService의 코드를 좀 수정해야한다.

package com.example.tistoryuserservice.controller;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/user-service")
public class StatusController {
    private final Environment environment;

    @GetMapping("/welcome")
    public String welcomePage() {
        return "Welcome ! This is User Service.";
    }

    @GetMapping("/message")
    public String message(@RequestHeader("user-request") String header) {
        log.info("header: {}", header);
        return "header check";
    }

    @GetMapping("/check")
    public String check() {
        log.info("current port: {}", environment.getProperty("local.server.port"));
        return "Hi, check method !" + environment.getProperty("local.server.port");
    }
}

Environment 클래스를 주입한다. 이 클래스는 환경 변수에 접근할 수 있게 해주는 스프링에서 제공해주는 클래스이다. 이 클래스를 주입받고 check() method에 이 요청이 들어왔을 때 처리해주는 현재 서버의 포트를 찍어주게 변경했다. 

 

그리고 인스턴스를 두 개 띄웠으니까 각 인스턴스의 잡혀있는 포트를 확인해보자.

유레카 서버에서 보면 인스턴스 두 개에 각각 링크가 걸려있다. 각 링크를 클릭해보면 포트번호를 확인할 수 있는데 나의 경우 인스턴스 한 개는 56482, 56537로 잡혀있다.

 

이 두 개의 포트번호를 확인한 후 Postman을 열어 실제로 요청을 보내보자.

최초 요청을 보내면 응답은 포트번호 56482로 나온다. 즉, 56482로 띄워진 인스턴스가 이 요청을 처리했다는 의미인데 바로 한번 더 요청을 보내보자.

그 다음 요청은 56537로 잡힌 인스턴스가 이 요청을 처리했다. 이후에 계속 실행을 해보면 한번은 56482가 한번은 56537 인스턴스가 각 요청을 처리한다 이런 방식을 라운드로밍 방식이라고 하고 Load Balancer가 각 요청에 대해 띄워져 있는 인스턴스에게 한 번씩 요청을 전달해 처리하도록 수행해준다. 이게 Load Balancing이고 이를 Spring Cloud Gateway가 해준다.

 

 

728x90
반응형
LIST