利用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