欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot使用布隆過(guò)濾器解決緩存穿透問(wèn)題

 更新時(shí)間:2023年10月10日 08:38:09   作者:YIRC99  
緩存穿透是指當(dāng)緩存系統(tǒng)中無(wú)法命中需要的數(shù)據(jù)時(shí),會(huì)直接請(qǐng)求底層存儲(chǔ)系統(tǒng)(如數(shù)據(jù)庫(kù)),但是如果請(qǐng)求的數(shù)據(jù)根本不存在,那么大量的請(qǐng)求就會(huì)直接穿透緩存層,本文將給大家介紹一下SpringBoot使用布隆過(guò)濾器解決緩存穿透問(wèn)題,需要的朋友可以參考下

緩存穿透基礎(chǔ)介紹

緩存穿透是指當(dāng)緩存系統(tǒng)中無(wú)法命中需要的數(shù)據(jù)時(shí),會(huì)直接請(qǐng)求底層存儲(chǔ)系統(tǒng)(如數(shù)據(jù)庫(kù)),但是如果請(qǐng)求的數(shù)據(jù)根本不存在,那么大量的請(qǐng)求就會(huì)直接穿透緩存層,直接訪問(wèn)底層存儲(chǔ)系統(tǒng),導(dǎo)致底層系統(tǒng)壓力過(guò)大,甚至崩潰。這也是緩存系統(tǒng)面臨的一種常見(jiàn)攻擊。

說(shuō)白了就是查詢大量不傳在的key  繞過(guò)緩存 直接查詢數(shù)據(jù)庫(kù) 導(dǎo)致緩存跟不不存在一樣 這就是緩存穿透

場(chǎng)景介紹

下面說(shuō)下我的場(chǎng)景 我需要添加一個(gè)user 然后我再通過(guò)id去查詢  如果查詢有結(jié)果那就放入緩存 如果沒(méi)有那就直接查詢數(shù)據(jù)庫(kù) ?

這是添加user的方法

這是查詢user的方法

問(wèn)題描述

在這兩個(gè)方法中 我雖然加入的緩存的機(jī)制 但是在查詢user的方法中 會(huì)有一個(gè)問(wèn)題 就是如果我查詢的id是不存在的 那就會(huì)一直查詢數(shù)據(jù)庫(kù)

@Cacheable(value = "userCache", key = "#id", condition = "#result != null")

當(dāng)然你可以說(shuō) 我去掉注解上面的condition = "#result != null"   (這句話意思是condition 條件為真才緩存)  這樣就算我查詢一個(gè)不存在的id 然后將一個(gè)null或者空對(duì)象返回 然后再加入緩存不就可以啦  下次再去查詢這個(gè)不存在的id的時(shí)候 就不會(huì)走數(shù)據(jù)庫(kù)了  

可是 如果我每一次查詢的都是不同的并且不存在的id呢? 那么這個(gè)問(wèn)題還是無(wú)法解決 那么接下來(lái)就可以引入布隆過(guò)濾器  布隆過(guò)濾器具體的原理我這里就不做解釋了

解決問(wèn)題

第一步在maven中導(dǎo)入布隆過(guò)濾器  事先說(shuō)明 導(dǎo)入的方法很多 我的方法不一定是最優(yōu)的 但是一定是能行的

在pom.xml中引入依賴

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>30.1-jre</version>
        </dependency>
        Guava庫(kù)(Google Guava)是一個(gè)Google開(kāi)發(fā)的Java工具庫(kù),
        它提供了許多常用的Java工具類和數(shù)據(jù)結(jié)構(gòu),包括布隆過(guò)濾器(Bloom Filter)

創(chuàng)建項(xiàng)目結(jié)構(gòu) 這個(gè)不需要解釋吧 能看這種文章的 我相信項(xiàng)目結(jié)構(gòu)應(yīng)該都是能看懂的?

AppConfig的代碼如下 就是簡(jiǎn)單的注入Bean對(duì)象

@Configuration
public class AppConfig {
    @Bean
    public BloomFilterService bloomFilterService() {
        return new BloomFilterService();
    }
}

BloomFilterService的代碼如下

public class BloomFilterService {
    private BloomFilter<Long> bloomFilter;
    public BloomFilterService(){
        // 創(chuàng)建一個(gè)布隆過(guò)濾器,設(shè)置期望插入的元素?cái)?shù)量和誤判率
        int  bloomFilterSize = 1000;  // 期望插入的元素?cái)?shù)量
        double falsePositiveRate = 0.001; // 誤判率
        bloomFilter = BloomFilter.create(Funnels.longFunnel(), bloomFilterSize, falsePositiveRate);
    }
    // 添加元素到布隆過(guò)濾器
    public void add(Long id){
        bloomFilter.put(id);
    }
    //判斷元數(shù)是否在布隆過(guò)濾器中
    public boolean contains(Long id){
        return bloomFilter.mightContain(id);
    }
}

接下來(lái)就是在controller中引入并且使用布隆過(guò)濾器了

正常注入

    @Autowired
    private BloomFilterService bloomFilterService;

