OpenResty 从入门到实战
温铭
OpenResty 软件基金会第一任主席,Apache APISIX 项目 VP
20903 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 52 讲
结束语 (1讲)
OpenResty 从入门到实战
15
15
1.0x
00:00/00:00
登录|注册

43 | 灵活实现动态限流限速,其实没有那么难

combine 函数
leaving 接口
使用方法
限制并发连接数
incoming 函数返回值
使用方法
限制请求数
自定义 key
incoming 函数
使用方法
漏桶算法
未来发展
OpenResty 的优势
业务需求
支持的限速器
限速器的组合
limit-conn
limit-count
limit-req
使用 Lua 脚本
局限性
总结
limit.traffic
OpenResty 的动态限流限速
Nginx 配置文件的限流限速
漏桶和令牌桶算法
灵活实现动态限流限速

该思维导图由 AI 生成,仅供参考

你好,我是温铭。
前面的课程中,我为你介绍了漏桶和令牌桶算法,它们都是应对突发流量的常用手段。同时,我们也学习了如何通过 Nginx 配置文件的方式,来实现对请求的限流限速。不过很显然,使用 Nginx 配置文件的方式,仅仅停留在可用的层面,距离好用还是有不小的距离的。
第一个问题便是,限速的 key 被限制在 Nginx 的变量范围内,不能灵活地设置。比如,根据不同的省份和不同的客户端渠道,来设置不同的限速阈值,这种常见的需求用 Nginx 就没有办法实现。
另外一个更大的问题是,不能动态地调整速率,每次修改都需要重载 Nginx 服务,这一点我们在上节课的最后也提到过。这样一来,根据不同的时间段限速这种需求,就只能通过外置的脚本来蹩脚地实现了。
要知道,技术是为业务服务的,同时,业务也在驱动着技术的进步。在 Nginx 诞生的时代,并没有什么动态调整配置的需求,更多的是反向代理、负载均衡、低内存占用等类似的需求,在驱动着 Nginx 的成长。在技术的架构和实现上,并没有人能够预料到,在移动互联网、IoT、微服务等场景下,对于动态和精细控制的需求会大量爆发。
而 OpenResty 使用 Lua 脚本的方式,恰好能够弥补 Nginx 在这方面的缺失,形成了有效的互补。这也是 OpenResty 被广泛地用于替换 Nginx 的根源所在。在后面几节课中,我会为你继续介绍更多 OpenResty 中动态的场景和示例。今天,就让我们先来看下,如何使用 OpenResty 来实现动态限流和限速。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

使用OpenResty实现动态限流和限速是一种灵活的解决方案。本文介绍了OpenResty通过Lua脚本来弥补Nginx配置文件在动态调整速率方面的不足。详细介绍了在OpenResty中使用limit-req、limit-count和limit-conn这三种不同的限制方式,以及如何组合使用这些限速器来满足复杂的业务需求。通过示例代码和解释,读者可以了解如何使用这些限速器来限制请求速率、请求次数和并发连接数,并且可以根据不同的需求设置不同的限速阈值和key,实现灵活的限流限速效果。文章还提到了limit.traffic的功能,可以管理任何有incoming和uncommit接口的限速器。最后,作者留下了一个作业题,鼓励读者分享和交流。整体而言,本文通过介绍OpenResty的限速器的使用方法,为读者提供了一种灵活实现动态限流限速的解决方案。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《OpenResty 从入门到实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(8)

  • 最新
  • 精选
  • FF
    请教个问题。如果把 lua 模块用 lua_by_* 的方式引入 ngx 的 location 指令块里面,那每次请求,都会执行一遍 lua 模块中的 top level 变量和那些不是定义在函数中的全局代码块吗 ? 我测了一下好像每次请求都执行一遍 ?那全局变量不是每次请求都要初始化一次啊 ?这样的话如果想在函数执行的上下文中再将一些数据保存到全局变量里面,那不是没办法用全局变量实现了 ? 盼温老师解惑。

    作者回复: 如果你要使用全局变量, 可以写到 init 阶段,这样就只会执行一遍了。但是全局变量是不推荐使用的,在最新的OpenResty 1.15.8 版本中,增加了全局变量的检测,如果发现就会打印一条 warn 级别的日志。 如果你希望保持函数上下文的全局数据,可以试试模块的 top level 变量。 同时,在你测试的时候,记得保持 lua_code_cache on,并且不要在 Windows 下测试。

    2019-09-03
    2
  • wusiration
    老师,限制器的组合小节里面的代码,limit_req重复了,应该有一个limit_count。 课后习题: local limit_rate = require "resty.limit.rate" local limit_count = require "resty.limit.count" local limit_conn = require "resty.limit.conn" local lim_rate, err = limit_rate.new("my_rate_store", 100, 6000, 2) -- 将resty.limit.req替换成resty.limit.rate即可 local lim_count, err = limit_count.new("my_count_store", 200, 100) local lim_conn, err = limit_conn.new("my_conn_store", 1000, 1000, 0.5) local limiters = {lim_rate, lim_count, lim_conn} local host = ngx.var.host local client = ngx.var.binary_remote_addr local keys = {host, client, client} local delay, err = limit_traffic.combine(limiters, keys, states)

    作者回复: 多谢指正,看的真仔细👍

    2019-09-02
    2
  • Sir
    老师好,我把这段代码也在location中,是不是相当于我每次请求都new了一次,比较迷惑 local lim, err = limit_req.new("my_limit_req_store", 200, 100)

    作者回复: 这种对象的 new 一般都是放在 module 的 top level 中,避免重复创建

    2019-09-18
    2
  • jackstraw
    老师,这里的限流都是针对一台NGINX的,我们的业务是N台NGINX同时提供服务的,这种情况下可以怎么做限流啊?
    2019-12-20
    1
    9
  • 温暖岁月
    老师,请教个问题,对于limit_rate限速配置,如果是动态去改这个值,对于已经在下载的连接来说是没有作用的,该如何让已经连上的也生效?
    2020-12-29
    1
  • 张靳
    之前有用过limit-req方法,tps比较高的时候不是很准,老师有遇到过吗
    2022-02-08
  • 春夏秋冬
    老师,我想要将限速限流参数放置在memcached中,每次请求时通过读取相关的配置来达到动态配置限流限速的功能(代码如下),当我扩大memcached中limit_num值后,发现返回的剩余的调用次数(remaining)并未发生变化,其中原理并不清楚,期望老师解惑或者提供更好的动态修改限流配置的方向 local memcached = require "resty.memcached" local memc, err = memcached:new() memc:set_timeout(1000) local ok, err = memc:connect("127.0.0.1", 11211) local limit_num, flags, err = memc:get("limit_num") local limit_time, flags, err = memc:get("limit_time") local limit_count = require "resty.limit.count" local lim, err = limit_count.new("global_count_limit", tonumber(limit_num), tonumber(limit_time)) local delay, remaining = lim:incoming('global', true) if not delay then return ngx.exit(503) end ngx.say(remaining)
    2019-11-10
    1
  • 许童童
    跟着老师一起精进。
    2019-09-02
收起评论
显示
设置
留言
8
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部