68 lines
2.2 KiB
Java
68 lines
2.2 KiB
Java
package com.tacit.gateway.config;
|
||
|
||
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
|
||
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
|
||
import org.springframework.context.annotation.Bean;
|
||
import org.springframework.context.annotation.Configuration;
|
||
import org.springframework.context.annotation.Primary;
|
||
import org.springframework.web.server.ServerWebExchange;
|
||
import reactor.core.publisher.Mono;
|
||
|
||
/**
|
||
* 限流配置类
|
||
*/
|
||
@Configuration
|
||
public class RateLimiterConfig {
|
||
|
||
/**
|
||
* IP限流 - 根据请求IP地址进行限流
|
||
* 添加@Primary注解,作为默认的KeyResolver
|
||
*/
|
||
@Bean
|
||
@Primary
|
||
public KeyResolver ipKeyResolver() {
|
||
return exchange -> {
|
||
// 处理可能的空指针异常
|
||
var remoteAddress = exchange.getRequest().getRemoteAddress();
|
||
if (remoteAddress != null && remoteAddress.getAddress() != null) {
|
||
return Mono.just(remoteAddress.getAddress().getHostAddress());
|
||
}
|
||
return Mono.just("unknown");
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 接口限流 - 根据请求路径进行限流
|
||
*/
|
||
@Bean
|
||
public KeyResolver apiKeyResolver() {
|
||
return exchange -> Mono.just(exchange.getRequest().getPath().value());
|
||
}
|
||
|
||
/**
|
||
* 用户限流 - 根据请求头中的X-User-Id进行限流
|
||
*/
|
||
@Bean
|
||
public KeyResolver userKeyResolver() {
|
||
return exchange -> {
|
||
String userId = exchange.getRequest().getHeaders().getFirst("X-User-Id");
|
||
return Mono.just(userId != null ? userId : "anonymous");
|
||
};
|
||
}
|
||
|
||
/**
|
||
* 服务限流 - 根据路由ID进行限流
|
||
*/
|
||
@Bean
|
||
public KeyResolver serviceKeyResolver() {
|
||
return exchange -> {
|
||
// 从路由中获取服务名称,使用正确的常量避免空指针
|
||
Object routeObj = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
|
||
if (routeObj != null) {
|
||
// 使用toString()方法获取路由信息,避免类型转换错误
|
||
return Mono.just(routeObj.toString());
|
||
}
|
||
return Mono.just("unknown");
|
||
};
|
||
}
|
||
} |