最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

一、前言

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

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

二、incr命令

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

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

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

本操作的值限制在 64 位(bit)有符號數(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并沒有一個明確的類型來表示整型數(shù)據(jù),所以這個操作是一個字符串操作。

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

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

三、使用場景

1.計數(shù)器

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

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

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

這個場景可以有很多種擴(kuò)展方法:

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

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

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

2.限速器

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

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

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

我們可以通過incr命令來實現(xiàn)兩種方法解決這個問題。

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

這里我們將在java中使用redis-incr的特性來構(gòu)建一個1分鐘內(nèi)只允許 請求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連接實例,可以使單鏈接也可以使用鏈接池獲取,實現(xiàn)方式請參考之前的blog內(nèi)容
        //如果redis目前沒有這個key,創(chuàng)建并賦予0,有效時間為60s
        jedisInstance.setex(key, 60, "0");
      } else {
        //獲取加1后的值
        total = jedisInstance.incr(redisKey).longValue();
        //Redis TTL命令以秒為單位返回key的剩余過期時間。當(dāng)key不存在時,返回-2。當(dāng)key存在但沒有設(shè)置剩余生存時間時,返回-1。否則,以秒為單位,返回key的剩余生存時間。
        if (jedisInstance.ttl(redisKey).longValue() == -1L)
        {
          //為給定key設(shè)置生存時間,當(dāng)key過期時(生存時間為0),它會被自動刪除。
          jedisInstance.expire(redisKey, 60);
        }
      }
    } catch (Exception e) {
      logger.error("流量控制組件:執(zhí)行計數(shù)操作失敗,無法執(zhí)行計數(shù)");
    }
    long keytotaltransations = max;
    //判斷是否已超過最大值,超過則返回false
    if (total > keytotaltransations) {
      return false;
    }
    return true;
  }

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

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

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

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

相關(guān)文章

  • 詳解SpringBoot如何自定義一個Starter

    詳解SpringBoot如何自定義一個Starter

    小伙伴們曾經(jīng)可能都經(jīng)歷過整天寫著CURD的業(yè)務(wù),都沒寫過一些組件相關(guān)的東西,這篇文章記錄一下SpringBoot如何自定義一個Starter。原理和理論就不用多說了,可以在網(wǎng)上找到很多關(guān)于該方面的資料,這里主要分享如何自定義
    2022-11-11
  • java實現(xiàn)KFC點餐系統(tǒng)

    java實現(xiàn)KFC點餐系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實現(xiàn)KFC點餐系統(tǒng),模擬肯德基快餐店的收銀系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • maven中deploy命令報401錯誤的原因及解決方案

    maven中deploy命令報401錯誤的原因及解決方案

    在mac版idea使用過程中有時候會出現(xiàn)deploy時候報401錯誤,所以本文給大家介紹了maven 中deploy命令報401錯誤的原因及解決方案,文章通過圖文結(jié)合的方式講解的非常詳細(xì),需要的朋友可以參考下
    2024-05-05
  • 詳解Java解析XML的四種方法

    詳解Java解析XML的四種方法

    本篇文章主要介紹了java解析XML的幾種方式,XML現(xiàn)在已經(jīng)成為一種通用的數(shù)據(jù)交換格式,給數(shù)據(jù)集成與交互提供了方便,有需要的可以了解一下。
    2016-11-11
  • JAVA找不到符號的三種解決方案

    JAVA找不到符號的三種解決方案

    這篇文章主要給大家介紹了關(guān)于JAVA找不到符號的三種解決方案, 找不到符號錯誤主要發(fā)生在我們試圖引用一個未在我們正在編譯的程序中聲明的變量時,這意味著編譯器不知道我們所引用的Java變量,需要的朋友可以參考下
    2024-03-03
  • java 線程創(chuàng)建多線程詳解

    java 線程創(chuàng)建多線程詳解

    本文主要講解java 線程創(chuàng)建多線程的知識,這里對java線程的創(chuàng)建做了詳細(xì)介紹,并附簡單示例代碼,有興趣的小伙伴可以參考下
    2016-09-09
  • Java中Switch的使用方法及新特性

    Java中Switch的使用方法及新特性

    在java中控制流程語句是由選擇語句、循環(huán)語句、跳轉(zhuǎn)語句構(gòu)成,選擇語句包括if和switch,在過多的使用if語句嵌套會使程序很難閱讀,這時就可以用到switch語句,這篇文章主要給大家介紹了關(guān)于Java中Switch的使用方法及新特性的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • Java dom4j創(chuàng)建解析xml文檔過程解析

    Java dom4j創(chuàng)建解析xml文檔過程解析

    這篇文章主要介紹了Java dom4j創(chuàng)建解析xml文檔過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-07-07
  • Java連接MySQL數(shù)據(jù)庫命令行程序過程

    Java連接MySQL數(shù)據(jù)庫命令行程序過程

    SQL編程包括兩種形式,一種是過程化編程,主要通過數(shù)據(jù)庫交互式工具,通過存儲過程、觸發(fā)器、函數(shù)等形式的編程;另一種是嵌入式SQL編程,將SQL語句嵌入到高級開發(fā)語言,完成數(shù)據(jù)的各種操作
    2021-10-10
  • Spring如何處理注解的深入理解

    Spring如何處理注解的深入理解

    這篇文章主要給大家介紹了關(guān)于Spring如何處理注解的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用java中的注解具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11

最新評論

汤阴县| 谢通门县| 沽源县| 平利县| 邛崃市| 唐山市| 于都县| 清原| 神农架林区| 华阴市| 河南省| 灵川县| 通化县| 乐清市| 保康县| 炎陵县| 临颍县| 双桥区| 彰化县| 墨竹工卡县| 普兰店市| 德州市| 昭平县| 洛扎县| 双桥区| 桐柏县| 东阿县| 黑河市| 镇宁| 彝良县| 天柱县| 泸溪县| 洮南市| 靖州| 班玛县| 淮滨县| 佳木斯市| 涞源县| 五指山市| 胶州市| 通河县|