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

Redis實(shí)現(xiàn)分布式限流的幾種方法

 更新時(shí)間:2026年01月11日 10:05:58   作者:辭暮爾爾-煙火年年  
Redis實(shí)現(xiàn)分布式限流能有效防止系統(tǒng)過(guò)載,,可以防止系統(tǒng)過(guò)載并確保公平的資源分配,主要算法包括固定窗口、滑動(dòng)窗口和令牌桶,具有一定的參考價(jià)值,感興趣的可以了解一下

使用Redis實(shí)現(xiàn)分布式限流是一種常見(jiàn)且有效的方法,可以防止系統(tǒng)過(guò)載并確保公平的資源分配。Redis的高性能和豐富的數(shù)據(jù)結(jié)構(gòu)使其成為實(shí)現(xiàn)分布式限流的理想選擇。常見(jiàn)的限流算法包括固定窗口計(jì)數(shù)、滑動(dòng)窗口計(jì)數(shù)和令牌桶算法。

1. 固定窗口計(jì)數(shù)算法

固定窗口計(jì)數(shù)算法將時(shí)間劃分為固定長(zhǎng)度的窗口,并在每個(gè)窗口內(nèi)計(jì)數(shù)請(qǐng)求的數(shù)量。

示例代碼

以下示例展示了如何使用Redis實(shí)現(xiàn)固定窗口計(jì)數(shù)算法的分布式限流:

import redis.clients.jedis.Jedis;

public class FixedWindowRateLimiter {

    private Jedis jedis;
    private int maxRequests;
    private int windowSize; // 窗口大小,單位為秒

    public FixedWindowRateLimiter(String host, int port, int maxRequests, int windowSize) {
        this.jedis = new Jedis(host, port);
        this.maxRequests = maxRequests;
        this.windowSize = windowSize;
    }

    public boolean isAllowed(String clientId) {
        String key = "rate_limiter:" + clientId;
        long currentWindow = System.currentTimeMillis() / 1000 / windowSize;
        String windowKey = key + ":" + currentWindow;

        long requestCount = jedis.incr(windowKey);
        if (requestCount == 1) {
            jedis.expire(windowKey, windowSize);
        }

        return requestCount <= maxRequests;
    }

    public void close() {
        jedis.close();
    }

