实现思路
- 动态限流:
- 使用Spring Cloud Gateway的限流过滤器,如
RequestRateLimiter
过滤器。
- 结合Redis作为限流计数器存储,实现动态限流规则的管理。可以通过操作Redis中的限流数据来动态调整限流参数。
- 基于IP的访问控制:
- 在Spring Cloud Gateway的过滤器链中添加自定义过滤器。
- 在自定义过滤器中获取请求的IP地址,与允许访问的IP列表进行比对,决定是否放行请求。
关键代码片段
- 动态限流:
- 引入依赖:
在
pom.xml
中添加Spring Cloud Gateway和Redis相关依赖:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
- 配置限流过滤器:
在
application.yml
中配置限流过滤器:
spring:
cloud:
gateway:
routes:
- id: specific_service_route
uri: lb://specific - service
predicates:
- Path=/specific - service/**
filters:
- name: RequestRateLimiter
args:
key - resolver: "#{@ipKeyResolver}"
redis - rate - limiter.replenishRate: 10 # 每秒补充令牌数
redis - rate - limiter.burstCapacity: 20 # 令牌桶容量
- 配置Key Resolver:
在配置类中定义
Key Resolver
,用于根据请求IP生成限流的Key:
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Configuration
public class RateLimitConfig {
@Bean
public KeyResolver ipKeyResolver() {
return new KeyResolver() {
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
return Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
}
};
}
}
- 基于IP的访问控制:
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.Arrays;
import java.util.List;
@Component
public class IpAccessFilterFactory extends AbstractGatewayFilterFactory<IpAccessFilterFactory.Config> {
public IpAccessFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
String clientIp = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
if (config.getAllowedIps().contains(clientIp)) {
return chain.filter(exchange);
} else {
exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
return Mono.empty();
}
};
}
public static class Config {
private List<String> allowedIps;
public List<String> getAllowedIps() {
return allowedIps;
}
public void setAllowedIps(List<String> allowedIps) {
this.allowedIps = allowedIps;
}
}
}
- 配置自定义过滤器:
在
application.yml
中配置自定义过滤器:
spring:
cloud:
gateway:
routes:
- id: specific_service_route
uri: lb://specific - service
predicates:
- Path=/specific - service/**
filters:
- name: IpAccessFilter
args:
allowedIps:
- 192.168.1.100
- 10.0.0.1