亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

利用Redis實(shí)現(xiàn)訪問次數(shù)限流的方法詳解

 更新時(shí)間:2022年02月22日 08:59:44   作者:架構(gòu)擺渡人  
這篇文章主要給大家介紹了關(guān)于如何利用Redis實(shí)現(xiàn)訪問次數(shù)限流的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

假設(shè)我們要做一個(gè)業(yè)務(wù)需求,這個(gè)需求就是限制用戶的訪問頻次。比如1分鐘內(nèi)只能訪問20次,10分鐘內(nèi)只能訪問200次。因?yàn)槭怯脩艟S度的場景,性能肯定是要首先考慮,那么適合這個(gè)場景的非Redis莫屬。

最簡單的實(shí)現(xiàn),莫過于只是用incr進(jìn)行計(jì)數(shù)操作,于是有了下面的代碼:

long count = redisTemplate.opsForValue().increment("user:1:60");
if (count > maxLimitCount) {
   throw new LimitException("訪問太頻繁");
}

count = redisTemplate.opsForValue().increment("user:1:600");
if (count > maxLimitCount) {
   throw new LimitException("訪問太頻繁");
}

來,我們對(duì)上面這段代碼解讀一下。需求有2個(gè)時(shí)間維度的限制,所以這邊基于用戶和時(shí)間維度構(gòu)建了Redis的Key。然后對(duì)每個(gè)Key進(jìn)行計(jì)數(shù),計(jì)數(shù)后的結(jié)果用于跟限制的值進(jìn)行判斷,如果超出了限制的值就拋出異常。

假設(shè)限制的時(shí)間場景有10個(gè)呢?那上面的代碼是不是得寫10遍才可以。有人可能會(huì)說,這還不簡單嗎?循環(huán)呀,循環(huán)確實(shí)能夠解決這個(gè)問題。但是大家有沒有去思考,這是用戶維度的請(qǐng)求,如果每個(gè)請(qǐng)求里面都去操作10次Redis的話,這耗時(shí)至少也得10來毫秒吧。所以問題在這,并不是說這個(gè)邏輯實(shí)現(xiàn)的有問題。

那我們就改成批量的吧,用pipeline來批量執(zhí)行。

redisTemplate.execute(new RedisCallback<Long>() {
    @Override
    public Long doInRedis(RedisConnection connection) throws DataAccessException {
        connection.openPipeline();
        connection.incr("user:1:60".getBytes());
        connection.incr("user:1:600".getBytes());
        onnection.closePipeline();
        return null;
    }
});

用pipeline也有一個(gè)問題,那就是拿不到返回值,也就只能增加,但是沒辦法判斷是否超過了限制的閥值。

所以需要在第一步先查詢下,用查到的值進(jìn)行判斷,這樣也就是只需要和Redis交互兩次就可以了。

上面的代碼在單節(jié)點(diǎn)下沒問題,但是如果在集群下,其實(shí)每個(gè)Key都可能分配到不同的節(jié)點(diǎn)上去,只不過是底層幫你屏蔽掉了細(xì)節(jié),并發(fā)執(zhí)行,拿到了所有結(jié)果后合并返回的。所以我們需要讓所有的Key都路由到一個(gè)節(jié)點(diǎn)上,本來就是用戶維度的,直接使用userId路由即可。

這個(gè)時(shí)候Redis的HashTag功能就排上用場了,將Key user:1:600改寫成user:{1}:600 。

雖然已經(jīng)優(yōu)化了,但是還是要發(fā)起兩次網(wǎng)絡(luò)請(qǐng)求才能完成這個(gè)邏輯,有沒有可能再進(jìn)一步優(yōu)化下呢?一次請(qǐng)求行不行。

這個(gè)時(shí)候要放大招了,Lua腳本走起,將所有邏輯都放入Lua腳本中,一次網(wǎng)絡(luò)交互即可完成。

local current
current = redis.call("incr",KEYS[1])
if current == 1 then
    redis.call("expire",KEYS[1],1)
end

if current > ARGV[1]
  return 1
end

return 0

