前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >开放API网关实践(三) —— 限流

开放API网关实践(三) —— 限流

作者头像
草堂笺
发布于 2019-12-20 09:45:33
发布于 2019-12-20 09:45:33
1.4K00
代码可运行
举报
文章被收录于专栏:代码如诗代码如诗
运行总次数:0
代码可运行

.example_responsive_1 { width: 200px; height: 50px; } @media(min-width: 290px) { .example_responsive_1 { width: 270px; height: 50px; } } @media(min-width: 370px) { .example_responsive_1 { width: 339px; height: 50px; } } @media(min-width: 500px) { .example_responsive_1 { width: 468px; height: 50px; } } @media(min-width: 720px) { .example_responsive_1 { width: 655px; height: 50px; } } @media(min-width: 800px) { .example_responsive_1 { width: 728px; height: 50px; } } (adsbygoogle = window.adsbygoogle || []).push({});

开放API网关实践(三) —— 限流

目录

如何设计实现一个轻量的开放API网关之限流 文章地址: https://cloud.tencent.com/developer/article/1557579

前言

开发高并发系统时有多重系统保护手段, 如缓存、限流、降级等. 在网关层, 限流的应用比较广泛. 很多情况下我们可以认为网关上的限流与业务没有很强的关联(与系统的承载能力有关), 且各个子系统都有限流这种需求, 将部分限流功能放到网关会比较合适.

什么是限流

众所周知, 服务器、网站应用的处理能力是有上限的, 不论配置有多高总会有一个极限, 超过极限如果放任继续接收请求, 可能会发生不可控的后果.

举个栗子?, 节假日网上购票, 常常会遇到排队中系统繁忙请稍后再试等提示, 这便是服务端对单位时间处理请求的数量进行了限制, 超出限制就会排队、降级甚至拒绝服务, 否则如果把系统搞崩了, 大家都买不到票了╮( ̄▽ ̄)╭.

我们先给出限流的定义: 限流是高并发系统保护保护手段之一, 在网关层的应用很广泛. 其目的是对并发请求进行限速或限制一个时间窗口内请求的数量, 一旦达到阈值就排队等待或降级甚至拒绝服务.

其最终目的是: 在扛不住过高并发的情况下做到有损服务而不是不服务.

常用限流玩法

令牌桶

令牌桶算法, 是一个存放固定数量令牌的桶按照固定速率添加令牌. 如图:

  • 按照固定速率向桶中添加令牌.
  • 桶满时拒绝增加新令牌.
  • 每次请求消耗一个令牌(也可根据数据包大小来消耗对应的令牌数).
  • 当令牌不足时, 拒绝请求(或等待).
  • 特点: 可以应对一定程度的突发.

举个现实生活中比较常见的例子来理解, 电影院售票, 每场电影所售出的票数是一定的, 如果来晚了(后面的请求)就没票了, 要么等待下一场(等待新的令牌发放), 要么不看了(被拒绝).

漏桶

漏桶是一个底部破洞的桶, 水可以匀速流出(这时候不考虑压强, 不要杠( ̄. ̄)), 所以与令牌桶不一样的是, 漏桶算法是匀速消费, 可以用来进行流量整形流量控制. 如图:

  • 固定容量的漏桶, 按照固定速率流出水(不要杠水深和压强的问题).
  • 流入水的速率固定, 溢出则被丢弃.
  • 特点: 平滑流入速率.

版权声明

