우리네 장
[ MSA ] Spring Cloud Gateway에 커스텀 필터 적용하기 본문
전 게시글에서, spring cloud gateway에서 기본으로 제공하는 필터가 있다고 설명하였습니다.
AddRequestHeader / RemoveRequestHeader / AddResponseHeader / RemoveResponseHeader / RewritePath
해당 필터들 외에도, 사용자가 커스텀 필터를 정의하여 게이트웨이에게 로깅이나 인증등의 역할을 수행할 수 있도록 할 수 있습니다.
단일 지점에서 로깅이나 인증, 캐싱, 접근 제한등의 기능을 수행하면, 각 서비스에서 수행하는 것보다 관리면에서 훨씬 수월할 것입니다.
아래는 로깅 작업을 수행하는 필터를 만들어 보았습니다.
@Component
@Slf4j
public class LoggingCopyFilter extends AbstractGatewayFilterFactory<LoggingCopyFilter.Config> {
public LoggingCopyFilter() {
super(Config.class);
}
//게이트 웨이 역할 구현
@Override
public GatewayFilter apply(Config config) {
return ((exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
String requestId = request.getId();
String requestPath = request.getPath().toString();
log.info( "logging filter start." );
if( config.isPreLogger ) {
log.info( "request Id : {}", requestId );
log.info( "request Path : {}", requestPath );
}
return chain.filter(exchange).then(Mono.fromRunnable(()->{
if( config.isPostLogger ) {
log.info( "response status code : {}", response.getStatusCode() );
}
}));
});
}
static class Config{
private boolean isPreLogger;
private boolean isPostLogger;
}
}
게이트웨이의 필터는 AbstractGatewayFilterFactory<xxx.Config> 를 구현해 사용합니다.
해당 필터 클래스는 @Component를 사용해 spring에서 관리할 수 있도록 지정해줍니다.
내부에 Config라는 static 클래스가 보이는데, 이 클래스는 필터에 임의의 변수를 사용하기 위해 정의하는 클래스 입니다.
위 Config 클래스의 isPreLogger와 isPostLogger 변수의 값은 application.yml에서 지정해줍니다.
apply(Config c)라는 메소드를 구현해주면 되는데요.
스프링 클라우드 게이트웨이는 내부적으로 Netty를 통해 동작합니다. 인자로 보이는 exchange는 ServerWebExchange로 사용자 요청과 응답을 조회할 수 있는 클래스입니다. Netty에서는 요청과 응답 타입이 ServerHttpRequest / ServerHttpResponse 입니다.
return chain.filter(exchange).then(Mono.fromRunnable(()->{
if( config.isPostLogger ) {
log.info( "response status code : {}", response.getStatusCode() );
}
위 코드가 가장 난해하지 않을까 합니다.
일단 Mono는 데이터 발행자로써, 하나의 데이터를 의미한다고 보면 됩니다. 지금은 Runnable 인터페이스를 구현한 구현체를 Mono라는 클래스로 Wrapping 한 것인데요. 로그를 찍는 동작 자체를 하나의 데이터로 표현한 것이라고 생각하시면됩니다.
chain.filter(exchange) 에서 chain은 GatewayFilterChain입니다. exchange를 다음다음 필터로 넘기면서 필터의 동작을 수행합니다. 그리고 모든 필터가 실행이 끝나면 제일 마지막 필터부터 return 하여 then( Mono.fromRunnable( () -> {} ) 이 차근차근 실행됩니다.
수정된 application.yml 파일 입니다. filters에 등록할 커스텀 필터의 이름과 필요하다면 Config에 설정한 변수들의 인자 값을 정의해줍니다.
스프링 클라우드 게이트웨이에는 글로벌 필터라는 것이 있습니다.
다른 커스텀 필터들보다 제일 먼저 실행되고 필터 체인으로 동작하기 때문에 제일 마지막에 종료됩니다.
각 커스텀 필터는 라우팅 정보마다 사용할 필터를 정의할 수 있는데요, 로깅 동작 처럼 모든 요청에 대해 실행할 필터인 경우, 글로벌 필터로 정의할 수 있습니다.
spring:
cloud:
gateway:
default-filters:
-name:LoggingFilter
args :
isPreLogger : true
isPostLogger : true
설정 파일에서는 default-filters라는 속성을 사용해 위와 같이 정의할 수 있습니다.
'MSA' 카테고리의 다른 글
[MSA] Config 서버에 actuator 적용하기 - no빌드, no재기동! (0) | 2024.01.10 |
---|---|
[ MSA ] Spring Cloud Config 소개 (0) | 2024.01.10 |
[ MSA ] Spring Cloud Gateway와 Discovery Server 같이 사용하기 (0) | 2024.01.10 |
[ MSA ] Spring Cloud Gateway 소개 (0) | 2023.03.08 |
[ MSA ] Netflix Eureka (0) | 2023.03.06 |