上面腳本演示了如何對(duì)一個(gè)Key進(jìn)行處理,返回1表示限流,返回0表示通過。不過使用lua腳本的時(shí)候要注意,某些云服務(wù)的Redis會(huì)對(duì)腳本進(jìn)行校驗(yàn),像Redis的Key不能使用變量,必須用KEYS[下標(biāo)]的方式,所以這里操作多個(gè)Key還不能用循環(huán),代碼得寫多遍,這是一個(gè)惡心的點(diǎn)。

總結(jié)

到此這篇關(guān)于利用Redis實(shí)現(xiàn)訪問次數(shù)限流的文章就介紹到這了,更多相關(guān)Redis訪問次數(shù)限流內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決Redis設(shè)置密碼重啟后失效的問題

    解決Redis設(shè)置密碼重啟后失效的問題

    今天小編就為大家分享一篇解決Redis設(shè)置密碼重啟后失效的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • Redis keys命令的具體使用

    Redis keys命令的具體使用

    本文主要介紹了Redis keys命令的具體使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • Redis?異常?read?error?on?connection?的解決方案

    Redis?異常?read?error?on?connection?的解決方案

    這篇文章主要介紹了Redis異常read?error?on?connection的解決方案,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下
    2022-08-08
  • redis計(jì)數(shù)器與數(shù)量控制的實(shí)現(xiàn)

    redis計(jì)數(shù)器與數(shù)量控制的實(shí)現(xiàn)

    使用Redis計(jì)數(shù)器可以輕松地解決數(shù)量控制的問題,同時(shí)還能有效地提高應(yīng)用的性能,本文主要介紹了redis計(jì)數(shù)器與數(shù)量控制的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • Redis分布式限流組件設(shè)計(jì)與使用實(shí)例

    Redis分布式限流組件設(shè)計(jì)與使用實(shí)例

    本文主要講解基于 自定義注解+Aop+反射+Redis+Lua表達(dá)式 實(shí)現(xiàn)的限流設(shè)計(jì)方案。實(shí)現(xiàn)的限流設(shè)計(jì)與實(shí)際使用。具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 一文弄懂Redis 線程模型

    一文弄懂Redis 線程模型

    使用Redis 時(shí),幾乎不存在 CPU 成為瓶頸的情況, Redis 主要受限于內(nèi)存和網(wǎng)絡(luò) 使用了單線程后,可維護(hù)性高,感興趣的可以了解一下
    2024-02-02
  • 使用redis實(shí)現(xiàn)延遲通知功能(Redis過期鍵通知)

    使用redis實(shí)現(xiàn)延遲通知功能(Redis過期鍵通知)

    這篇文章主要介紹了使用redis實(shí)現(xiàn)延遲通知功能(Redis過期鍵通知)的相關(guān)知識(shí),本文通過實(shí)例代碼圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-09-09
  • 使用百度地圖api通過redis實(shí)現(xiàn)地標(biāo)存儲(chǔ)及范圍坐標(biāo)點(diǎn)查詢功能

    使用百度地圖api通過redis實(shí)現(xiàn)地標(biāo)存儲(chǔ)及范圍坐標(biāo)點(diǎn)查詢功能

    這篇文章主要介紹了使用百度地圖api通過redis實(shí)現(xiàn)地標(biāo)存儲(chǔ)及范圍坐標(biāo)點(diǎn)查詢功能,本文通過圖文實(shí)例代碼相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2021-08-08
  • Redis主從配置和底層實(shí)現(xiàn)原理解析(實(shí)戰(zhàn)記錄)

    Redis主從配置和底層實(shí)現(xiàn)原理解析(實(shí)戰(zhàn)記錄)

    今天給大家分享Redis主從配置和底層實(shí)現(xiàn)原理解析,本文通過實(shí)戰(zhàn)項(xiàng)目給大家源碼解析,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-06-06
  • Reactor?WebFlux集成Redis處理緩存操作

    Reactor?WebFlux集成Redis處理緩存操作

    這篇文章主要為大家介紹了Reactor?WebFlux集成Redis處理緩存操作示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09

最新評(píng)論