代码语言:txt
AI代码解释
复制
 本文发布于[朴瑞卿的博客](https://blog.piaoruiqing.com/), 允许非商业用途转载, 但转载必须保留原作者[朴瑞卿](https://blog.piaoruiqing.com/) 及链接:[https://blog.piaoruiqing.com](https://blog.piaoruiqing.com/).
代码语言:txt
AI代码解释
复制
 如有授权方面的协商或合作, 请联系邮箱: [piaoruiqing@gmail.com](https://blog.piaoruiqing.com/mailto:piaoruiqing@gmail.com). 

应用级限流

一个单体的应用程序有其承受极限, 在高并发情况下, 有必要进行过载保护, 以防过多的请求将系统弄崩. 最简单粗暴的方式就是使用计数器进行控制, 处理请求时+1, 处理完毕后-1, 除此之外我们还可以利用前文提到的令牌桶和漏桶来进行更精细的限流.如果网关是单体应用, 我们完全可以不借助其他介质, 直接在应用级别进行限流.

计数器

这种方式实现最简单粗暴,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
try {
    if (counter.incrementAndGet() > limit) {
        throw new SomeException();
    }
    // do something
} finally {
    counter.decrementAndGet();
}

令牌桶

Guava提供了令牌桶算法的实现.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void testGuavaRateLimiter() throws InterruptedException {
    RateLimiter limiter = RateLimiter.create(5);
    TimeUnit.SECONDS.sleep(1);  // 等待一秒钟发几个令牌
    for (int index = 0; index < 10; index++) {
        System.out.println(limiter.acquire()); // 打印等待时间
    }
}

输出为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
0.0
0.0
0.0
0.0
0.0
0.0
0.196108
0.194372
0.19631
0.198373

在令牌用尽后, 后面的请求都要等待有新的令牌后才能继续执行.

应用级限流实现简单, 但其局限性在于无法进行全局限流, 对于集群就无能为力了.

分布式限流

想要在集群中进行全局限流, 其关键在于将限流信息记录在共享介质中, 如Redismemcached等. 为了将限流做的精确, 写必须是原子操作.

Redis+Lua是一个不错的选择, 示例Lua脚本如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
local key = KEYS[1] -- 限流的KEY
local limit = tonumber(ARGV[1]) -- 限流大小
local current = tonumber(redis.call('get', key) or '0')
if current + 1 > limit then
    return 0
else
    redis.call('INCRBY', key,'1')
    redis.call('expire', key,ARGV[2])   -- 过期时间
    return current + 1
end
  • 分布式限流将令牌的发放放到共享介质中.
  • 获取(消费)令牌操作必须是原子的.
  • 共享介质要高可用(Redis集群)

结语

网关作为内部系统外的一层屏障, 对内起到一定的保护作用, 限流便是其中之一. 网关层的限流可以简单地针对不同业务的接口进行限流, 也可考虑将限流功能做成网关的一个功能模块(如限流规则的配置、统计、针对用户维度进行统计和限流等)

© 2019, 朴瑞卿.

版权声明

代码语言:txt
AI代码解释
复制
 本文发布于[朴瑞卿的博客](https://blog.piaoruiqing.com/), 允许非商业用途转载, 但转载必须保留原作者[朴瑞卿](https://blog.piaoruiqing.com/) 及链接:[https://blog.piaoruiqing.com](https://blog.piaoruiqing.com/).      如有授权方面的协商或合作, 请联系邮箱: [piaoruiqing@gmail.com](https://blog.piaoruiqing.com/mailto:piaoruiqing@gmail.com).
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
秒杀场景实践之抢红包(一) —— 常用解决方案
.example_responsive_1 { width: 200px; height: 50px; } @media(min-width: 290px) { .example_responsive_1 { width: 270px; height: 50px; } } @media(min-width: 370px) { .example_responsive_1 { width: 339px; height: 50px; } } @media(min-width: 500px) { .example_responsive_1 { width: 468px; height: 50px; } } @media(min-width: 720px) { .example_responsive_1 { width: 655px; height: 50px; } } @media(min-width: 800px) { .example_responsive_1 { width: 728px; height: 50px; } } (adsbygoogle = window.adsbygoogle || []).push({});
草堂笺
2019/12/20
1.4K0
开放API网关实践(二) —— 重放攻击及防御
.example_responsive_1 { width: 200px; height: 50px; } @media(min-width: 290px) { .example_responsive_1 { width: 270px; height: 50px; } } @media(min-width: 370px) { .example_responsive_1 { width: 339px; height: 50px; } } @media(min-width: 500px) { .example_responsive_1 { width: 468px; height: 50px; } } @media(min-width: 720px) { .example_responsive_1 { width: 655px; height: 50px; } } @media(min-width: 800px) { .example_responsive_1 { width: 728px; height: 50px; } } (adsbygoogle = window.adsbygoogle || []).push({});
草堂笺
2019/12/20
2K0
开放API网关实践(二) —— 重放攻击及防御
记一次Redis连接超限排查
.example_responsive_1 { width: 200px; height: 50px; } @media(min-width: 290px) { .example_responsive_1 { width: 270px; height: 50px; } } @media(min-width: 370px) { .example_responsive_1 { width: 339px; height: 50px; } } @media(min-width: 500px) { .example_responsive_1 { width: 468px; height: 50px; } } @media(min-width: 720px) { .example_responsive_1 { width: 655px; height: 50px; } } @media(min-width: 800px) { .example_responsive_1 { width: 728px; height: 50px; } } (adsbygoogle = window.adsbygoogle || []).push({});
草堂笺
2019/12/20
1.6K0
记一次Redis连接超限排查
MySQL查漏补缺
.example_responsive_1 { width: 200px; height: 50px; } @media(min-width: 290px) { .example_responsive_1 { width: 270px; height: 50px; } } @media(min-width: 370px) { .example_responsive_1 { width: 339px; height: 50px; } } @media(min-width: 500px) { .example_responsive_1 { width: 468px; height: 50px; } } @media(min-width: 720px) { .example_responsive_1 { width: 655px; height: 50px; } } @media(min-width: 800px) { .example_responsive_1 { width: 728px; height: 50px; } } (adsbygoogle = window.adsbygoogle || []).push({});
草堂笺
2019/12/20
2.5K0
用了这么久HTTP, 你是否了解Content-Length和Transfer-Encoding ?
.example_responsive_1 { width: 200px; height: 50px; } @media(min-width: 290px) { .example_responsive_1 { width: 270px; height: 50px; } } @media(min-width: 370px) { .example_responsive_1 { width: 339px; height: 50px; } } @media(min-width: 500px) { .example_responsive_1 { width: 468px; height: 50px; } } @media(min-width: 720px) { .example_responsive_1 { width: 655px; height: 50px; } } @media(min-width: 800px) { .example_responsive_1 { width: 728px; height: 50px; } } (adsbygoogle = window.adsbygoogle || []).push({});
草堂笺
2019/12/20
8230
用了这么久HTTP, 你是否了解Content-Length和Transfer-Encoding ?
Kubernetes(二) 应用部署
.example_responsive_1 { width: 200px; height: 50px; } @media(min-width: 290px) { .example_responsive_1 { width: 270px; height: 50px; } } @media(min-width: 370px) { .example_responsive_1 { width: 339px; height: 50px; } } @media(min-width: 500px) { .example_responsive_1 { width: 468px; height: 50px; } } @media(min-width: 720px) { .example_responsive_1 { width: 655px; height: 50px; } } @media(min-width: 800px) { .example_responsive_1 { width: 728px; height: 50px; } } (adsbygoogle = window.adsbygoogle || []).push({});
草堂笺
2019/12/20
1K0
Kubernetes(二) 应用部署
如何设计实现一个轻量的开放API网关
随着业务的发展, 所对接的第三方越来越多, 各个业务系统面临着同样一个问题: 如何让第三方安全快速接入. 此时有一个集验签、鉴权、限流、降级等功能于一身的API网关服务变得尤为重要.
Bug开发工程师
2019/08/27
2.1K0
如何设计实现一个轻量的开放API网关
高并发系统支撑---限流算法
有些场景并不能用缓存和降级来解决,比如写服务、频繁的复杂查询,因此需有一种手段来限制这些场景的并发/请求量,即限流。
一条老狗
2019/12/26
8590
我是如何通过Nginx日志实时封禁风险IP的
.example_responsive_1 { width: 200px; height: 50px; } @media(min-width: 290px) { .example_responsive_1 { width: 270px; height: 50px; } } @media(min-width: 370px) { .example_responsive_1 { width: 339px; height: 50px; } } @media(min-width: 500px) { .example_responsive_1 { width: 468px; height: 50px; } } @media(min-width: 720px) { .example_responsive_1 { width: 655px; height: 50px; } } @media(min-width: 800px) { .example_responsive_1 { width: 728px; height: 50px; } } (adsbygoogle = window.adsbygoogle || []).push({});
草堂笺
2019/12/20
1.2K0
我是如何通过Nginx日志实时封禁风险IP的
看完这篇,轻松get限流!
限流,也叫速率限制(Rate Limiting),是一种限制请求速率的技术。通常用于保护服务自身,或在下游服务已知无法保护自身的情况下,保护下游服务
一只小黄鱼
2022/08/02
1.4K0
看完这篇,轻松get限流!
最近学到的限流知识
之前在学习的时候也接触不到高并发/大流量这种东西,所以限流当然是没接触过的了。在看公司项目的时候,发现有用到限流(RateLimiter),顺带了解一波。
Java3y
2019/09/12
5380
最近学到的限流知识
读书笔记:限流详解
在压测时我们可以找出每个系统的处理峰值,然后通过设定峰值阈值,来防止当系统过载时,通过拒绝处理过载的请求来保障系统可用。
看、未来
2021/12/07
3430
分布式环境下限流方案的实现redis RateLimiter Guava,Token Bucket, Leaky Bucket
对于web应用的限流,光看标题,似乎过于抽象,难以理解,那我们还是以具体的某一个应用场景来引入这个话题吧。在日常生活中,我们肯定收到过不少不少这样的短信,“双11约吗?,千款….”,“您有幸获得唱读卡,赶快戳链接…”。这种类型的短信是属于推广性质的短信。为什么我要说这个呢?听我慢慢道来。一般而言,对于推广营销类短信,它们针对某一群体(譬如注册会员)进行定点推送,有时这个群体的成员量比较大,甚至可以达到千万级别。因此相应的,发送推广短信的量也会增大。然而,要完成这些短信发送,我们是需要调用服务商的接口来完成的。倘若一次发送的量在200万条,而我们的服务商接口每秒能处理的短信发送量有限,只能达到200条每秒。那么这个时候就会产生问题了,我们如何能控制好程序发送短信时的速度昵?于是限流这个功能就得加上了
用户6182664
2020/05/11
5.9K0
面试官:网关如何实现限流?
网关(Gateway)是微服务中不可缺少的一部分,它是微服务中提供了统一访问地址的组件,充当了客户端和内部微服务之间的中介。网关主要负责流量路由和转发,将外部请求引导到相应的微服务实例上,同时提供一些功能,如身份认证、授权、限流、监控、日志记录等。
磊哥
2023/11/20
5800
面试官:网关如何实现限流?
SpringCloudGateway限流原理与实践
限制总并发数、限制瞬时并发数、限制时间窗口内的平均速率、限制远程接口的调用速率、限制MQ的消费速率,或根据网络连接数、网络流量、CPU或内存负载等来限流。
JavaEdge
2021/02/22
1.3K0
SpringCloudGateway限流原理与实践
Spring Cloud 分布式服务限流实战,已经为你排好了
在一个分布式高并发的系统设计中,限流是一个不可忽视的功能点。如果不对系统进行有效的流量访问限制,在双十一和抢票这种流量洪峰的场景下,很容易就会把我们的系统打垮。而作为系统服务的卫兵的网关组件,作为系统服务的统一入口,更需要考虑流量的限制,直接在网关层阻断流量比在各个系统中实现更合适。Spring Cloud Gateway的实现中,就提供了限流的功能,下面主要分析下Spring Cloud Gateway中是如何通过一段lua脚本实现限流功能的。
搜云库技术团队
2019/12/24
1.3K0
使用Redis实现限流
在分布式系统中,限流是保护服务的重要手段之一。通过限流,可以防止接口被恶意刷请求或突发流量压垮,从而保证系统的稳定性。Redis是一个高性能的键值存储工具,因其高效的读写性能和丰富的数据结构,被广泛用于限流场景。本文将介绍三种使用Redis实现限流的方式,并通过代码示例说明其实现原理和应用场景。
用户11397231
2024/12/23
2920
使用Redis实现限流
常见限流算法解读
在现在的互联网系统中有很多业务场景,比如商品秒杀、下单、数据查询详情,其最大特点就是高并发,但是我们的系统通常不能承受这么大的流量,继而产生了很多的应对措施:消息队列、多级缓存、异地多活。但是无论如何优化,由于硬件的物理特性决定了我们系统性能的上限,如果强行接收所有请求,往往造成服务雪崩,导致服务的不可用,这个时候服务限流就成为我们必不可少的一个手段了。
一个风轻云淡
2023/11/15
6770
大厂面试必备--分布式限流,一篇文章搞定
缓存比较好理解,在大型高并发系统中,如果没有缓存数据库将分分钟被爆,系统也会瞬间瘫痪。使用缓存不单单能够提升系统访问速度、提高并发访问量,也是保护数据库、保护系统的有效方式。大型网站一般主要是“读”,缓存的使用很容易被想到。在大型“写”系统中,缓存也常常扮演者非常重要的角色。比如累积一些数据批量写入,内存里面的缓存队列(生产消费),以及HBase写数据的机制等等也都是通过缓存提升系统的吞吐量或者实现系统的保护措施。甚至消息中间件,你也可以认为是一种分布式的数据缓存。
三哥
2020/05/26
1.8K0
大厂面试必备--分布式限流,一篇文章搞定
常见限流方案设计与实现
编者注:高并发系统设计的3个利器:缓存、限流、降级,本文就限流相关算法,分析其设计与实现。
luoxn28
2019/11/06
1.1K0
相关推荐
秒杀场景实践之抢红包(一) —— 常用解决方案
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验