前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >分布式限流

分布式限流

作者头像
dys
发布2019-03-07 10:36:37
1.9K0
发布2019-03-07 10:36:37
举报
文章被收录于专栏:性能与架构性能与架构

一、限流

在高并发系统中,需要使用多种方式来保护系统,例如:

  • 缓存,目的是提升系统访问速度,增大系统处理能力。
  • 降级,当服务器压力剧增的时候,根据实际业务情况,对某些服务或者页面有策略的不处理或者简单处理,从而释放服务器资源,以保证核心业务正常运行,通过牺牲局部利益来保证全局利益。
  • 限流,目的是通过对请求进行限速来保护系统,如果达到限速值就可以采取一定的手段,例如拒绝服务、排队、等待。

所以,限流是保证系统高可用的重要手段。

二、分布式限流

在单机系统中,限流逻辑直接放在服务接口中即可,Guava RateLimiter 可以方便的实现。

但在分布式系统中,一个服务可能启动多个实例,需要对服务整体进行限流,就不能放在每个实例中进行限流判断了,需要统一管理,例如放到API网关中:

分布式限流最关键的是要将限流服务做成原子化,常见的方案是 Redis+Lua 和 Nginx+Lua。

三、Redis + Lua 实现方式

Lua 代码:

-- 获取调用脚本时传入的第一个key值(用作限流的 key)
local key = KEYS[1]
-- 获取调用脚本时传入的第一个参数值(限流大小)
local limit = tonumber(ARGV[1])

-- 获取当前流量大小
local curentLimit = tonumber(redis.call('get', key) or "0")

-- 是否超出限流
if curentLimit + 1 > limit then
    -- 返回(拒绝)
    return 0
else
    -- 没有超出 value + 1
    redis.call("INCRBY", key, 1)
    -- 设置过期时间
    redis.call("EXPIRE", key, 2)
    -- 返回(放行)
    return 1
end

Redis 是单线程,如上的限流逻辑是在 Lua 脚本中,是线程安全的。

Java 调用示例代码:

public boolean limit() throws Exception {
    String luaScript = Files.toString(
            new File("limit.lua")
            , Charset.defaultCharset());
    Jedis jedis = new Jedis(ip, port);
    
    String key = "ip:" 
            + System.currentTimeMillis()/1000;
    String limit = "3";
    ArrayList<String> scriptKeys = 
            Lists.newArrayList(key);
    ArrayList<String> scriptArgs = 
            Lists.newArrayList(limit);
    
    return (Long)jedis.eval(
            luaScript, 
            scriptKeys, 
            scriptArgs) == 1;
}

点击?阅读原文,查看文章列表

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-02-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JAVA高性能架构 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、限流
  • 二、分布式限流
  • 三、Redis + Lua 实现方式
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档