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

免费文档模板下载一键优化

免费文档模板下载,一键优化,网络公关公司有哪些,做信贷抢客户网站背景 令牌桶限流是一种常见的流量控制算法,用于控制系统的请求处理速率,防止系统过载。在令牌桶限流算法中,可以将请求看作是令牌,而令牌桶则表示系统的处理能力。系统在处理请求时,首先需要从令牌桶中获取令牌&#…

背景

令牌桶限流是一种常见的流量控制算法,用于控制系统的请求处理速率,防止系统过载。在令牌桶限流算法中,可以将请求看作是令牌,而令牌桶则表示系统的处理能力。系统在处理请求时,首先需要从令牌桶中获取令牌,如果令牌桶中没有足够的令牌,就需要等待一定时间,直到令牌桶中有足够的令牌。
具体来说,令牌桶限流算法可以通过以下方式实现:
1.系统维护一个固定容量的令牌桶,每秒钟会向桶中添加一定数量的令牌,直到桶的容量达到上限。
2.每次请求来临时,需要先从令牌桶中获取令牌,如果桶中有足够的令牌,则请求被允许通过,并从桶中移除一个令牌;如果桶中的令牌数量不足,则请求被拒绝。具体来说,令牌桶算法会维护一个令牌桶,其中包含一定数量的令牌,每个令牌代表一个可以执行操作的许可。在每个时间段内,如果有令牌可用,就可以执行一个操作,并将令牌桶中的令牌数量减少一。如果没有令牌可用,就不能执行操作,需要等待一定时间,直到令牌桶中有足够的令牌。
3.由于令牌桶的容量是有限的,因此当桶中的令牌数量达到上限时,新的令牌会被丢弃,从而限制了请求的处理速率。
令牌桶限流算法可以在多种场景中进行流量控制,例如 Web 应用程序、消息队列、数据库等。在 Web 应用程序中,可以通过令牌桶限流算法控制 API 的访问速率,防止 API 被恶意攻击或者过载。在消息队列中,可以通过令牌桶限流算法控制消息的生产和消费速率,防止消息堆积和系统崩溃。在数据库中,可以通过令牌桶限流算法控制查询和写入操作的速率,防止数据库过载和响应时间过长。

lua脚本实现令牌桶算法

Lua 脚本可以用来实现 Redis 的令牌桶限流:
1.定义 Redis 数据结构
使用 Redis 的 Hash 数据结构存储当前令牌桶的状态。在 Hash 中,rate 表示速率(每秒生成的令牌数),capacity 表示桶的容量(最多可以同时存储的令牌数),tokens 表示当前桶中的令牌数量,timestamp 表示上次更新令牌数量的时间戳。示例代码:

HSET rdb:token_bucket rate 10 capacity 100 tokens 100 timestamp 0

2.编写 Lua 脚本
编写 Lua 脚本来实现限流逻辑。在脚本中,首先读取当前时间戳和桶的状态,计算出从上次更新时间戳到当前时间应该生成的令牌数量。然后,将当前桶中的令牌数量和应该生成的令牌数量相加,得到当前桶中的令牌数量。如果当前桶中的令牌数量超过了桶的容量,将其限制为桶的容量。
然后,判断当前桶中的令牌数量是否足够执行操作。如果令牌数量足够,将当前桶中的令牌数量减去操作所需的令牌数量,并更新桶的状态。如果令牌数量不足,则返回限流的错误信息。
示例代码:

-- 读取桶的状态
local rate = tonumber(redis.call('HGET', KEYS[1], 'rate'))
local capacity = tonumber(redis.call('HGET', KEYS[1], 'capacity'))
local tokens = tonumber(redis.call('HGET', KEYS[1], 'tokens'))
local timestamp = tonumber(redis.call('HGET', KEYS[1], 'timestamp'))-- 计算应该生成的令牌数量
local now = redis.call('TIME')
local elapsed = now[1] - timestamp
local generated = math.floor(elapsed * rate)-- 更新令牌数量并限制桶的容量
tokens = math.min(capacity, tokens + generated)-- 执行操作
local required = tonumber(ARGV[1])
if tokens >= required thentokens = tokens - requiredredis.call('HSET', KEYS[1], 'tokens', tokens)redis.call('HSET', KEYS[1], 'timestamp', now[1])return 1
elsereturn 0
end

3.在应用程序中调用 Lua 脚本
在应用程序中,使用 Redis 的 EVAL 命令来调用 Lua 脚本。示例代码:

@Component
public class TokenBucketLimiter {@Autowiredprivate RedisTemplate<String, String> redisTemplate;public boolean tryAcquire(String key, int tokens) {List<String> keys = Arrays.asList(key);List<String> args = Arrays.asList(Integer.toString(tokens));Long result = redisTemplate.execute(new DefaultRedisScript<>("local rate = tonumber(redis.call('HGET', KEYS[1], 'rate')) " +"local capacity = tonumber(redis.call('HGET', KEYS[1], 'capacity')) " +"local tokens = tonumber(redis.call('HGET', KEYS[1], 'tokens')) " +"local timestamp = tonumber(redis.call('HGET', KEYS[1], 'timestamp')) " +"local now = redis.call('TIME') " +"local elapsed = now[1] - timestamp " +"local generated = math.floor(elapsed * rate) " +"tokens = math.min(capacity, tokens + generated) " +"if tokens >= tonumber(ARGV[1]) then " +"    tokens = tokens - tonumber(ARGV[1]) " +"    redis.call('HSET', KEYS[1], 'tokens', tokens) " +"    redis.call('HSET', KEYS[1], 'timestamp', now[1]) " +"    return 1 " +"else " +"    return 0 " +"end",Long.class), keys, args);return result != null && result == 1L;}
}

或者如下脚本:

-- 返回码 1:通过限流 0:不通过
-- rate ARGV[1] 每秒填充速率
-- now  ARGV[2] 当前时间
-- capacity ARGV[3] 令牌桶最大数量
-- request ARGV[4] 需要令牌数量
local SUCCESS = "1"
local FAIL = "0"
local rate = tonumber(ARGV[1]) -- replenishRate 令令牌桶填充平均速率
local capacity = tonumber(ARGV[2]) -- burstCapacity 令牌桶上限
local now = tonumber(ARGV[3]) -- 机器传入的当前时间 秒
local requested = tonumber(ARGV[4]) -- 消耗令牌数量,默认取1local fill_time = capacity/rate   -- 计算令牌桶填充满令牌需要多久时间
local ttl = math.floor(fill_time*2) -- *2 保证时间充足local result = SUCCESS;-- ttl 防止小于0
if ttl < 1 thenttl = 10
end-- 1、获取桶内令牌剩余数量
local last_tokens = tonumber(redis.call("get", KEYS[1]))
-- 获得令牌桶剩余令牌数
if last_tokens == nil then -- 第一次时,没有数值,所以桶时满的last_tokens = capacity
end-- 2、获取上次更新时间
local last_refreshed = tonumber(redis.call("get", KEYS[2]))
-- 令牌桶最后填充令牌时间
if last_refreshed == nil thenlast_refreshed = 0
end-- 3、本次验证和上次更新时间的间隔
local delta = math.max(0, now-last_refreshed)
-- 填充令牌,计算新的令牌桶剩余令牌数 填充不超过令牌桶令牌上限。
local filled_tokens = math.min(capacity, last_tokens+(delta*rate))-- 4、判断令牌数量是否足够
local allowed = filled_tokens >= requested
local new_tokens = filled_tokens
local allowed_num = "0"
if allowed then-- 若成功,令牌桶剩余令牌数(new_tokens) 减消耗令牌数( requested ),并设置获取成功( allowed_num = 1 ) 。new_tokens = filled_tokens - requestedallowed_num = SUCCESS
end-- 5、设置令牌桶剩余令牌数( new_tokens ) ,令牌桶最后填充令牌时间(now) ttl是超时时间
redis.call("setex", KEYS[1], ttl, new_tokens)
redis.call("setex", KEYS[2], ttl, now)if not allowed thenreturn FAIL
endreturn SUCCESS
http://www.ritt.cn/news/27309.html

相关文章:

  • 海安做网站博客网站seo
  • 一台服务做两个网站吗专业网络推广公司排名
  • 怎么用自己电脑做网站seo和sem的联系
  • 滕州营销型网站建设网络营销10大平台
  • 连云港市建设局网站安全员考试短链接在线生成器
  • 做网站选哪个语言网络服务商怎么咨询
  • 潍坊知名网站建设价格低站长工具seo综合查询广告
  • 网络营销具体做什么seo课程培训入门
  • 太原微网站建设app制作一个需要多少钱
  • 大连政府招标网官方网站深圳谷歌网络推广公司
  • 寮步网站建设公司百度关键词价格怎么查询
  • 5173网站做的很垃圾深圳网站优化公司
  • 做的网站百度搜索不出来的百度数据研究中心官网
  • 做视频怎样传到网站线上营销方式主要有哪些
  • 网页游戏开服表时间表seo课程
  • 重庆高端网站开发百度广告业务
  • 委托别人建设网站的合同的版本搜索引擎优化实训
  • 高级网站建设费用智慧教育
  • 做母婴的网站有哪些常用的关键词挖掘工具有哪些
  • 如何再网站上做免费广告词新产品推广方式有哪些
  • 郑州做网站的论坛广州seo外包多少钱
  • 网站推广的重要性网站推广的方式有
  • 网站建设入账哪个科目人民日报今天新闻
  • 上海网站建设服务器济南网站推广公司
  • 做网站好平台化it行业培训机构一般多少钱
  • 芜湖做网站哪个公司好智能优化网站
  • 做个类似淘宝的网站怎么做网站推广沈阳
  • 东莞网站建设服务有什么用链爱交易平台
  • 服务专业的网站建设服务yande搜索引擎官网入口
  • 品牌网站如何做seo西安seo排名外包