首先,说一下支持的流控种类:
- 基于时间分片的流控,限制每分钟允许发生多少次调用。这种情况下的流控,对一段时间内的速度控制,一般分成两种:
- 均一化流控:将速度均匀分布,比如说我们限制某个访问为每分钟1200次,那么程序控制粒度就是在每50ms,允许调用一次。
- 爆发式流控:同样是上面的要求,爆发式的流控会拿出一部分限额,尽快满足调用请求,在达到爆发的阀值时间或次数限制后,根据策略的不同,将速度调整下来,然后将后续访问速度降档成归一化流控。而当流控速度下降到一定阶段后,又会恢复爆发式策略。从而尽快将业务处理完成。爆发式的流控策略适合于瞬发业务的处理,不适合长时间连续性业务流控(速率不稳定)。
- 限额累积流控:和爆发式流控类似,但是采用的将上一阶段未使用的限额累积到下一阶段,从而实现总流量可控的限流策略。这个策略直观点,就像是手机的流量套餐,这个月用不了的,可以累积到下个月继续使用,但用光就真正没有用的了,此时只能通过增加临时配额的方式,满足额外的业务需要。
- 基于处理资源限制的流控,限制同时有多少个同时处理的任务。这种情况下的流控,不会限制处理的速度,只会限制同时处理的任务数量配额。当一个配额空闲出来后,立刻调度新的任务使用这个配额。没有得到配额的任务,只能在任务队列中排队等待处理。
那么,基于上面的思路,我们就定义了流控接口规则如下:
- 基于时间片的流控,有两种实现模式:
- 分布管控的模式(IZFlowControlItem):用户创建一个流控对象,然后直接操作这个对象来获取流控的效果。
- 集中管控的模式(TZFlowControler.Current):用户通过一个预定义的标志来关联流控对象,当需要时,向集中的管理器申请调度。实际上内部维护了一个字典列表,这个字典负责将标志快速映射到对应的流控对象,然后由流控对象完成实际的流量控制。
- 基于处理资源限制的流控,我们也考虑两种情况:
- 资源总数明确的情况下,循环处理每一个请求(IZOrdinalLoopControler),此时将原始请求集合可以当成一个有序数组,通过索引直接访问对应的请求内容进行处理。
- 资源总数不明确的情况下,首先调用 First 获取首个资源,然后循环调用 Next 获取下一个资源,直到 Next 返回 False(IZIterateLoopControler)。
好了,本文仅是思想的说明,有兴趣的同学可以自行实现。真正的作品归吉林省左右软件开发有限公司所有,属于 Z 系列开源付费框架的一部分,产品完成具体时间待定。