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

Redis原子計(jì)數(shù)器incr,防止并發(fā)請(qǐng)求操作

 更新時(shí)間:2020年11月24日 11:44:30   作者:張小鳴  
這篇文章主要介紹了Redis原子計(jì)數(shù)器incr,防止并發(fā)請(qǐng)求操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

一、前言

在一些對(duì)高并發(fā)請(qǐng)求有限制的系統(tǒng)或者功能里,比如說(shuō)秒殺活動(dòng),或者一些網(wǎng)站返回的當(dāng)前用戶過(guò)多,請(qǐng)稍后嘗試。這些都是通過(guò)對(duì)同一時(shí)刻請(qǐng)求數(shù)量進(jìn)行了限制,一般用作對(duì)后臺(tái)系統(tǒng)的保護(hù),防止系統(tǒng)因?yàn)檫^(guò)大的流量沖擊而崩潰。對(duì)于系統(tǒng)崩潰帶來(lái)的后果,顯然還是拒絕一部分請(qǐng)求更能被維護(hù)者所接受。

而在各種限流中,除了系統(tǒng)自身設(shè)計(jì)的帶鎖機(jī)制的計(jì)數(shù)器外,利用Redis實(shí)現(xiàn)顯然是一種既高效安全又便捷方便的方式。

二、incr命令

Redis Incr 命令將 key 中儲(chǔ)存的數(shù)字值增一。

如果 key 不存在,那么 key 的值會(huì)先被初始化為 0 ,然后再執(zhí)行 INCR 操作。

如果值包含錯(cuò)誤的類型,或字符串類型的值不能表示為數(shù)字,那么返回一個(gè)錯(cuò)誤。

本操作的值限制在 64 位(bit)有符號(hào)數(shù)字表示之內(nèi)。

示例:

127.0.0.1:6379> set num 10
OK
127.0.0.1:6379> incr num
(integer) 11
127.0.0.1:6379> get num  # 數(shù)字值在 Redis 中以字符串的形式保存
"11"

注意: 由于redis并沒(méi)有一個(gè)明確的類型來(lái)表示整型數(shù)據(jù),所以這個(gè)操作是一個(gè)字符串操作。

執(zhí)行這個(gè)操作的時(shí)候,key對(duì)應(yīng)存儲(chǔ)的字符串被解析為10進(jìn)制的64位有符號(hào)整型數(shù)據(jù)。

事實(shí)上,Redis 內(nèi)部采用整數(shù)形式(Integer representation)來(lái)存儲(chǔ)對(duì)應(yīng)的整數(shù)值,所以對(duì)該類字符串值實(shí)際上是用整數(shù)保存,也就不存在存儲(chǔ)整數(shù)的字符串表示(String representation)所帶來(lái)的額外消耗。

三、使用場(chǎng)景

1.計(jì)數(shù)器

使用思路是:每次有相關(guān)操作的時(shí)候,就向Redis服務(wù)器發(fā)送一個(gè)incr命令。

例如這樣一個(gè)場(chǎng)景:我們有一個(gè)web應(yīng)用,我們想記錄每個(gè)用戶每天訪問(wèn)這個(gè)網(wǎng)站的次數(shù)。

web應(yīng)用只需要通過(guò)拼接用戶id和代表當(dāng)前時(shí)間的字符串作為key,每次用戶訪問(wèn)這個(gè)頁(yè)面的時(shí)候?qū)@個(gè)key執(zhí)行一下incr命令。

這個(gè)場(chǎng)景可以有很多種擴(kuò)展方法:

通過(guò)結(jié)合使用INCR和EXPIRE命令,可以實(shí)現(xiàn)一個(gè)只記錄用戶在指定間隔時(shí)間內(nèi)的訪問(wèn)次數(shù)的計(jì)數(shù)器

客戶端可以通過(guò)GETSET命令獲取當(dāng)前計(jì)數(shù)器的值并且重置為0

通過(guò)類似于DECR或者INCRBY等原子遞增/遞減的命令,可以根據(jù)用戶的操作來(lái)增加或者減少某些值 比如在線游戲,需要對(duì)用戶的游戲分?jǐn)?shù)進(jìn)行實(shí)時(shí)控制,分?jǐn)?shù)可能增加也可能減少。

