springboot集成布隆过滤器配合redis解决缓存穿透

102 阅读1分钟

整体操作步骤如下:

1.引入maven坐标

<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>31.1-jre</version>
</dependency>

2.配置bloomFilter 全局bean 初始化大小

```
@Configuration
public class BeanConfig {
    //将BloomFilter设置为全局bean 并且初始化大小
    @Bean(name = "bloomFilterCustom")
    public   BloomFilter bloomFilterCustom() {
        BloomFilter<String> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8), 1000000000, 0.001);
        System.out.println("=========bloomFilter已经创建并且配置完成========" );
        return bloomFilter;
    }
}
```

3.项目启动时候将要存储的key存放到bloomFilter中

@Component
public class GuavaBloomReady implements InitializingBean {
    @Autowired
    private UserDao userDao;

    @Resource(name = "bloomFilterCustom")//根据名称查找并连接bean
    private BloomFilter  bloomFilterCustom;

    @Override
    public void afterPropertiesSet() throws Exception {
        List<String> ids = userDao.selectIdOnly();
        if (ids.size()>0) {
            System.out.println(ids.size()+"项目启动后将项目所有ids存入到布隆过滤器中");
            for (String id : ids) {
                bloomFilterCustom.put(id);
            }

        }
    }

}

4.具体业务场景使用

@RequestMapping(value = "/getBloomFilterTest/{id}", method = RequestMethod.GET)
@ApiOperation(value = "布隆过滤器测试)")
public Result getBloomFilterTest(@PathVariable("id") String id) {
    //如果布隆过滤器里面有这个值
    if (bloomFilterCustom.mightContain(id)) {
        Object o = redisUtils.get(id);
        if (o == null) {
            //缓存不存在,查询数据库
            User user = userDao.queryById(id);
            //空值处理(布隆误判 | 数据被删)
            String value = user == null ? " " : JSONObject.toJSONString(user);
            //设置时间随机值
            String randNum = (new Random().nextInt(9999)+10000)+"";
            redisUtils.set(id, value, (7 * 24 * 60 * 60 * 1000)+Long.parseLong(randNum));
            return Result.okData(user);
        } else if (o.equals("")) {
            //缓存空值处理
            return null;
        } else {
            JSONObject jsonObjectUser = JSONObject.parseObject(o.toString());
            return Result.okData(jsonObjectUser);
        }
    }
        return Result.error("布隆过滤器中不包含这个值");
}

5.数据 同步 例如新增用户时候也要将用户id存到过滤器中

int insert = userDao.insert(user);
if (insert>0){
    //同步数据到布隆过滤器
    bloomFilterCustom.put(uid);
}

加油 冲冲冲 !!!!!