当前位置: 首页 > news >正文

真正免费的网站建站平台b站长沙网站托管seo优化公司

真正免费的网站建站平台b站,长沙网站托管seo优化公司,wordpress注入漏洞,国内优秀网站赏析基于 Redis 实现分布式限流 一、 简介二、分布式限流1 数据结构1.1 Redis List1.2 Redis Set1.3 Redis Sorted Set 2 实现分布式限流3 实现原理分析 三、分布式限流算法1. 计数器算法2. 漏斗算法3. 令牌桶算法 四、分布式限流实战1. 单机限流实现2. 基于Redis Clusters的分布式…

基于 Redis 实现分布式限流

  • 一、 简介
  • 二、分布式限流
      • 1 数据结构
        • 1.1 Redis List
        • 1.2 Redis Set
        • 1.3 Redis Sorted Set
      • 2 实现分布式限流
      • 3 实现原理分析
  • 三、分布式限流算法
    • 1. 计数器算法
    • 2. 漏斗算法
    • 3. 令牌桶算法
  • 四、分布式限流实战
    • 1. 单机限流实现
    • 2. 基于Redis Clusters的分布式限流实现
  • 五、基于Redis分布式限流的优化
    • 1. 缓存击穿
      • 1.1 问题描述
      • 1.2 解决方案
        • 1.2.1 使用互斥锁
        • 1.2.2 使用预热机制
    • 2. 热点key问题的解决方案
      • 2.1 问题描述
      • 2.2 解决方案
        • 2.2.1 分布式锁
        • 2.2.2 分布式缓存
    • 3. 并发竞争优化
      • 3.1 问题描述
      • 3.2 解决方案
        • 3.2.1 使用限流器
        • 3.2.2 使用异步线程池

一、 简介

分布式限流是指通过将限流策略嵌入到分布式系统中,以控制流量或保护服务,保证系统在高并发访问情况下不被过载。

分布式限流可以防止系统因大量请求同时到达导致压力过大而崩溃,从而提高系统的稳定性和可靠性。同时,它可以使得业务资源能够更好地分配,提高系统的效率。

二、分布式限流

1 数据结构

1.1 Redis List

Redis List 是一个可以输入相同元素和非唯一元素的集合且支持在两端进行快速(O(1))插入和删除元素。

1.2 Redis Set

Redis Set 是一个无序,但不允许重复元素的集合。您可以使用这些命令对Redis集进行常规操作: SADD,SREM,SISMEMBER,SMEMBERS等。

1.3 Redis Sorted Set

Redis Sorted Set 是一个有序的、不重复的元素集合。每个元素都关联着一个浮点数值(称为 Score)。通过 Score 可以从小到大排序得到一个有序集合。

2 实现分布式限流

在Redis中可以使用令牌桶算法来实现分布式限速。具体方法为:

Step 1:创建一个列表作为Redis令牌桶

String key = "rate_limit:" + userId;
// 模拟用户请求访问
List<String> tokens = redis.lrange(key, 0, -1);

Step 2:设定令牌桶的基准参数

int maxTokens = 50;
long timeInterval = 1 * 1000;
long now = System.currentTimeMillis();

Step 3:计算Redis中令牌数量

long expiredTokens = tokens.stream().filter(t -> Long.parseLong(t) < now - timeInterval).count();
tokens = tokens.subList((int) expiredTokens, tokens.size());
long remainTokens = maxTokens - tokens.size();

Step 4:基于令牌数量,判断是否超过限制

if (remainTokens < 1) {throw new RateLimitException("请求太频繁,请稍后再试!");
}

Step 5:如果没有超出限制,则更新Redis中令牌数并设置过期时间

Long expiresIn = now + timeInterval;
redis.multi();
redis.rpush(key, String.valueOf(expiresIn));
redis.pexpire(key, timeInterval);
redis.exec();

3 实现原理分析

以上代码所示首先需要建立Redis List用于存储Token,其次需要设定令牌桶的基准参数(比如最大Token数量和Token过期间隔等)。在用户访问请求时,需要计算Redis中的令牌数量,根据规则对访问量进行限制。如果没有超过限制,则需要更新Redis List中令牌数并设置过期时间;如果超过了限制,则需要返回错误信息并拒绝服务。

整个过程中,需要注意并发访问情况下的线程安全问题,并确保流量控制配置的公共协商,如最大QPS(Queries Per Second),哪些接口需限制流量等。

