函数保险丝:避免函数过热调用
2021.01.28
JerryC
搬砖码农
 热度
℃

前言
在日常开发中,我们会遇到很多这样的场景:
- 在抢购活动中,用户往往会频繁刷新接口,要给接口加上防护,频繁调用停止响应。
- 在弱网环境中,往往会实现失败重试功能,如果失败次数多了,频繁的重试需要制止。
- 在股票市场中,当价格波动的幅度在交易时间中达到某一个限定的熔断点时,对其暂停交易一段时间的机制。
- ……
这类问题,本质是:「过热的调用」
在物理电路中,对于「过热的调用」有一种大家生活中都常见的电子元件:保险丝
保险丝会在电流异常升高到一定的高度和热度的时候,自身熔断切断电流,保护电路安全运行。
我们可以模仿这样的思路,去解决编程中的「过热的调用」问题:
- 设定一个阈值,如果函数在短时间内调用次数达到这个阈值,就熔断一段时间。
- 在函数有一段时间没有被调用了,让函数的热度降下来。
函数保险丝的功能实现
基于以上的思路,我实现了一个 npm 库:Method Fuse
使用方式如下:
Step1:安装
npm install @jerryc/method-fuse
Step2:快速使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| import { MethodFuse } from '@jerryc/method-fuse'; const getAssets = async () => API.requestAssets(); const fuse = new MethodFuse({ name: 'TestFuse', maxLoad: 3, breakingTime: 5000, coolDownTime: 1000, }); const getAssetsProxy = fuse.proxy(getAssets); getAssetsProxy(); getAssetsProxy(); getAssetsProxy(); getAssetsProxy(); setTimeout(() => getAssetsProxy(), 5000);
|
Step3:使用装饰器
如果你的项目中支持 TS
或者 ES Decorator
,那么 MethodFuse
提供了快捷使用的装饰器。
1 2 3 4 5 6
| import { decorator as methodFuse } from '@jerryc/method-fuse'; @methodFuse({ name: 'TestFuse' }) async function getAsset() { return API.requestAssets(); };
|
Step4:修改日志级别
MethodFuse
内置了一个迷你 logger(power by @jerryc/mini-logger),方便内部日志打印,外部可以获得 Logger
的实例,进行 log level 的控制。
1 2 3 4 5 6 7 8
| import { LoggerLevel } from '@jerryc/mini-logger'; import { logger, MethodFuse } from '@jerryc/method-fuse'; const MethodFuse = new MethodFuse({ name: 'TestFuse' }); logger.level = LoggerLevel.ERROR;
|