利用redis实现分布式的布隆过滤器,过滤无效请求
By:Roy.LiuLast updated:2021-05-10
对于布隆过滤器本身是什么,怎么实现的,网上已经有很多解释了。而且网上很多举例用的是google 的 guava ,对于单机应用,用guava 肯定没什么问题。但现在的系统都是微服务,或者分布式架构的。这种情况下,需要多台服务器共享数据,这个时候,redis的优势就体现出来了。本文利用redis来实现共享的布隆过滤器。
一. 引入Redis响应的包
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.15.4</version> </dependency>
二. 将RedissonClient注入到spring容器中.
@Configuration
public class RedissionClientBean {
@Bean
public RedissonClient redissonClient(){
//创建Config
Config config = new Config();
//测试用单机模式,生产环境用集群实现
config.useSingleServer().setAddress("redis://192.168.222.150:6379");
return Redisson.create(config);
}
}三. 在项目启动的时候,把白名单URL增加到布隆过滤器中
@Component
public class InitBloomUrl implements ApplicationRunner {
@Autowired
RedissonClient redissionClient;
@Override
public void run(ApplicationArguments args) throws Exception {
RBloomFilter<Object> urlBloomFilter = redissionClient.getBloomFilter("url_filter");
urlBloomFilter.tryInit(1000000,0.00001);
urlBloomFilter.add("/provider/categories");
urlBloomFilter.add("/provider/goods");
urlBloomFilter.add("/provider/user/*");
}
}四. 当用户访问的时候,在拦截器中,利用布隆过滤器判断URL是否是有效请求. 不同的项目,可能有不同的开发方式,但一般用拦截器,比如类似如下的方法。
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String path = request.getURI().getPath();
RBloomFilter<Object> urlFilter = redissonClient.getBloomFilter("url_filter");
if (urlFilter.contains(path)) {
logger.info("yes it exists");
}
logger.info("====全局过滤器=====, path: {}", path);
return chain.filter(exchange);
}这样就实现了基于redis的分布式布隆过滤器。
From:一号门
Previous:spring boot结合redis实现限流

COMMENTS