92 | 项目实战一:设计实现一个支持各种算法的限流框架(实现)
王争
该思维导图由 AI 生成,仅供参考
上一节课,我们介绍了如何通过合理的设计,来实现功能性需求的同时,满足易用、易扩展、灵活、低延迟、高容错等非功能性需求。在设计的过程中,我们也借鉴了之前讲过的一些开源项目的设计思想。比如,我们借鉴了 Spring 的低侵入松耦合、约定优于配置等设计思想,还借鉴了 MyBatis 通过 MyBatis-Spring 类库将框架的易用性做到极致等设计思路。
今天,我们讲解这样一个问题,针对限流框架的开发,如何做高质量的代码实现。说的具体点就是,如何利用之前讲过的设计思想、原则、模式、编码规范、重构技巧等,写出易读、易扩展、易维护、灵活、简洁、可复用、易测试的代码。
话不多少,让我们正式开始今天的学习吧!
V1 版本功能需求
我们前面提到,优秀的代码是重构出来的,复杂的代码是慢慢堆砌出来的。小步快跑、逐步迭代是我比较推崇的开发模式。所以,针对限流框架,我们也不用想一下子就做得大而全。况且,在专栏有限的篇幅内,我们也不可能将一个大而全的代码阐述清楚。所以,我们可以先实现一个包含核心功能、基本功能的 V1 版本。
针对上两节课中给出的需求和设计,我们重新梳理一下,看看有哪些功能要放到 V1 版本中实现。
在 V1 版本中,对于接口类型,我们只支持 HTTP 接口(也就 URL)的限流,暂时不支持 RPC 等其他类型的接口限流。对于限流规则,我们只支持本地文件配置,配置文件格式只支持 YAML。对于限流算法,我们只支持固定时间窗口算法。对于限流模式,我们只支持单机限流。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
设计实现一个支持各种算法的限流框架是一项复杂而重要的任务。本文深入探讨了如何借鉴开源项目的设计思想,详细讲解了V1版本的功能需求,并展示了最小原型代码的目录结构和相关类的代码实现。重点剖析了代码的设计和实现,从可读性和扩展性两个方面进行了评估,并提出了重构建议。通过对MVP代码的重构,拆分出了限流规则加载的逻辑,并设计了抽象接口,以提高代码的扩展性。总结强调了优秀代码是通过重构得到的,鼓励采用小步快跑、逐步迭代的开发模式。读者可以从中学习到如何优化重构MVP代码,以及如何评估代码质量并针对性地进行优化。文章提出了课堂讨论问题,引发读者思考如何进行code review和重构,以及如何支持自定义限流规则配置文件名和路径。欢迎读者分享自己的想法,并将这篇文章分享给更多朋友,共同学习成长。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《设计模式之美》,新⼈⾸单¥98
《设计模式之美》,新⼈⾸单¥98
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(31)
- 最新
- 精选
- Jiehttps://github.com/wangzheng0822/ratelimiter4j 老师忘记在专栏里面放自己项目的地址了么,翻看隔壁算法之美发现的
作者回复: 感谢你的补充!
2020-06-05318 - 高源老师今天讲的骨架,有代码吗,我想结合你讲的自己再多考虑和分析,学习其中的方法解决的问题
作者回复: 代码都在文章里了,你也可以看下我github上的一个比较老的版本的,但写的比较详细 https://github.com/wangzheng0822
2020-06-037 - 杨杰1、在配置文件中是否应该指定默认的限流算法和每个api(或appid)对应的算法,在加载配置文件的时候自动生成这个配置算法的实例 2、在RateLimiter中的limit方法里面添加每个api对应的限流算法这个地方感觉有点儿不太好,如果每个API对应的限流算法都不一样会导致大量的If else 判断,是不是应该像第一点说的那样初始化的时候就自动生成了。
作者回复: 可以把选择哪种限流算法配置到配置文件中,但没有必要给每个appid都配置不同的限流算法吧
2020-06-183 - 沧海public class RuleConfig { private List<UniformRuleConfig> configs; public List<AppRuleConfig> getConfigs() { return configs; } } RuleConfig中的属性configs类型应该是List<AppRuleConfig>
作者回复: 嗯呢,多谢指出!
2020-06-101 - HuaMaxstopwatch.reset()之后要调用stopwatch.start()重新开始,或者stopwatch.stop().start(),亲入坑。。。2020-06-0325
- jaryoung课后习题二: 如何重构代码,支持自定义限流规则配置文件名和路径? public static final String DEFAULT_API_LIMIT_CONFIG_NAME = "ratelimiter-rule"; private final String customApiLimitConfigPath; public FileRuleConfigSource(String configLocation) { this.customApiLimitConfigPath = configLocation; } private String getFileNameByExt(String extension) { return StringUtils.isEmpty(customApiLimitConfigPath) ? DEFAULT_API_LIMIT_CONFIG_NAME + "." + extension : customApiLimitConfigPath; } Spring boot 如何实现配置文件约定和扫描?可以去看看ConfigFileApplicationListener 这个类,如何跑起来,请去debug,不懂怎么debug,请新建窗口输入 google.com2020-06-0312
- leezerRatelimitAlg在重构后应该是可支持多种算法形式,那么在limit调用的时候应该不是直接new出来,可以通过策略形式进行配置,而算法的选取应该包含默认和指定,也可以配置到文件规则里面。2020-06-035
- bucher感谢争哥,写的很棒。根据url查找限流规则使用了trie树这块是不是属于过度设计呢?一个app下的api个数不多的情况,直接用map存就可以了吧(map的key使用url名)2021-01-0423
- djfhchdh1、RateLimiter类中,构建api对应在内存中的限流计数器(RateLimitAlg)这个逻辑可以独立出来,初始化的过程中,就将api和相应RateLimitAlg实现类的对应关系建立好; 2、可以使用DI框架,FileRuleConfigSource构建时,从bean配置文件读取构造参数,如果没有提供构造参数就用默认值2020-06-043
- 龙猫tryAcquire 为什么要 调用两次 currentCount.incrementAndGet()方法呢?没太看懂,有大佬解释一下吗2020-10-0132
收起评论