    public static void main(String[] args) {
        FixedWindowRateLimiter rateLimiter = new FixedWindowRateLimiter("localhost", 6379, 5, 60);

        for (int i = 0; i < 10; i++) {
            boolean allowed = rateLimiter.isAllowed("client1");
            System.out.println("Request " + (i + 1) + " allowed: " + allowed);
            try {
                Thread.sleep(500); // 模擬請(qǐng)求間隔
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        rateLimiter.close();
    }
}

2. 滑動(dòng)窗口計(jì)數(shù)算法

滑動(dòng)窗口計(jì)數(shù)算法通過(guò)記錄多個(gè)小窗口內(nèi)的請(qǐng)求數(shù),計(jì)算滑動(dòng)窗口內(nèi)的總請(qǐng)求數(shù)。

示例代碼

以下示例展示了如何使用Redis實(shí)現(xiàn)滑動(dòng)窗口計(jì)數(shù)算法的分布式限流:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

import java.util.List;

public class SlidingWindowRateLimiter {

    private Jedis jedis;
    private int maxRequests;
    private int windowSize; // 窗口大小,單位為秒
    private int interval; // 時(shí)間間隔,單位為秒

    public SlidingWindowRateLimiter(String host, int port, int maxRequests, int windowSize, int interval) {
        this.jedis = new Jedis(host, port);
        this.maxRequests = maxRequests;
        this.windowSize = windowSize;
        this.interval = interval;
    }

    public boolean isAllowed(String clientId) {
        String key = "rate_limiter:" + clientId;
        long currentTime = System.currentTimeMillis() / 1000;
        long windowStart = currentTime - windowSize;

        Transaction transaction = jedis.multi();
        transaction.zadd(key, currentTime, String.valueOf(currentTime));
        transaction.zremrangeByScore(key, 0, windowStart);
        transaction.zcard(key);
        transaction.expire(key, windowSize + interval);

        List<Object> results = transaction.exec();
        long requestCount = (long) results.get(2);

        return requestCount <= maxRequests;
    }

    public void close() {
        jedis.close();
    }

    public static void main(String[] args) {
        SlidingWindowRateLimiter rateLimiter = new SlidingWindowRateLimiter("localhost", 6379, 5, 60, 1);

        for (int i = 0; i < 10; i++) {
            boolean allowed = rateLimiter.isAllowed("client1");
            System.out.println("Request " + (i + 1) + " allowed: " + allowed);
            try {
                Thread.sleep(500); // 模擬請(qǐng)求間隔
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        rateLimiter.close();
    }
}

3. 令牌桶算法

令牌桶算法通過(guò)生成令牌來(lái)控制請(qǐng)求的速率。每次請(qǐng)求需要消耗一個(gè)令牌,如果桶中沒(méi)有令牌,則請(qǐng)求被拒絕。

示例代碼

以下示例展示了如何使用Redis實(shí)現(xiàn)令牌桶算法的分布式限流:

import redis.clients.jedis.Jedis;

public class TokenBucketRateLimiter {

    private Jedis jedis;
    private int maxTokens;
    private int refillRate; // 令牌生成速率,單位為令牌/秒

    public TokenBucketRateLimiter(String host, int port, int maxTokens, int refillRate) {
        this.jedis = new Jedis(host, port);
        this.maxTokens = maxTokens;
        this.refillRate = refillRate;
    }

    public boolean isAllowed(String clientId) {
        String key = "rate_limiter:" + clientId;
        long currentTime = System.currentTimeMillis() / 1000;
        long lastRefillTime = jedis.hget(key, "lastRefillTime") == null ?
                0 : Long.parseLong(jedis.hget(key, "lastRefillTime"));
        int tokens = jedis.hget(key, "tokens") == null ?
                maxTokens : Integer.parseInt(jedis.hget(key, "tokens"));

        long tokensToAdd = (currentTime - lastRefillTime) * refillRate;
        tokens = Math.min(maxTokens, tokens + (int) tokensToAdd);
        lastRefillTime = currentTime;

        if (tokens > 0) {
            jedis.hset(key, "tokens", String.valueOf(tokens - 1));
            jedis.hset(key, "lastRefillTime", String.valueOf(lastRefillTime));
            return true;
        } else {
            jedis.hset(key, "tokens", String.valueOf(tokens));
            jedis.hset(key, "lastRefillTime", String.valueOf(lastRefillTime));
            return false;
        }
    }

    public void close() {
        jedis.close();
    }

    public static void main(String[] args) {
        TokenBucketRateLimiter rateLimiter = new TokenBucketRateLimiter("localhost", 6379, 5, 1);

        for (int i = 0; i < 10; i++) {
            boolean allowed = rateLimiter.isAllowed("client1");
            System.out.println("Request " + (i + 1) + " allowed: " + allowed);
            try {
                Thread.sleep(500); // 模擬請(qǐng)求間隔
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        rateLimiter.close();
    }
}

4. 令牌桶算法與Lua腳本

為了確保限流操作的原子性,可以使用Redis的Lua腳本。以下示例展示了如何結(jié)合Lua腳本和令牌桶算法來(lái)實(shí)現(xiàn)分布式限流。

Lua腳本

保存為token_bucket.lua

local key = KEYS[1]
local maxTokens = tonumber(ARGV[1])
local refillRate = tonumber(ARGV[2])
local currentTime = tonumber(ARGV[3])

local tokens = tonumber(redis.call("hget", key, "tokens") or maxTokens)
local lastRefillTime = tonumber(redis.call("hget", key, "lastRefillTime") or 0)

local tokensToAdd = math.floor((currentTime - lastRefillTime) * refillRate)
tokens = math.min(maxTokens, tokens + tokensToAdd)
lastRefillTime = currentTime

if tokens > 0 then
    redis.call("hset", key, "tokens", tokens - 1)
    redis.call("hset", key, "lastRefillTime", lastRefillTime)
    return 1
else
    redis.call("hset", key, "tokens", tokens)
    redis.call("hset", key, "lastRefillTime", lastRefillTime)
    return 0
end

Java代碼

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;

public class TokenBucketRateLimiterWithLua {

    private JedisPool jedisPool;
    private String luaScript;
    private String scriptSha;

    public TokenBucketRateLimiterWithLua(String host, int port, String scriptPath) throws IOException {
        this.jedisPool = new JedisPool(host, port);
        this.luaScript = new String(Files.readAllBytes(Paths.get(scriptPath)));
        try (Jedis jedis = jedisPool.getResource()) {
            this.scriptSha = jedis.scriptLoad(luaScript);
        }
    }

    public boolean isAllowed(String clientId, int maxTokens, int refillRate) {
        String key = "rate_limiter:" + clientId;
        long currentTime = System.currentTimeMillis() / 1000;


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

相關(guān)文章

  • Redis數(shù)據(jù)刪除與淘汰策略從原理到實(shí)戰(zhàn)指南

    Redis數(shù)據(jù)刪除與淘汰策略從原理到實(shí)戰(zhàn)指南

    本文講解了Redis的數(shù)據(jù)刪除與淘汰策略,從基礎(chǔ)概念鋪墊到策略細(xì)節(jié)拆解,再到底層原理和實(shí)戰(zhàn)配置,重點(diǎn)介紹了三種刪除策略(惰性刪除、定期刪除、主動(dòng)刪除)和六種常用淘汰策略(allkeys-lru、volatile-lru、allkeys-lfu、volatile-lfu等),感興趣的朋友跟隨小編一起看看吧
    2026-04-04
  • Redis中的常用的五種數(shù)據(jù)類型詳解

    Redis中的常用的五種數(shù)據(jù)類型詳解

    這篇文章主要介紹了Redis中的常用的五種數(shù)據(jù)類型詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • redis 解決key的亂碼問(wèn)題,并清理詳解

    redis 解決key的亂碼問(wèn)題,并清理詳解

    這篇文章主要介紹了redis 解決key的亂碼問(wèn)題,并清理詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-07-07
  • 基于Redis實(shí)現(xiàn)基本搶紅包算法詳解

    基于Redis實(shí)現(xiàn)基本搶紅包算法詳解

    [key, value]的緩存數(shù)據(jù)庫(kù), Redis官方性能描述非常高, 所以面對(duì)高并發(fā)場(chǎng)景, 使用Redis來(lái)克服高并發(fā)壓力是一個(gè)不錯(cuò)的手段, 本文主要基于Redis來(lái)實(shí)現(xiàn)基本的搶紅包系統(tǒng)設(shè)計(jì),感興趣的朋友跟隨小編一起看看吧
    2024-04-04
  • Redis中Hash類型相關(guān)命令介紹

    Redis中Hash類型相關(guān)命令介紹

    Redis?hash是一個(gè)String類型的field和value的映射表,hash特別適合用于存儲(chǔ)對(duì)象,這篇文章主要介紹了Redis中Hash類型相關(guān)命令的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-12-12
  • Redis分布式限流生產(chǎn)環(huán)境落地方案

    Redis分布式限流生產(chǎn)環(huán)境落地方案

    本文主要介紹了Redis分布式限流生產(chǎn)環(huán)境落地方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2026-02-02
  • 一篇文章揭秘Redis的磁盤持久化機(jī)制

    一篇文章揭秘Redis的磁盤持久化機(jī)制

    這篇文章主要給大家介紹了如何通過(guò)一篇文章揭秘Redis的磁盤持久化機(jī)制的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Redis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 淺談分布式鎖的幾種使用方式(redis、zookeeper、數(shù)據(jù)庫(kù))

    淺談分布式鎖的幾種使用方式(redis、zookeeper、數(shù)據(jù)庫(kù))

    這篇文章主要介紹了淺談分布式鎖的幾種使用方式(redis、zookeeper、數(shù)據(jù)庫(kù)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-07-07
  • 緩存替換策略及應(yīng)用(以Redis、InnoDB為例)

    緩存替換策略及應(yīng)用(以Redis、InnoDB為例)

    本文以Redis、InnoDB為例給大家講解緩存替換策略及應(yīng)用,本文給大家提到五種置換策略,通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2021-07-07
  • redis批量刪除namespace下的數(shù)據(jù)的實(shí)現(xiàn)步驟

    redis批量刪除namespace下的數(shù)據(jù)的實(shí)現(xiàn)步驟

    在開(kāi)發(fā)中為了更好的管理數(shù)據(jù),對(duì)redis進(jìn)行了分組存儲(chǔ)操作,在存值時(shí)加了命名空間來(lái)實(shí)現(xiàn),本文就來(lái)介紹一下redis批量刪除namespace下的數(shù)據(jù)的實(shí)現(xiàn)步驟,感興趣的可以了解一下
    2025-12-12

最新評(píng)論

成安县| 哈尔滨市| 荆门市| 湛江市| 昌邑市| 确山县| 蒙自县| 府谷县| 丹巴县| 郁南县| 万盛区| 瓮安县| 肇州县| 曲沃县| 曲阜市| 泉州市| 大连市| 张家口市| 沂源县| 涞源县| 泸州市| 南汇区| 富顺县| 科技| 探索| 新龙县| 平江县| 大田县| 沙田区| 肥东县| 鄂托克前旗| 四会市| 天峨县| 唐河县| 石柱| 平顺县| 灯塔市| 黑水县| 凤山市| 增城市| 麻城市|