2.限速器

限速器是一種可以限制某些操作執(zhí)行速率的特殊場(chǎng)景。

傳統(tǒng)的例子就是限制某個(gè)公共api的請(qǐng)求數(shù)目。

假設(shè)我們要解決如下問(wèn)題:限制某個(gè)api每秒每個(gè)ip的請(qǐng)求次數(shù)不超過(guò)10次。

我們可以通過(guò)incr命令來(lái)實(shí)現(xiàn)兩種方法解決這個(gè)問(wèn)題。

四、流量控制之java實(shí)現(xiàn)

這里我們將在java中使用redis-incr的特性來(lái)構(gòu)建一個(gè)1分鐘內(nèi)只允許 請(qǐng)求100次的控制代碼,key代表在redis內(nèi)存放的被控制的鍵值。

public static boolean flowControl(String key){
    //最大允許100
    int max = 100;
    long total = 1L;
    try {
      if (jedisInstance.get(key) == null) {
        //jedisInstance是Jedis連接實(shí)例,可以使單鏈接也可以使用鏈接池獲取,實(shí)現(xiàn)方式請(qǐng)參考之前的blog內(nèi)容
        //如果redis目前沒(méi)有這個(gè)key,創(chuàng)建并賦予0,有效時(shí)間為60s
        jedisInstance.setex(key, 60, "0");
      } else {
        //獲取加1后的值
        total = jedisInstance.incr(redisKey).longValue();
        //Redis TTL命令以秒為單位返回key的剩余過(guò)期時(shí)間。當(dāng)key不存在時(shí),返回-2。當(dāng)key存在但沒(méi)有設(shè)置剩余生存時(shí)間時(shí),返回-1。否則,以秒為單位,返回key的剩余生存時(shí)間。
        if (jedisInstance.ttl(redisKey).longValue() == -1L)
        {
          //為給定key設(shè)置生存時(shí)間,當(dāng)key過(guò)期時(shí)(生存時(shí)間為0),它會(huì)被自動(dòng)刪除。
          jedisInstance.expire(redisKey, 60);
        }
      }
    } catch (Exception e) {
      logger.error("流量控制組件:執(zhí)行計(jì)數(shù)操作失敗,無(wú)法執(zhí)行計(jì)數(shù)");
    }
    long keytotaltransations = max;
    //判斷是否已超過(guò)最大值,超過(guò)則返回false
    if (total > keytotaltransations) {
      return false;
    }
    return true;
  }

補(bǔ)充知識(shí):【限流算法】java實(shí)現(xiàn)redis分布式時(shí)間窗口計(jì)數(shù)器算法

本文實(shí)現(xiàn)一種基于java的分布式固定時(shí)間窗口計(jì)數(shù)器算法

//每次請(qǐng)求進(jìn)來(lái),查詢一下當(dāng)前的計(jì)數(shù)值,如果超出請(qǐng)求數(shù)閾值,則拒絕請(qǐng)求,返回系統(tǒng)繁忙提示
private long limitFlow(String key) {
    //Setnx(SET if Not eXists) 命令在指定的 key 不存在時(shí),為 key 設(shè)置指定的值。設(shè)置成功返回1,設(shè)置失敗返回0
    Long lng = redisCacheClient.setnx(jedisGroup, key, "1");
    if (lng == 1) {
      //設(shè)置時(shí)間窗口,redis-key時(shí)效為10秒
      redisCacheClient.expire(jedisGroup, key, 10);
      return 1L;
    } else {
      //Redis Incrby 命令將 key 中儲(chǔ)存的數(shù)字加上指定的增量值。相當(dāng)于放在redis中的計(jì)數(shù)器,每次請(qǐng)求到來(lái)計(jì)數(shù)器自增1
      long val = redisCacheClient.incrBy(jedisGroup, key, 1);
 
      return val;
    }
  }

