小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。
1、简介
令牌桶算法比较简单,它就好比摇号买房,拿到号的人才有资格买,没拿到号的就只能等下次了(还好小编不需摇号,因为买不起!)。
在实际的开发中,系统会维护一个容器用于存放令牌(token),并且系统以一个固定速率往容器中添加令牌(token),这个速率通常更加系统的处理能力来权衡。当客户端的请求打过来时,需要从令牌桶中获取到令牌(token)之后,这个请求才会被处理,否则直接拒绝服务。
令牌桶限流的关键在于发放令牌的速率和令牌桶的容量。\
实现令牌桶限流的方式有很多种,本文讲述的是基于Redis的Redis-Cell限流模块,这是Redis提供的适用于分布式系统、高效、准确的限流方式,使用十分广泛,而且非常简单!
2、Redis-Cell的安装
Redis默认是没有集成Redis-Cell这个限流模块的,就好比Redis使用布隆过滤器一样,我们也需要对该模块进行安装与集成。
2.1 GitHub源码&安装包
Redis-Cell的GitHub地址:
Redis-Cell基于Rust语言开发,如果不想花费精力去搞Rust环境,那么可以直接下载与你的操作系统对应的安装包(这个很关键,我就安装了挺多次的,如果安装的问题比较多的话,也建议降低一个release版本!)\
image.png
下载对应的安装包:
如果不清楚自己的服务器(Linux)版本的,可以事先查看后再下载安装包:
1 | bash复制代码# Linux 查看当前操作系统的内核信息 |
2.2 安装&异常处理
- 在Redis的安装目录的同级目录下,新建文件夹Redis-Cell,将压缩包上传后解压
1 | sql复制代码tar -zxvf redis-cell-v0.2.5-powerpc64-unknown-linux-gnu.tar.gz |
- 解压后出现如下文件,复制libredis_cell.so文件的路径(pwd查看当前路径
- 修改Redis配置文件,redis.conf,添加完成后记得保存后再退出
- 重启Redis,如果启动正常,进入redis客户端,通过module list查看挂载的模块是否有Redis-Cell
- 测试指令,出现如下情况说明集成Redis-Cell成功
- 如果重启Redis后,客户端无法连接成功,说明Redis启动失败,这个时候我们需要查看Redis的启动日志,如果已经配置日志文件的可以直接查看日志定位问题,如果还未配置日志文件的需要先配置日志文件,redis.conf添加日志文件路径地址,再次重启,查看日志文件输出的错误日志
- 错误可能千奇百怪,问题不大搞技术就不要心急,一个个解决,我这里记录下我最后遇到的问题, /lib64/libc.so.6: version `GLIBC_2.18‘ not found
1 | lua复制代码43767:M 08 Sep 2021 21:39:39.643 # Module /usr/local/soft/Redis-Cell-0.3.0/libredis_cell.so failed to load: /lib64/libc.so.6: version `GLIBC_2.18' not found (required by /usr/local/soft/Redis-Cell-0.3.0/libredis_cell.so) |
- 缺失GLIBC_2.18,那就安装它(最后两个编译的过程时间比较长,耐心等待几分钟)
1 | bash复制代码yum install gcc |
- 安装完成后,重启Redis,测试是否安装成功,循环上面的过程,通过日志分析错误即可
3、CL.THROTTLE指令
指令CL.THROTTLE参数含义
1 | scss复制代码CL.THROTTLE liziba 10 5 60 1 |
输出参数值含义
1 | bash复制代码127.0.0.1:6379> cl.throttle liziba 10 5 60 1 |
这里唯一有歧义的可能是max_burst,这个并不是令牌桶的最大容量,从作者的README.md中的解释也可以看出来
The total limit of the key (max_burst + 1). This is equivalent to the common X-RateLimit-Limit HTTP header.
4、Java调用Redis-Cell模块实现限流
4.1 导入依赖
1 | xml复制代码<dependency> |
4.2 实现代码
Redis命令接口定义:
1 | java复制代码package com.lizba.redis.limit.tokenbucket; |
Redis-Cell令牌桶限流类定义:
1 | java复制代码package com.lizba.redis.limit.tokenbucket; |
测试代码:
1 | java复制代码package com.lizba.redis.limit.tokenbucket; |
测试结果(这里也说明了令牌桶的容量是max_burst + 1):
1 | 复制代码第0次请求成功 |
本文转载自: 掘金