请教, Java 怎么控制 API 调用的频率

2019-05-29 20:10:08 +08:00
 liaojl
服务端需要调用第三方 API,但是第三方 API 有调用频率限制,多次超出调用频率会被拉黑。目前用线程池来调 API,怎么才能控制服务器端每分钟调用次数不超过指定数量,比如每分钟不超过 500 次。
8756 次点击
所在节点    Java
36 条回复
liaojl
2019-05-30 09:42:44 +08:00
@jorneyr 是限制我方调用第三方 API 的频率,不是限制客户端调我方 API 的频率😂,不过还是感谢哈,Nginx 还可以这么用
liaojl
2019-05-30 09:44:05 +08:00
@lihongjie0209 哈哈,只是限制每分钟的调用频率,不限制历史总的调用次数的
lzxz1234
2019-05-30 10:31:58 +08:00
选定一个时间单位,记录这个时间段内所有请求发出去的时间,每次请求时查看最早的那个请求时间,大于时间单位通过并更新请求时间,否则等待或者返回 false,一个循环数组就可以搞定了,根据目标频率选一个合适的大小就可以
clarkyi
2019-05-30 11:41:23 +08:00
guava 这种不支持分布式吧?多台设备就 gg 了,redis+guava 考虑一下
lihongjie0209
2019-05-30 11:55:00 +08:00
@liaojl
00:00:03 秒调用了 300 次
00:00:05 服务器重启
00:00:40 重启成功
00:00:59 又调用了 300 次

总数超了
cyhulk
2019-05-30 12:46:48 +08:00
@lihongjie0209 要看场景的,如果是考虑性能问题限制次数,重启了,重新 300 也无所谓,反正服务器重启过了,300 也压的住,直接内存,相对于 redis 调用的性能损耗,要划算的多
luozic
2019-05-30 12:53:07 +08:00
网关也能干出去调用的,代理一下就行。
mejee
2019-05-30 13:02:51 +08:00
单机的话简单的限流算法就可以 令牌桶算法之类的
vtoee
2019-05-30 13:10:55 +08:00
有点类似于调百度地图 API 坐标转换
lihongjie0209
2019-05-30 13:15:23 +08:00
@cyhulk 这个限制是第三方 API 的, 不是楼主的
EastLord
2019-05-30 13:17:39 +08:00
目测 阿里的 Sentine 满足楼主需求
zzzmode
2019-05-30 13:23:04 +08:00
kong 网关
opengps
2019-05-30 13:27:11 +08:00
如果是单机应用,服务器上装个安全狗之类的防护工具,可以对所有请求整体频率起效果。
如果只是某个接口调用,套了 cdn 则被忽视,不套上 cdn 的业务需要做个公共缓存统计,记录一个列表,每次请求顺便释放掉超时的缓存对象
opengps
2019-05-30 13:29:08 +08:00
如果是单机单接口,那么可以利用系统自带缓存,或者本机 memcached 缓存做个计数(取出结果非等于 1 则++,等于 null 则赋值 1 ),超时时间就设置 1 分钟
gaius
2019-05-30 14:24:41 +08:00
这问题我遇到过,1 时 0 分 1s 发了 500 个,2 时 0 分 2s 又发了 500,从 1s 到 2s 的这个时间窗口却是 1 小时发了 1000。
如果消费还有优先级的话,还再麻烦点。
gscoder
2019-05-30 19:52:38 +08:00
和限流是一样的方法:漏桶算法、令牌桶算法、滑动窗口算法。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/568892

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX