软件设计 架构 阮一峰
2024-03-04
几乎所有我喜欢的软件架构师,都认同康威定律(Conway Law),认为这个定律非常重要,足以影响到所有系统。而且,你没法与之抗争,想要抗拒康威定律注定要失败。
康威定律的最好表述是:“任何系统的构成,都反映了设计这个系统的组织结构。”
它的出处是 Melvin Conway 在 1968 年写的一篇文章。后来,弗雷德·布鲁克斯(Fred Brooks)在著名的《人月神话》(The Mythical Man-Month)引用了这条定律。
Melvin Conway 观察到,软件系统的架构看起来与构建它的开发团队的组织结构非常相似。
最初的描述是,如果一个团队编写一个编译器,那么它将是一个单通道编译器;但是,如果两个团队共同开发,那么它将是一个双通道编译器。这个描述后来被发现,广泛适用于大量系统。
正如我的同事 Chris Ford 对我说的:“软件耦合是由人类交流促成的。” 如果我可以轻松与代码作者交谈,那么我就更容易对代码有更深入的了解,因此我的代码更容易耦合到该代码。
应对康威定律的第一步是不要与之抗争。我仍然记得一位技术主管,他刚刚被任命为 一个大型新项目的架构师,该项目由分布在世界各地不同城市的六个团队组成。“我做出了第一个架构决定”,他告诉我:“就是这个系统将有六个主要的子系统。我不知道它们会是什么子系统,但肯定会有六个。”
为了适应康威定律,现在有一种策略,就是一旦定下软件架构,就相应改变组织结构,让紧密耦合模块的开发者更容易沟通。
开发者 软件设计
2023-12-09
突然来了大量客户请求,我们无法判断这些请求是正常的,还是客户被攻击所致。为了避免产生严重客损,我们需要识别到这些突然出现的流量高峰,并进行通知以及执行一些处理措施。
客户配置
比如:
request_limit = {
rate: {
// 客户配置
3600: 1000, // 指定 API 1 小时之内的请求量上限
86400: 8000, // 指定 API 1 天之内的请求量上限
},
rate_computed: {
// 根据之前的请求情况,结合客户配置计算出来的值(不小于客户配置)
3600: 1000,
86400: 8000,
},
strategy: {
times_to_notify: 1, // 连续触发几次之后通知
times_to_suspend: 3, // 连续触发几次之后暂停
times_to_intercept: 12, // 连续触发几次之后拦截请求
},
};
- 默认给所有客户开启最近 1 小时和最近 24 小时的限制。
- 速率控制以小时为单位(
[1, 24]
)
定时检查
- 定时执行
5 10 15 20 25 30
35 40 45 50 55 0
-
查询过去 1 天有请求的客户清单,根据系统参数(可能还有业务上其他条件)跳过忽略检查客户
-
逐个客户查询最近 5 分钟内的请求量,并将 5 分钟数据统计到小时内
然后逐个时间区间配置,判断总请求量是否超出预设值
end_min = (minute // 5) * 5
start_min = end_minute - 5
- 如果流量异常,按照指定策略触发相关事件
客户处理
PS:这个机制的目的是处理异常流量,如果正常的请求量上来了应该调整客户配置。
- 警告页面给出客户过去的请求情况,标出告警时间段的数据
- 让客户选择处理方案:
- 忽略并继续
- 清空暂停队列并继续
可以查看下载受影响的请求信息
- 暂不处理
- 往后 24 小时之内,下一次触发告警的数量,提供一个默认值(当前请求量的 1.5 倍)
另一种思路:如果客户选择继续请求,不用填下一次告警的数量,后面计算的时候直接跳过过去一段时间(比如 6 小时)的请求量。
软件设计
2021-08-24
在满足需求、有良好的使用体验(基于真实的用户看法,不是开发者自己觉得)基础上,进一步提更高的要求:
- 接口响应超时
- CPU load 升高
- 内存
- GC 频繁
- 死锁
- 大数据量存储
一、三高(高可用 + 高性能 + 高并发)
1.1 高可用(可用性) Availability
可用性强调的是服务的总体持续时间,比如可用性级别为三个九(99.9%)意味着一年 365 天里总共停止服务 8.76 个小时。
可靠性 Reliability
- 功能如预期运行(宁可抛出异常,不要默默地给错误运行)
- 出现故障的频率
- 出现故障也应该不对系统造成太大的影响
- 可维修性:故障定位容易、修复步骤简单、修复成本低廉
和高可用的区别:
- 大部分时候,这两个指标都是密切相关的
- 如果我有一个电视机,每天都准时看儿童频道的《动漫世界》一个小时,然后过去三年也都用得挺好,没有送去修过(导致我看不了),那可以说高可用了(正常运行时间 / 预期运行时间),但是如果这个电视机每次看的时候可能隔一会儿需要拍一巴掌(中间出雪花的时间可以忽略),那这就不能说这个电视机是可靠了。
-
又比如说,我又买了另一个电视机,不需要拍巴掌了,我看的挺开心,不过才高兴两年,坏了,看不了了,楼下电器维修店的小哥搞不定,联系厂家售后维修,一下就是两周看不了电视。对于一个家用电器,两年坏一次可以说高可靠,但是可用性就有问题了((365 - 7) / 365 = 98%
)。
-
MTBF Mean Time Between Failure 无故障时间,每隔多久遇到一次故障
- MTTR Mean Time To Repair 修复时间,每次遇到故障需要维修多久
-
MTTF Mean Time To Failure
-
根据当前的可用性级别,然后指定合理的可行性目标
- 操作规范/最佳实践
- 预防性维护 Preventive Maintenance
- 合理的 PM 计划:可实施,正确的时机
- 重点是影响最大的故障
- 不断的改进和优化
稳定性 Stability
连续性 Continuity
故障出现之后的处理能力:故障能否快速修复,能否不影响主要业务的运行。
比如我有两台电视机,坏了一台,我还有另一台可以看,虽然另一台是之前淘汰的一台黑白电视,效果差点,好歹能用啊。
这台电视就是我们常说的灾难备份,或者说容灾备份。
1.2 高性能 HP Performance
1.3 高并发 HC Concurrency
二、安全性
- 基础设施安全:操作系统、网络、数据库
- 数据安全
- 脱敏:降低数据泄漏所产生的消极影响
三、易用性
四、其他
3.1 可测试性
3.2 可维护性
运维方便,运营方便,二次开发方便
- 代码注释与文档
- 合理的日志
- 监控与数据统计
- 误操作发生率低
- 可理解性:代码可读性,合理的技术框架/系统架构
- 可拓展性:新增功能不需要修改现有结构的能力。分层,合理的耦合度(尽可能的高内聚、低耦合),合理的功能抽象,数据结构可拓展
3.3 可伸缩性 Scalable/Scalability
在系统不需要修改(顶多改改配置)的前提下,通过增加或减少硬件资源来动态提升或降低系统各项能力。
- 通常采用服务器集群的方式。
- 集群一上来,就和高可用有很大关联。
3.4 可扩展性 Extensibility
通过合理的设计,使得新增功能时,不需要改动现有功能,或者只需要对现有系统进行少量调整就行。
总之,将新功能对现有业务逻辑的影响降到最低。
3.5 可观测性
能够方便快捷的了解到程序运行情况。
合理的日志,指标数据的暴露(Pull/Push)。
软件设计
2020-02-08
:) 本文正在编辑中,暂时不提供浏览...
软件设计 设计模式
2019-05-26
什么是设计模式
https://en.wikipedia.org/wiki/Design_Patterns
https://en.wikipedia.org/wiki/Software_design_pattern
我们说的 23 中设计模式,是来自一本 1994 年出版的书:《Design Patterns: Elements of Reusable Object-Oriented Software》。
这本书的中文名字叫:《设计模式:可复用面向对象软件的基础》。
写这本书的四位作者,被人成为 GoF(Gang of Four),也就是四人帮的意思(因为我们这边的关系,这个词在西方也比较著名,所以...)。
其中定义了设计模式,就是类似的问题的一种解决方案,或者说优秀的设计风格、编码风格,提升代码重用,同时实现高内聚、低耦合,让程序会更加可理解,更加可拓展,更加可维护。
- 一般谈到设计模式,都是在面向对象编程。但是我理解这是一种编程思想,和面向对象并不是强绑定关系。这点需要更多的思考和总结。
- 这里只研究 GoF 的 23 种设计模式,不是说这就是设计模式的全部,这个可能每个人有不同的看法。
- 根据维基百科信息,GoF 后来想重新整理这本书,重新分类,增删一些模式,但是最终没有达成一致。
- 根据维基百科信息,有人认为本书提到的设计模式只是语言特性缺失,在其他语言中,部分模式是不需要的。
- 就好像我们教材上基于 C 语言的数据结构,有部分在现代语言中是不需要开发者去编码实现一样,编译器做的很好了。
六大原则 SOLID
- 单一职责原则(Single Responsibility Principle)
- 开闭原则(Open Closed Principle)
- 里氏替换原则(Liskov Substitution Principle)
- 迪米特法则(Law of Demeter),又叫:最少知识法则(Least Knowledge Principle)
- 接口隔离原则(Interface Segregation Principle)
- 依赖倒置原则(Dependence Inversion Principle)
有些资料中还加入了一个:合成复用原则 Composite/Aggregate Reuse Principle,减少继承,多用聚合。
- https://zhuanlan.zhihu.com/p/110130347
- https://cloud.tencent.com/developer/article/1650116
模式清单
创建型模式 Creational
- 工厂模式 Factory Pattern
- 问题:
- 方案:
- 效果:
- 抽象工厂模式 Abstract Factory Pattern
- 问题:
- 方案:
- 效果:
- 单例模式 Singleton Pattern
- 问题:
- 方案:
- 效果:
- 建造者模式 Builder Pattern
- 问题:
- 方案:
- 效果:
- 原型模式 Prototype Pattern
- 问题:
- 方案:
- 效果:
结构型模式 Structural
- 代理模式 Proxy Pattern
- 问题:
- 方案:
- 效果:
- 适配器模式 Adapter Pattern
- 问题:
- 方案:
- 效果:
- 桥接模式 Bridge Pattern
- 问题:
- 方案:
- 效果:
- 组合模式 Composite Pattern
- 问题:
- 方案:
- 效果:
- 装饰器模式 Decorator Pattern
- 问题:
- 方案:
- 效果:
- 外观模式 Facade Pattern
- 问题:
- 方案:
- 效果:
- 享元模式 Flyweight Pattern
- 问题:
- 方案:
- 效果:
行为型模式 Behavioral
- 责任链模式 Chain of Responsibility Pattern
- 问题:
- 方案:
- 效果:
- 命令模式 Command Pattern
- 问题:
- 方案:
- 效果:
- 解释器模式 Interpreter Pattern
- 问题:
- 方案:
- 效果:
- 迭代器模式 Iterator Pattern
- 问题:
- 方案:
- 效果:
- 中介者模式 Mediator Pattern
- 问题:
- 方案:
- 效果:
- 备忘录模式 Memento Pattern
- 问题:
- 方案:
- 效果:
- 观察者模式 Observer Pattern
- 问题:
- 方案:
- 效果:
- 状态模式 State Pattern
- 问题:
- 方案:
- 效果:
- 策略模式 Strategy Pattern
- 问题:
- 方案:
- 效果:
- 模板模式 Template Pattern
- 访问者模式 Visitor Pattern
参考资料与拓展阅读
软件设计 设计模式
2015-08-10
最经典的是 SOLID 五个,但也有说六个、七个的。
软件设计
2013-12-31
被一个简单的位运算给唬住了~