본문 바로가기

공부내용 정리/스프링

[SpringBoot, MSA #3] Spring Cloud Gateway, Eureka Server 테스트하기(짱쉬움)

저번 Spring Cloud Gateway 개념에 이어서 이번엔 간단하게 구현해보고 테스트까지 해보려고 합니다.

그리고 오타 찾기 하지마시고 붙여넣기 하셔도 돼요.

구현해보고  테스트해보는 과정이 중요한 것 같습니다. 

 

1. 프로젝트를 하나 생성해볼게요

프로젝트명은 자유, java 버전은 17, Maven

 

 

 

 

 

 

 

 

 

 

 

 

스프링 부트 버전은 3.4.0, 의존성은 Lombok, Eureka Discovery Client, Reactive Gateway 추가

 

2. 프로젝트 생성 후 filter패키지를 생성하고 GlobalFilter 클래스를 아래처럼 생성해줍니다.

package com.example.demo.filter;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;

@Component
@Slf4j
public class GlobalFilter extends AbstractGatewayFilterFactory<GlobalFilter.Config> {
	
	@Data
	public static class Config {
		private String baseMessage;
		private boolean preLogger;
		private boolean postLogger;
	}
	
	public GlobalFilter() {
		super(Config.class);
	}

	public GatewayFilter apply(Config config) {
        return (((exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            ServerHttpResponse response = exchange.getResponse();

            log.info("Global Filter baseMessage: {}", config.getBaseMessage());
            if (config.isPreLogger()) {
                log.info("Global Filter Start: request id -> {}", request.getId());
            }

            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                if (config.isPostLogger()) {
                    log.info("Global Filter End: response code -> {}", response.getStatusCode());
                }
            }));
        }));
    }
	
	

}

 

3. filter패키지에 CustomFilter 클래스를 아래처럼 생성해줍니다.

package com.example.demo.filter;

import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;

import lombok.extern.slf4j.Slf4j;
import reactor.core.publisher.Mono;

@Slf4j
@Component
public class CustomFilter extends AbstractGatewayFilterFactory<CustomFilter.Config> {
	
	public static class Config {
		
	}
	
	public CustomFilter() {
		super(Config.class);
	}
	

	@Override
	public GatewayFilter apply(Config config) {
		
		return ((exchange, chain) -> {
			ServerHttpRequest request = exchange.getRequest();
			ServerHttpResponse response = exchange.getResponse();
			
			System.out.println("Custom PRE filter: request id -> " + request.getId());
			
			return chain.filter(exchange).then(Mono.fromRunnable(() -> {
				System.out.println("Custom POST filter: response code ->" + response.getStatusCode());
			}));
		});
	}
	
}

 

4.  src/main/resourcecs/application.properties 의 이름을 application.yml 로 변경하고 아래 내용을 넣습니다.

server:
  port: 8000

spring:
  application:
    name: api-gateway-1
  cloud:
    gateway:
      routes:
        - id: service1
          uri: lb://service1
          predicates:
            - Path=/service1/**
          filters:
            - CustomFilter
        - id: service2
          uri: lb://service2
          predicates:
            - Path=/service2/**
          filters:
            - AddRequestHeader=second-request, second-request-header
            - AddResponseHeader=second-response, second-response-header
      default-filters:
        - name: GlobalFilter
          args:
            baseMessage: Spring Cloud Gateway GlobalFilter
            preLogger: true
            postLogger: true

management:
  endpoints:
    web:
      exposure:
        include:
          - "gateway"
  endpoint:
    gateway:
      enabled: true

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

간단히 설명하면, api gateway 포트는 8000으로 설정하고, 

Gateway는 service1, service2 라는 마이크로서비스를 라우팅 대상으로 설정합니다.(id: service1..)

service1과, service2는 각각의 서비스 이름으로 Eureka 서비스 레지스트리에 등록해야되는데 이건 밑에 쓰겠습니다.

그리고 Path=/service1/**의 요청은 service1 으로, Path/=service2/**의 요청은 service2로 전달합니다.

service1 에서  filters: - CustomFilter 이부분은 service1에만 요청 전/후로 처리를 하게끔 설정합니다.(위에서 CustomFilter 만들었죠?)

service2 에서 filters : - AddRequestHeader=second-request, second-request-header, AddResponseHeader... 이부분은 

필터를 통해서 요청헤더와 응답헤더를 추가한다는 뜻입니다.

그리고 GlobalFilter는 모든 라우팅 요청에 대해서 필터를 적용한다는 뜻이고, baseMessage, preLogger, postLogger 설정으로 로깅 및 전/후 공통처리 작업을 하도록 설정한다는 뜻입니다.

그리고 application.yml에서 아래부분은 Eureka와의 연동 설정입니다.

지금 만들고 있는 api gateway는 Eureka의 클라이언트로 등록되고(client: register-with-eureka: true)

서비스 레지스트리 정보를 가져옵니다. 어떤 의미냐면 어떤 서비스가 유레카에 저장되어있는지 목록을 조회할 수 있게끔 합니다. (client: fetch-registry: true)

(위에서 프로젝트 생성할때 의존성에 Eureka Client를 넣은 이유입니다.)

defaultZone: http://localhost:8761/eureka 라고 되어있는 부분은

Eureka Server를 http://localhost:8761 에서 실행시키겠다라는 뜻입니다.

 

5. 이대로 gateway만 실행시키면 실행되지 않습니다. 등록되어 있는 Eureka server를 먼저 실행시켜야 해요.

간단하게 Eureka server 생성 ㄱㄱ (5분도 안걸림)

 

의존성에는 Eureka Server 한개만.

 

6. @EnableEurekaServer 추가

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {

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

}

 

7. application.yml

server:
  port: 8761

spring:
  application:
    name: eureka-discovery-service

eureka:
  client:
    register-with-eureka: false  # eureka server를 registry에 등록할지 여부
    fetch-registry: false  # registry에 있는 정보들을 가져올지 여부

 

8. Eureka 서버 실행시키고, localhost:8761 접속하시면 아래처럼 대시보드가 뜹니다!

 

9. 이제 아까 생성했던 api-gateway server를 실행시킵니다.

그리고 대시보드(localhost:8761)에서 새로고침하면 API-GATE-WAY-1 이 보이시죠! 

 

그럼 이제 API GATEWAY 플랫폼 그림에서 GATEWAY, Eureka Server 부분(파란색으로 칠한 부분)이 완성됐습니다.

글이 너무 길어져서 다음 글에서 계속 정리해보겠습니다.

다음 글에서 할 일은 Eureka Client(보라색으로 칠한 부분) 를 몇개 생성해서 Eureka Client로 등록하고

Gateway로 요청해서 라우팅되는 것까지 테스트 해보는 것입니다.

 

끝.

bye bye~~