然后在每一次添加對(duì)象之后都將用戶的id添加到布隆過(guò)濾器中

    @CachePut(value = "userCache", key = "#user.id") // value 指定緩存的名字
    @PostMapping
    public User save(User user){
        userService.save(user);
        bloomFilterService.add(user.getId()); 
        //這里注意必須要放在添加之后 因?yàn)橐婚_(kāi)始傳過(guò)來(lái)的user是沒(méi)有id的 會(huì)有空指針錯(cuò)誤
        //這里利用的查詢回顯 不懂的可以去查查
        return user;
    }

然后更改查詢方法 這樣每一次查詢user的時(shí)候都會(huì)先過(guò)一遍布隆過(guò)濾器 然后再去查詢用戶 如果存在那么就加入緩存 不傳在就會(huì)被布隆過(guò)濾器攔截 注意去掉, condition = "#result != null" 這個(gè)好像跟 布隆有沖突 如果有懂的可以在評(píng)論區(qū)提一下

    @Cacheable(value = "userCache", key = "#id")
    @GetMapping("/{id}")
    public User getById(@PathVariable Long id){
        if (!bloomFilterService.contains(id)) {
            // ID 不合法,可以返回錯(cuò)誤響應(yīng)或進(jìn)行其他處理
            return null;
        }
        User byId = userService.getById(id);
        return byId;
    }

最后的效果

在添加的時(shí)候會(huì)將id添加到布隆中 下一次查詢的時(shí)候如果添加的數(shù)據(jù)不合法 那就直接攔截

如果添加的數(shù)據(jù)是合法的 那么就會(huì)直接查緩存  如果緩存沒(méi)有那就直接查數(shù)據(jù)庫(kù) 然后再加入緩存

上面的效果我自己測(cè)試了發(fā)現(xiàn)是沒(méi)有什么問(wèn)題的 本人的水平也不高 如果有發(fā)現(xiàn)什么問(wèn)題歡迎評(píng)論區(qū)討論 謝謝觀看

以上就是SpringBoot使用布隆過(guò)濾器解決緩存穿透問(wèn)題的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot緩存穿透的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 基于Java并發(fā)容器ConcurrentHashMap#put方法解析

    基于Java并發(fā)容器ConcurrentHashMap#put方法解析

    下面小編就為大家?guī)?lái)一篇基于Java并發(fā)容器ConcurrentHashMap#put方法解析。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • java 基本算法之歸并排序?qū)嵗a

    java 基本算法之歸并排序?qū)嵗a

    這篇文章主要介紹了java 基本算法之歸并排序?qū)嵗a的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • 關(guān)于mybatis-plus插件使用時(shí)的一些問(wèn)題小結(jié)

    關(guān)于mybatis-plus插件使用時(shí)的一些問(wèn)題小結(jié)

    這篇文章主要給大家介紹了關(guān)于mybatis-plus插件使用時(shí)的一些問(wèn)題的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-03-03
  • 教你如何用Java替換Word中帶有${}的內(nèi)容

    教你如何用Java替換Word中帶有${}的內(nèi)容

    這篇文章主要介紹了教你如何用Java替換Word中帶有${}的內(nèi)容,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-04-04
  • SSH框架網(wǎng)上商城項(xiàng)目第9戰(zhàn)之添加和更新商品類別功能實(shí)現(xiàn)

    SSH框架網(wǎng)上商城項(xiàng)目第9戰(zhàn)之添加和更新商品類別功能實(shí)現(xiàn)

    這篇文章主要為大家詳細(xì)介紹了SSH框架網(wǎng)上商城項(xiàng)目第9戰(zhàn)之添加和更新商品類別功能實(shí)現(xiàn),感興趣的小伙伴們可以參考一下
    2016-06-06
  • Java新特性之Optional類超詳細(xì)介紹

    Java新特性之Optional類超詳細(xì)介紹

    這篇文章主要給大家介紹了關(guān)于Java新特性之Optional類超詳細(xì)介紹的相關(guān)資料,Java8中的Optional類是一個(gè)容器對(duì)象,可以包含null或非null值,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • Java 多線程死鎖的產(chǎn)生以及如何避免死鎖

    Java 多線程死鎖的產(chǎn)生以及如何避免死鎖

    這篇文章主要介紹了Java 多線程死鎖的產(chǎn)生以及如何避免死鎖,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 基于Redis生成分布式全局唯一ID的3種策略

    基于Redis生成分布式全局唯一ID的3種策略

    在分布式系統(tǒng)設(shè)計(jì)中,全局唯一ID是一個(gè)基礎(chǔ)而關(guān)鍵的組件,Redis具備高性能、原子操作及簡(jiǎn)單易用的特性,因此我們可以基于Redis實(shí)現(xiàn)全局唯一ID的生成,下面我們來(lái)看看實(shí)現(xiàn)的三種方法吧
    2025-04-04
  • Eclipse git推送上傳錯(cuò)誤問(wèn)題解決方案

    Eclipse git推送上傳錯(cuò)誤問(wèn)題解決方案

    這篇文章主要介紹了Eclipse git推送上傳錯(cuò)誤問(wèn)題解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Java實(shí)現(xiàn)順序表的操作

    Java實(shí)現(xiàn)順序表的操作

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)順序表的基本操作,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01

最新評(píng)論