Spring Cloud Gateway 사용
- Simple, yet effective way to route to APIs
- Provide cross cutting concerns:
- Security
- Monitoring/metrics
- Built on top of Spring WebFlux (Reactive Approach)
- Features:
- Match routes on any request attribute
- Define Predicates and Filters
- Integrates with Spring Cloud Discovery Client (Load Balancing)
- Path Rewriting
Eureka
http://localhost:8761
Setting up Spring Cloud API Gateway
Dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
Gradle
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.6'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}
group = 'com.javapp'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', "2021.0.5")
}
dependencies {
implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
tasks.named('test') {
useJUnitPlatform()
}
Register the application in Eureka by specifying the Eureka URL(File Name: application.properties)
spring.application.name=api-gateway
server.port=8765
# 유레카 서버 등록
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka
spring.cloud.gateway.discovery.locator.enabled=true
spring.cloud.gateway.discovery.locator.lower-case-service-id=true
- 유레카 서버 등록
# 호환 가능한 서비스 레지스트리에 등록된 서비스를 기반으로 경로를 만들도록 구성
spring.cloud.gateway.discovery.locator.enabled=true
# 경로를 소문자로 설정
spring.cloud.gateway.discovery.locator.lower-case-service-id=true
URL 요청
localhost:API-gateway 포트/api-gateway 경로/서비스url
http://localhost:8765/currency-conversion/currency-conversion-feign/from/EUR/to/INR/quantity/10
API GATEWAY
http://localhost:8765/currency-conversion-feign/from/USD/to/INR/quantity/10
http://localhost:8765/currency-exchange/from/USD/to/INR/
유레카
http://localhost:8761
Currency Conversion Service
http://localhost:8100/currency-conversion-feign/from/USD/to/INR/quantity/10
Currency Exchange Service
http://localhost:8000/currency-exchange/from/USD/to/INR
Exploring Routes
@Configuration
public class ApiGatewayConfiguration
{
@Bean
public RouteLocator gatewayRouter(RouteLocatorBuilder builder)
{
return builder.routes()
.route(p -> p.path("/get")
.filters(f ->
f.addRequestHeader("MyHeader","MyURI")
.addRequestParameter("param", "MyValue"))
.uri("http://httpbin.org:80"))
.route(p->p.path("/currency-conversion-feign/**")
.uri("lb://currency-conversion"))
.route(p->p.path("/currency-conversion-new/**")
.filters(f->f.rewritePath(
"/currency-conversion-new/(?<segment>.*)",
"/currency-conversion-feign/${segment}"
))
.uri("lb://currency-conversion"))
.build();
}
}
헤더 추가와 파라미터 추가
.route(p -> p.path("/get")
.filters(f ->
f.addRequestHeader("MyHeader","MyURI")
.addRequestParameter("param", "MyValue"))
.uri("http://httpbin.org:80"))
경로 축소
.route(p->p.path("/currency-conversion-feign/**")
.uri("lb://currency-conversion"))
http://localhost:8765/currency-conversion/currency-conversion-feign/from/EUR/to/INR/quantity/10
--> http://localhost:8765/currency-conversion-feign/from/EUR/to/INR/quantity/10
"lb://{spring.application.name}" : 로드밸런싱으로 포트번호가 바뀌어도 API-Gateway는 해당 uri로 라우팅
스프링에서 유레카 서버를 통해 서버명을 확인한다.
경로 우회
.route(p->p.path("/currency-conversion-new/**")
.filters(f->f.rewritePath(
"/currency-conversion-new/(?<segment>.*)",
"/currency-conversion-feign/${segment}"
))
.uri("lb://currency-conversion"))
application.yml
server:
port: 8765
management:
endpoints:
web:
exposure:
include:
- "gateway"
endpoint:
gateway:
enabled: true
spring:
application:
name: api-gateway
cloud:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/user/**
filters:
- RewritePath=/user/(?<path>.*),/$\{path}
# 유레카 서버 등록
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka
Logging Filter
package com.javapp.microservices.apigateway.log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class LoggingFilter implements GlobalFilter {
private Logger logger = LoggerFactory.getLogger(LoggingFilter.class);
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
logger.info("URI 요청 받음 -> {}", exchange.getRequest().getPath());
return chain.filter(exchange);
}
}
리소스 요청시 필터를 통해 로그 확인
2022-12-02 14:34:08.406 INFO 9908 --- [ctor-http-nio-3] c.j.m.apigateway.log.LoggingFilter :
URI 요청 받음 -> /currency-conversion-feign/from/EUR/to/INR/quantity/10%0A
참고
Spring Cloud Gateway - Yun Blog | 기술 블로그 (cheese10yun.github.io)
'Back-end > Spring Cloud (MSA)' 카테고리의 다른 글
Spring Cloud (MSA) 분산추적 , Zipkin (0) | 2022.12.30 |
---|---|
Spring Cloud (MSA) - Resilience4j @Retry @CircuitBreaker(서킷브레이커) (0) | 2022.12.06 |
Spring Cloud (MSA) - 로드밸런싱 Eureka, Feign (0) | 2022.11.27 |
Spring Cloud (MSA) - Feign 다른 서버 값 가져오기 (0) | 2022.11.26 |
Spring Cloud (MSA) - Config Server (0) | 2022.11.25 |
댓글