服务端需要调用第三方 API,但是第三方 API 有调用频率限制,多次超出调用频率会被拉黑。目前用线程池来调 API,怎么才能控制服务器端每分钟调用次数不超过指定数量,比如每分钟不超过 500 次。
|
1
guava 有 ratelimiter
|
|
itechifyMay 29, 2019 via Android
2
用变量来记录当前时间分钟对应的调用次数可以否?到下一分钟,重置为 0,这分钟内每次调用增加 1,到 500 提示失败
|
|
itechifyMay 29, 2019 via Android
3
我渣渣哈哈~没做过这个东西,胡乱猜想的
|
|
5
@oneisall8955 我也这么想过,但是后来一想,如果负责置 0 的那个线程阻塞或者发生什么意外,那就 gg 了
|
|
securityCodingMay 29, 2019
9
1. guava 单机限流
2.阿里开源的 Sentine |
|
l8gMay 29, 2019
10
单机可以看下 Guava 的 RateLimiter
分布式场景下用 Redis 的 zset 做个简单的限流也可以 |
|
palmersMay 29, 2019
11
|
|
12
|
|
dawncoldMay 29, 2019
13
一个好的 API 设计会告诉你当前时间窗口还剩多少次调用,遵照执行就好
|
|
gz911122May 29, 2019
14
rxjava 被压
|
|
CoderGeekMay 30, 2019
15
简单的限流就可以实现 楼上都说了
|
|
xuanbgMay 30, 2019
16
redis 里面搞一个过期时间为 1 分钟的 key 作为计数器,读到计数器到达 500 了,就报调用失败或者扔到队列里面去等下一分钟再调用。队列可以满足削峰的需求,但不能满足你每分钟平均次数超过 500 的需求。如果平均每分钟超过 500 的话,只能报错了。
|
|
jorneyrMay 30, 2019
17
一文搞懂 Nginx 限流,原来这么简单 https://www.toutiao.com/i6694571806835081742/,用这个就不用写代码了
|
|
lihongjie0209May 30, 2019
18
老老实实写日志到 redis 或者是数据库中, 调用之前先查询一下日志.
基于 guava 这种内存型的, 服务器重启就 GG 了. |
|
ainoMay 30, 2019
19
俺用的 RateLimiter
|
|
luozicMay 30, 2019 via iPhone
20
kong/其他平台的网关
|
|
21
@jorneyr 是限制我方调用第三方 API 的频率,不是限制客户端调我方 API 的频率😂,不过还是感谢哈,Nginx 还可以这么用
|
|
22
@lihongjie0209 哈哈,只是限制每分钟的调用频率,不限制历史总的调用次数的
|
|
lzxz1234May 30, 2019
23
选定一个时间单位,记录这个时间段内所有请求发出去的时间,每次请求时查看最早的那个请求时间,大于时间单位通过并更新请求时间,否则等待或者返回 false,一个循环数组就可以搞定了,根据目标频率选一个合适的大小就可以
|
|
clarkyiMay 30, 2019
24
guava 这种不支持分布式吧?多台设备就 gg 了,redis+guava 考虑一下
|
|
lihongjie0209May 30, 2019
25
|
|
cyhulkMay 30, 2019
26
@lihongjie0209 要看场景的,如果是考虑性能问题限制次数,重启了,重新 300 也无所谓,反正服务器重启过了,300 也压的住,直接内存,相对于 redis 调用的性能损耗,要划算的多
|
|
luozicMay 30, 2019 via iPhone
27
网关也能干出去调用的,代理一下就行。
|
|
temp178May 30, 2019 via Android
28
单机的话简单的限流算法就可以 令牌桶算法之类的
|
|
vtoeeMay 30, 2019
29
有点类似于调百度地图 API 坐标转换
|
|
lihongjie0209May 30, 2019
30
@cyhulk 这个限制是第三方 API 的, 不是楼主的
|
|
EastLordMay 30, 2019
31
目测 阿里的 Sentine 满足楼主需求
|
|
zzzmodeMay 30, 2019
32
kong 网关
|
|
opengpsMay 30, 2019
33
如果是单机应用,服务器上装个安全狗之类的防护工具,可以对所有请求整体频率起效果。
如果只是某个接口调用,套了 cdn 则被忽视,不套上 cdn 的业务需要做个公共缓存统计,记录一个列表,每次请求顺便释放掉超时的缓存对象 |
|
opengpsMay 30, 2019
34
如果是单机单接口,那么可以利用系统自带缓存,或者本机 memcached 缓存做个计数(取出结果非等于 1 则++,等于 null 则赋值 1 ),超时时间就设置 1 分钟
|
|
gaiusMay 30, 2019
35
这问题我遇到过,1 时 0 分 1s 发了 500 个,2 时 0 分 2s 又发了 500,从 1s 到 2s 的这个时间窗口却是 1 小时发了 1000。
如果消费还有优先级的话,还再麻烦点。 |
|
gscoderMay 30, 2019
36
和限流是一样的方法:漏桶算法、令牌桶算法、滑动窗口算法。
|