以上這篇Redis原子計(jì)數(shù)器incr,防止并發(fā)請(qǐng)求操作就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Feign超時(shí) 在yml文件里的配置方式

    Feign超時(shí) 在yml文件里的配置方式

    這篇文章主要介紹了Feign超時(shí) 在yml文件里的配置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Java數(shù)組與二維數(shù)組及替換空格實(shí)戰(zhàn)真題講解

    Java數(shù)組與二維數(shù)組及替換空格實(shí)戰(zhàn)真題講解

    數(shù)組對(duì)于每一門編程語(yǔ)言來(lái)說(shuō)都是重要的數(shù)據(jù)結(jié)構(gòu)之一,當(dāng)然不同語(yǔ)言對(duì)數(shù)組的實(shí)現(xiàn)及處理也不盡相同。Java?語(yǔ)言中提供的數(shù)組是用來(lái)存儲(chǔ)固定大小的同類型元素,這篇文章主要介紹了Java數(shù)組與二維數(shù)組及替換空格實(shí)戰(zhàn)真題講解
    2022-07-07
  • Intellij IDEA神器居然還有這些小技巧

    Intellij IDEA神器居然還有這些小技巧

    Intellij IDEA真是越用越覺(jué)得它強(qiáng)大,它總是在我們寫代碼的時(shí)候,不時(shí)給我們來(lái)個(gè)小驚喜,本文給大家主要介紹一些你可能不知道的但是又實(shí)用的小技巧,感興趣的朋友跟隨小編一起看看吧
    2021-01-01
  • SpringAOP+RabbitMQ+WebSocket實(shí)戰(zhàn)詳解

    SpringAOP+RabbitMQ+WebSocket實(shí)戰(zhàn)詳解

    這篇文章主要介紹了SpringAOP+RabbitMQ+WebSocket實(shí)戰(zhàn)詳解,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • Java新手環(huán)境搭建 Tomcat安裝配置教程

    Java新手環(huán)境搭建 Tomcat安裝配置教程

    這篇文章主要為大家詳細(xì)介紹了Java新手環(huán)境搭建的相關(guān)資料,Tomcat安裝配置教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • Java 數(shù)組分析及簡(jiǎn)單實(shí)例

    Java 數(shù)組分析及簡(jiǎn)單實(shí)例

    這篇文章主要介紹了Java 數(shù)組分析及簡(jiǎn)單實(shí)例的相關(guān)資料,在Java中它就是對(duì)象,一個(gè)比較特殊的對(duì)象,需要的朋友可以參考下
    2017-03-03
  • Java實(shí)現(xiàn)簡(jiǎn)單點(diǎn)餐系統(tǒng)

    Java實(shí)現(xiàn)簡(jiǎn)單點(diǎn)餐系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)單點(diǎn)餐系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Spring中IOC和AOP的核心組成架構(gòu)詳解

    Spring中IOC和AOP的核心組成架構(gòu)詳解

    這篇文章主要介紹了Spring中IOC和AOP的核心組成架構(gòu)詳解,本文是對(duì)Spring的2大核心功能——IoC和AOP 的總結(jié)提煉,并增加了環(huán)境profile和條件化bean的內(nèi)容,篇幅較短,更像是一個(gè)大綱,或者思維導(dǎo)圖,需要的朋友可以參考下
    2023-08-08
  • Java程序中使用JavaMail發(fā)送帶圖片和附件的郵件

    Java程序中使用JavaMail發(fā)送帶圖片和附件的郵件

    這篇文章主要介紹了Java程序中使用JavaMail發(fā)送帶圖片和附件的郵件,JavaMail是專門用來(lái)處理郵件的Java API,需要的朋友可以參考下
    2015-11-11
  • 一篇文章詳解Java異常處理

    一篇文章詳解Java異常處理

    異常處理是編程語(yǔ)言或計(jì)算機(jī)硬件里的一種機(jī)制,用于處理軟件或信息系統(tǒng)中出現(xiàn)的異常狀況(即超出程序正常執(zhí)行流程的某些特殊條件),這篇文章主要給大家介紹了關(guān)于Java異常處理的相關(guān)資料,需要的朋友可以參考下
    2023-12-12

最新評(píng)論