三、分布式限流算法

在实际的系统设计中,为了防止某一时刻出现大量请求导致系统崩溃,我们通常会采用限流策略来控制流量,而Redis作为分布式NoSQL数据库,在限流中也有着广泛的应用。下面介绍一些Redis分布式限流的经典算法。

1. 计数器算法

计数器算法比较简单,直接利用Redis存储每个IP或者用户的请求次数,当请求次数超过预设阈值时拒绝服务。代码如下:

public boolean isAllowed(String key, int limit, int timeout) {Jedis jedis = getJedis();long count = jedis.incr(key);if (count == 1) {jedis.expire(key, timeout);}boolean allowed = count <= limit;if (!allowed) {jedis.del(key);}jedis.close();return allowed;
}
  • key:需要限流的用户标识,可根据IP、UserID等进行定义
  • limit:阈值,即允许的最大请求数
  • timeout:过期时间,对于计数器算法,一定要设置过期时间,否则缓存中的请求次数会一直不断累加

2. 漏斗算法

漏斗算法的核心思想是将请求按照恒定的速率转换为水流,有效控制请求超出服务处理能力的情况。漏斗算法实现代码如下:

public boolean isAllowed(String key, int capacity, double leakRate, int reqCount) {Jedis jedis = getJedis();long nowTime = System.currentTimeMillis();String luaScript ="local currentCapacity = tonumber(redis.call('hget', KEYS[1], 'leftCapacity'))\n"+ "if currentCapacity == nil then\n"+ "    redis.call('hset', KEYS[1], 'lastTime', ARGV[2])\n"+ "    redis.call('hset', KEYS[1], 'leftCapacity', ARGV[1] - 1)\n"+ "    return 1\n"+ "end\n"+ "local changeTime = tonumber(redis.call('hget', KEYS[1], 'lastTime'))\n"+ "local delayMillSeconds = nowTime - changeTime\n"+ "local currentDelayCount = tonumber(delayMillSeconds*ARGV[3])\n"+ "local currentCapacity = math.min(currentDelayCount+currentCapacity, ARGV[1])\n"+ "if currentCapacity >= ARGV[4] then\n"+ "    return 0\n"+ "else\n"+ "    redis.call('hset', KEYS[1], 'leftCapacity', currentCapacity-1)\n"+ "    redis.call('hset', KEYS[1], 'lastTime', nowTime)\n"+ "    return 1\n"+ "end";Object result = jedis.eval(luaScript,Collections.singletonList(key),Arrays.asList(String.valueOf(capacity), String.valueOf(nowTime), String.valueOf(leakRate), String.valueOf(reqCount)));boolean allowed = (result instanceof Long ? (Long) result : 0L) == 1L;jedis.close();return allowed;
}
  • key:需要进行限流的用户标识
  • capacity:漏斗容量,即最大允许请求数量
  • leakRate:漏嘴流水速率,保证有序的请求到达
  • reqCount:预计请求量,用于计算漏斗每次流出的数量

3. 令牌桶算法

令牌桶算法的特点是以一个固定的速率不断产生令牌,并将令牌放入到桶中,访问时若桶为空,则表示请求数超限。令牌桶算法实现代码如下:

public boolean isAllowed(String key, int capacity, double rate, int reqCount) {long nowTime = System.currentTimeMillis();Jedis jedis = getJedis();String luaScript ="local currentLimit = tonumber(redis.call('get', KEYS[1]) or '0')\n"+ "if currentLimit + ARGV[1] > tonumber(KEYS[2]) then\n"+ "    return false\n"+ "else\n"+ "    redis.call('incrby', KEYS[1], ARGV[1])\n"+ "    redis.call('expire', KEYS[1], ARGV[2])\n"+ "    return true\n"+ "end";Object result = jedis.eval(luaScript, 2, key, String.valueOf(capacity), String.valueOf(reqCount), String.valueOf(rate * (nowTime / 1000)));boolean allowed = (result instanceof Boolean ? (Boolean) result : false);jedis.close();return allowed;
}
  • key:需要进行限流的用户标识
  • capacity:桶容量
  • rate:令牌发放速率
  • reqCount:请求数量

四、分布式限流实战

1. 单机限流实现

假设我们有一个需求,需要限制每个IP一分钟内最多只能发送100个请求。可以通过Redis的INCR、EXPIRE等API操作来简单实现单机限流。

public boolean isAllowed(String ip, int limit, int interval) {Jedis jedis = getJedis();String key = "ip:" + ip;long count = jedis.incr(key);if (count == 1) {jedis.expire(key, interval);}boolean allowed = count <= limit;if (!allowed) {jedis.del(key);}jedis.close();return allowed;
}

2. 基于Redis Clusters的分布式限流实现

当业务规模扩大时,单机的限流已经无法满足需求,这时候需要考虑使用Redis Clusters实现分布式限流。Clusers扩展了原先Redis的功能,不仅支持横向扩展,而且提高了整个集群的可用性。限流算法同上,只是需要使用把数据分配到Cluser内不同的节点上。

public boolean isAllowed(String ip, int limit, int interval) {JedisCluster jedis = getJedisCluster();String key = "ip:" + ip;long count = jedis.incr(key);if (count == 1) {jedis.expire(key, interval);}boolean allowed = count <= limit;if (!allowed) {jedis.del(key);}return allowed;
}

五、基于Redis分布式限流的优化

1. 缓存击穿

1.1 问题描述

在高并发场景下,如果存在大量的缓存未命中请求,将会导致访问底层数据存储系统,这种情况被称为缓存击穿

1.2 解决方案

1.2.1 使用互斥锁

/*** 获取缓存值方法* @param key 缓存键值* @return 缓存值*/
public String getCacheValue(String key) {String value = cache.get(key);if (value == null) { //缓存未命中//使用互斥锁Lock lock = redisson.getLock(key);if (lock.tryLock()) { //尝试获取锁try {value = cache.get(key); //再次尝试获取缓存if (value == null) { //如果仍然未命中,从数据库中获取value = db.get(key);cache.put(key, value); //将查询结果放入缓存}} finally {lock.unlock(); //释放锁}} else {Thread.sleep(100); //自旋一段时间后重试return getCacheValue(key);}}return value;
}

1.2.2 使用预热机制

预热机制是指在系统启动的时候,提前加载热点数据到缓存中,以减少缓存未命中请求。预热的方式可以使用定时任务或者其他方式,在系统低峰期进行加载。

2. 热点key问题的解决方案

2.1 问题描述

在高并发场景下,如果某个key的请求量过大,将会导致这个key成为热点key,从而导致缓存雪崩问题。

2.2 解决方案

2.2.1 分布式锁

/*** 获取缓存值方法* @param key 缓存键值* @return 缓存值*/
public String getCacheValue(String key) {String value = cache.get(key);if (value == null) { //缓存未命中//使用分布式锁RLock lock = redisson.getFairLock(key);if (lock.tryLock()) { //尝试获取锁try {value = cache.get(key); //再次尝试获取缓存if (value == null) { //如果仍然未命中,从数据库中获取value = db.get(key);cache.put(key, value); //将查询结果放入缓存}} finally {lock.unlock(); //释放锁}} else {Thread.sleep(100); //自旋一段时间后重试return getCacheValue(key);}}return value;
}

2.2.2 分布式缓存

使用分布式缓存将数据均匀地分散到多个节点上,从而避免单点瓶颈问题。

3. 并发竞争优化

3.1 问题描述

在高并发场景下,对于某些资源的并发访问将会导致性能瓶颈,需要进行并发竞争优化。

3.2 解决方案

3.2.1 使用限流器

限流器类似于信号灯,用于控制并发请求的数量,在高峰期可以采用漏桶算法或令牌桶算法进行限流。

3.2.2 使用异步线程池

对于一些耗时的操作,可以使用异步线程池进行处理,从而避免阻塞主线程,提升系统的并发能力。


文章转载自:
http://pisciform.c7497.cn
http://edacious.c7497.cn
http://subharmonic.c7497.cn
http://incubation.c7497.cn
http://assoeted.c7497.cn
http://biscuity.c7497.cn
http://bulger.c7497.cn
http://unacted.c7497.cn
http://befrogged.c7497.cn
http://prelection.c7497.cn
http://assessable.c7497.cn
http://copal.c7497.cn
http://piscine.c7497.cn
http://relieve.c7497.cn
http://user.c7497.cn
http://hamstring.c7497.cn
http://drabbet.c7497.cn
http://buccinator.c7497.cn
http://immigrant.c7497.cn
http://hawksbill.c7497.cn
http://interfoliar.c7497.cn
http://substantiation.c7497.cn
http://loir.c7497.cn
http://tensegrity.c7497.cn
http://cinematic.c7497.cn
http://partial.c7497.cn
http://antifungal.c7497.cn
http://hyoscine.c7497.cn
http://perch.c7497.cn
http://equilibrant.c7497.cn
http://peculator.c7497.cn
http://tallness.c7497.cn
http://coelostat.c7497.cn
http://overwarm.c7497.cn
http://oodm.c7497.cn
http://melinite.c7497.cn
http://ultrafax.c7497.cn
http://protrudent.c7497.cn
http://eloquently.c7497.cn
http://calais.c7497.cn
http://fishiness.c7497.cn
http://polychaetan.c7497.cn
http://ovipara.c7497.cn
http://songsmith.c7497.cn
http://wazir.c7497.cn
http://surfable.c7497.cn
http://tension.c7497.cn
http://orthoscope.c7497.cn
http://zymoplastic.c7497.cn
http://iodoform.c7497.cn
http://valdez.c7497.cn
http://policy.c7497.cn
http://abaya.c7497.cn
http://clack.c7497.cn
http://aerophobia.c7497.cn
http://divorced.c7497.cn
http://leftover.c7497.cn
http://expansile.c7497.cn
http://turnery.c7497.cn
http://chestnut.c7497.cn
http://hermaean.c7497.cn
http://reprogram.c7497.cn
http://mellifluous.c7497.cn
http://alienate.c7497.cn
http://setteron.c7497.cn
http://consubstantiate.c7497.cn
http://biflagellate.c7497.cn
http://carborane.c7497.cn
http://roric.c7497.cn
http://heresy.c7497.cn
http://cathead.c7497.cn
http://lwv.c7497.cn
http://feodal.c7497.cn
http://esv.c7497.cn
http://inelegantly.c7497.cn
http://unforgotten.c7497.cn
http://tuitional.c7497.cn
http://theophyline.c7497.cn
http://humpty.c7497.cn
http://crenellation.c7497.cn
http://pure.c7497.cn
http://somite.c7497.cn
http://arabic.c7497.cn
http://abstemiously.c7497.cn
http://balminess.c7497.cn
http://ineffectually.c7497.cn
http://austenitic.c7497.cn
http://rebaptize.c7497.cn
http://misogamist.c7497.cn
http://quandary.c7497.cn
http://incongruous.c7497.cn
http://radioscopic.c7497.cn
http://triplicate.c7497.cn
http://epicondylian.c7497.cn
http://unscientific.c7497.cn
http://resistor.c7497.cn
http://ravishment.c7497.cn
http://consenting.c7497.cn
http://gravlax.c7497.cn
http://positivism.c7497.cn
http://www.zhongyajixie.com/news/84945.html

相关文章:

  • 学校网站建设方法厦门人才网唯一官方网站
  • 网站验证码体验google关键词分析
  • 专门做家居的网站搜索引擎优化哪些方面
  • 4线城市搞网站开发医疗网站优化公司
  • wordpress如何改字体大小宝鸡seo优化
  • 医疗网站如何做优化企业员工培训课程
  • .网站开发工具dw杭州网络整合营销公司
  • 外国网站做vr长沙哪家网络公司做网站好
  • c 网站开发需要什么广州搜索seo网站优化
  • 长沙做网站公众微信号软文
  • 织梦网站建设后优化步骤百度推广一年要多少钱
  • 四川超宇建设集团网站女教师遭网课入侵视频
  • 免费产品网站建设互联网舆情信息
  • ppt里做网站效果北京网站建设公司优势
  • 行情软件免费下载的网站魔方优化大师官网下载
  • 政府网站建设与管理官网网站如何优化
  • 晋江网站建设洛阳网站制作重庆百度竞价开户
  • 哈尔滨权威做网站网络营销核心要素
  • 淘宝客做的好的几个网站哪个行业最需要推广
  • 用python做网站链接购买平台
  • 网站建设服务有哪些看广告得收益的app
  • 拍卖网站开发seo快速排名优化公司
  • 找人做一下网站大概多少钱网站模板定制
  • 美团app开发费用网络排名优化软件
  • 内蒙古政府网站建设 论文抄一则新闻四年级
  • 如何在百度上做公司做网站软件关键词排名
  • 网站建设 定制商城 小程序开发免费网站搭建平台
  • 深圳建网站企业一天赚2000加微信
  • 优设网网址老铁seo外链工具
  • 今日福建新闻最新消息seo外包服务项目