点击上方 "编程技术圈"关注, 星标或置顶一起成长
后台回复“大礼包”有惊喜礼包!
每日英文
You must be strong now. You must never give up. And when you are afraid of the dark, don't forget the light is always there.
你要坚强,决不能放弃。当你担忧生活黑暗无边之时,请记得希望总会在某处闪光。
每日掏心话
告诉自己:再苦再累,只有坚持往前走。生活不会向你许诺什么,尤其是不会向你许诺成功。
责编:乐乐 | 来自:架构头条
编程技术圈(ID:study_tech)第 1139 次推文 图源:百度
往日回顾:CTO 说了,如果发现谁用 kill -9 关闭程序就开除
正文
作者 | sergiuoltean
策划 | 万佳
众所周知,架构特点多以"ility"结尾(例如 scalability、deployability),也被称为 NFR(非功能需求)、质量属性。架构的特点没有固定清单,但标准是有的,就是 ISO25010:
我们从业务需求(业务特征)、我们期望的系统运营方式(运营特征)中总结出这些特点,它们是隐式的、贯穿各领域,是架构师在字里行间能看出来的特点。《软件架构基础》书中的这张表是隐藏特点的一个例子。
《实践中的软件架构》一书中对架构特点解释得很清楚。
刺激的来源(Source of Stiumulus)可以是角色、触发事件的东西等。刺激(Stimulus)是实际产生的事件。环境(Environment)代表事件发生的系统条件。工件(Artifact)是系统中正在被刺激的部分。响应(Response)就是工件在我们应该度量(measure)的刺激下的行为方式。背景了解完毕,让我们来看具体的特点。
1性能
根据 Smith 所说,“性能是指响应能力:响应特定事件所需的时间,或给定时间间隔内处理的事件数”。性能可以有以下指标:
延迟 。表示获得响应之前经过的时间,这里指的是一段时间。我们有最小延迟(开始时间)和 截止日期 (结束时间)。衡量延迟的其他因素包括 优先级(我们在其中查看响应的顺序)和 抖动 (随时间观察到的延迟波动)。
吞吐量。是指在固定时间间隔内获得的响应数。但为了提高精度,我们应该度量多个时间间隔。
可用容量。以上度量的结合体。在不超出延迟要求的情况下可实现的最大吞吐量。
可调度的利用率。利用率是资源繁忙时间的百分比,而可调度的利用率是满足一定时间要求的最大利用率。
数据丢失。如果使用缓存来提高性能,那么缓存未命中将成为性能指标。
提高性能的技术
首先我们要了解影响性能的因素。
需求 。我们需要多少资源?
硬件 。我们需要什么类型的资源?比如 CPU、内存、I/O 设备、网络等。系统是否运行在正常条件下?还是在重负载下?
软件 。我们使用的框架是否是高性能的?有没有使用缓存?是否涉及某种反射(java)?是否做了最大的优化工作?
我们需要控制需求,为此我们可以使用队列、节流和背压机制。通过改进算法,我们可以减少资源需求。通过设置最大响应时间(超时)和某种优先级,我们可以进一步控制需求。
可以使用垂直缩放来获得更好的响应时间。提高性能的另一种方法是并发。还需要注意阿姆达尔定律。
加速效果的瓶颈是程序的串行部分。例如,如果 95%的代码可以并行化,则并行计算的理论最大加速比将是 20 倍。
限制你的资源、对所有内容(线程、队列)实施固定的生产限制、规划资源使用并尽可能避免争用……这些说起来容易,做起来难。还可以充分利用缓存、水平缩放、添加多个处理单元等。
你应该了解你的框架和你的数据库,并优化它们。
2可靠性
根据《牛津词典》,可靠意味着质量或性能始终如一,且能够被信任。可靠性可以用平均故障间隔时间(MTBF)来表示,可靠性 =exp(-t/MTBF)。
可靠性很难用数字度量。我们可以用一些软件指标衡量复杂度和代码覆盖率,以了解可靠性的边缘情况。适应度函数也可用于度量可靠性。未解决问题的数量、成功的构建和部署的数量也是一些可用指标。ISO-9001 是衡量可靠性的另一种方法。
https://sergiuoltean.com/2020/04/29/fitness-functions/
提高可靠性的技术
遵循最佳工程实践将产生更好的产品。使用更好的管理实践和流程,可以实现更高的可靠性。突变测试技术会让系统考虑边缘情况。混沌测试是提高可靠性的另一个重要工具。总之我们要强化系统来提高可靠性。
3可用性
表示可用系统时间与总工作时间的比率。这是可靠性之上的另一层。它是系统掩盖或修复特定阈值(例如时间间隔)内故障的能力。可用性可以表示为
在公众号编程技术圈后台回复“Java”,获取Java面试题和答案惊喜礼包。
MTBF= 平均无故障时间;MTTR= 平均修复时间
于是我们计算出下表:
提高可用性的技术
为了提升它,首先我们需要检测潜在的故障。
检测到异常情况后,我们可以进行干预。
4弹性
弹性指的是系统遇到问题时可以降级(而非中断服务),等待问题修复完成,表示的是系统在遇到严重故障时的持续运行能力。为实现弹性,需要提前设置防御机制(断路器模式)。弹性有时被称为容错性 。弹性系统指的是可以适应压力并持续运行的系统。很难用数字指标来度量弹性。
增强弹性的技术
首先是确定潜在风险:系统有哪些关键功能?哪些硬件至关重要?然后我们需要实施保护策略,为此需要检查哪些事件可能导致这些重要部件发生故障。找出风险因素后就需要确定容忍阈值。具体的保护策略包括对请求数和线程数施加限制、缓存相同的请求、批量发送请求等。
5可信赖性
它包括可靠性 、可用性 、弹性 、可持续性 (可用性 / 弹性的比值)、可恢复性 (弹性函数)和 稳健性 (可靠性函数)。我们应该始终将它们视为一个整体。
拿一辆汽车来说,如果它是新车并且是知名的可靠品牌(例如梅赛德斯),我们可以说它是可靠的。它有备用轮胎,所以有一些可用性。四轮驱动意味着弹性,其中两轮出故障还有两轮能工作(但性能会下降)。可持续性是可用性(备用轮胎)和弹性(四轮驱动)的综合。健壮性在这里可以指道路通过能力。如果汽车是电动的,那么充电速度就是一个可恢复性指标。
6可伸缩性
它是系统在重负载下在可接受的阈值内的执行能力。它分为手动和自动可伸缩性两种,后者也叫 灵活性 。当负载突增时,系统会做出反应并水平缩放(添加 / 删除更多实例)。我们可以查看 CPU 和内存来观察这些突发事件。这些突发操作完成后,系统将杀死不必要的实例,从而降低成本。垂直伸缩意味着我们向系统添加了更多物理资源(例如更多的内存、更好的 cpu)。
实现可伸缩性的技术
这里涉及到 devops,最好使用 aws fargate 之类的云服务。
https://aws.amazon.com/fargate/
下图中可以看到放大和缩小策略。
7安全性
它实际上是许多特点的集合:机密性 是指系统保护用户数据安全的能力;完整性 是保护外部资源免遭篡改的能力;身份验证 允许用户访问系统;授权 则告诉用户可以访问系统的哪些部分。授权通常使用 RBAC、ACL 或 ABAC 来实现。不可否认性 保证了消息的发送者不能否认自己发送了消息,并且接收者也不能否认自己接收了消息。
增强安全性的技术
首先我们需要检测。
针对攻击行为,我们需要制定灵活的应对策略。大多数情况下我们可以撤消访问权限,在某些极端情况下我们可以关闭系统,当然最好还是避免后一种情况出现。最好使用成熟的安全解决方案,自行实现往往不是好办法。
8互操作性
它表示系统与外部系统通信的能力。合约接口是互操作性中最重要的概念,其涵盖了通信的所有方面,包括错误处理。
改善互操作性的技术
最好的策略是使用企业集成模式。如果用到多个通信协议,这种策略就是最佳方法。
https://learning.oreilly.com/library/view/enterprise-integration-patterns/0321200683/
9可调整性
也称为 可变性 ,其描述了系统变化的难易程度。一般来说它是一个隐含的特征。作为架构师,你要知道系统变化的概率是未知的,但一旦出现变化,系统应该能够优雅地应对。变化是软件世界中唯一确定的事物。话虽如此,我们不能将整个系统都设计为可变组件。如果每个组件都是即插即用组件,设计就做不完了。因此我们需要找到那些变化概率很高的部分。
改进可调整性的技术
有两个维度。作为一名架构师,你需要确定哪些部分具有较高的变化概率;作为软件工程师,你必须确保这些部分容易改动。遵循 SOLID 原则是一个很好的开始。可以使用适应度函数度量传入和传出耦合。我们需要计算变化成本。比如要构建一个 UI 表单,它需要的位置比我们最初想像的要多,则我们可以复制粘贴代码并进行必要的调整,也可以构建一个新组件并插进来。然后我们得到了变化的成本:
N x 编写代码的成本(复制粘贴)<= 编写组件 +(N x 将其插进来的成本)
还需要考虑时间,观察较长的时间才能得到可靠的观察结果。
10可部署性
所有系统都应封装在某种工件中,可以是 war、jar、ear、apk、dll、gem 等。它们被部署在能够运行它们的环境中。由于 docker 的进化,现在我们可以在一台机器上拥有多个环境。可部署性是一种将代码转换为客户可用产品的机制。
改善可部署性的技术
最有效的是实施持续集成 / 持续部署(CI/CD)。认真的话,每次代码推送都将触发一个生产部署。为此,应通过适应度函数和自动化测试来保护你的代码。它是抗脆弱性的关键部分。我们希望能按需部署,一键完成工作。我们也会部署硬件。使用基础架构即代码之类的技术可以提高效率。
11可测试性
在所有系统中它都是一个重要特征。我们必须确保构建的系统尊重了客户的需求。复杂的系统很难测试。以微服务架构为例,我们有很多独立开发的活动部件。这个特征经常会让步给其他特征。为了使系统可测试,我们需要能控制每个组件的输入和输出。
改善可测试性的技术
请尽量控制系统的复杂性。我们应该构建较小的组件,不要重新发明轮子;还应该编写可测试的代码,在适当的位置应用 TDD。
12简单性
这条特征是很难实现的。一切都是权衡取舍,而大多数情况下这一条都会被牺牲掉。但如果我们需要在有限的时间内快速构建某些东西,那么就应该优先考虑简单性。在构建 MVP(最小可行产品)时,我们关心的只有简单性。但请注意,实现目标之后,我们不应丢掉所有东西。不要与 PoC(概念验证)或某种 R&D 混淆。可重用性 在这里也很重要。在公众号顶级架构师后台回复“架构整洁”,获取一份惊喜礼包。
改善简单性的技术
可以构建粗粒度的组件;使用 RAD 框架,例如 ApacheIsis、Vaadin 或 JHipster;牺牲简单性之前请确保自己能承受对应的代价;遵循 KISS 原则。记住时间是关键:先跑起来,再考虑美观和性能。
13可移植性
指的是系统从一个操作系统移植到另一个的能力,它会影响编程语言的选择。例如,我们知道为了运行 Java 代码需要一个 JVM,因此问题就是“JVM 是否可移植?”答案是肯定的。另一个例子是 golang:它打包为二进制文件,不需要外部依赖项,因此是可移植的。一些微软专属技术就不行,它们只能运行在微软操作系统中。
改善可移植性的技术
一个显而易见的选项就是容器化、docker。一个 docker 引擎能够运行多个隐藏了实现细节的 docker 容器。
14易用性
谈到易用性时通常会提到 可配置性 ,即用户自定义系统的能力,比如通过 UI 主题更改外观和配置系统行为(例如控制用户访问权限等)。还有 本地化,也称为 i18n(internationalization)。它指的是系统支持多种标准的能力,一般是通过用户体验(UX)实现的。这里的标准指的是语言、货币、公制单位、字符编码等。本地化资源通常是静态的。
可访问性 是另一个易用性特征。世界上有些人是残疾的(失明、听力受损、色盲),我们如何确保这些人可以受益于我们的系统呢?对于色盲来说,选择颜色会花很多时间。Siri/Alexa 是盲人的好帮手。考虑可访问性时,请想到我们的祖父母是不是能方便地使用我们的系统。
另外还有 可支持性 ,比如说帮助页面或者 24x7 技术支持。我们应该努力让系统直观易用,这会影响可学习性,也就是用户习惯系统所需的时间。用户培训和帮助页面之类的策略很好用。
15可扩展性
它是描述系统对即插即用组件需求程度的特征。对于使用内核架构的系统来说,这是很重要的特征。Eclipse Platform 和 OSGI 标准就是经典的例子。
16抗脆弱性
它是系统应对压力、冲击、波动、噪声、错误、故障或攻击的能力。
改善抗脆弱性的技术
首先我们要敲打敲打系统。可以使用 CI/CD,它们本来就是做这种事的。每次代码更改都必须投入生产。当然,我们也要有防御机制,适应度函数就是个好方法;Simian Army 也是个不错的工具。
https://github.com/Netflix/SimianArmy
17可升级性
它是指系统无缝升级自身的能力。对于非 Web 产品(例如 App Store 和 Google Play),这很容易实现,因为它们的升级能力是嵌入到 OS 中的;涉及到 Web 应用时,事情就麻烦多了。
改善可升级性的技术
首先我们需要为服务提供版本控制。下一步是使用蓝绿部署或金丝雀部署等策略进行零停机的时间部署。
18合规性
不管我们需要的是哪种第三方工具和框架,都应该得到它们的合法授权。我们需要重视开源软件的合规性因素,因为它们可能会附带一些我们不想要的额外约束。没有人愿意暴露自己的源代码,因此我们应该远离 GPL 许可证。在欧盟,《GDPR》已成为强制规定,因此我们需要确保系统符合其规定。还要考虑一些 ISO 标准,公司可能需要遵循某些流程才能符合它们的要求。
改善合规性的技术
理想情况下,每家公司都应该有一个法律部门,但现实并非如此。适应度函数(例如许可证检查)可以保护我们免受列入黑名单的许可证的影响。在设计系统时,我们必须找到一种保护用户数据隐私的方法。
19成本
可能是最重要的架构特点。一切都有成本,虚拟的、还是现实的都一样。任何成本都可以换算成金钱。如果我们需要购买某些工具(IDE)、云服务(例如 AWS)、第三方框架(例如 new-relic)的许可证,则总会产生财务成本。开发团队也要发工资,学习新技术或培训团队成员需要花钱。不尊重敏捷宣言是有代价的;错误的代码要付出代价;缺少单元测试会有代价;缺少 CI/CD 会有代价;没有基础架构即代码也会有代价……这个列表是没有尽头的。
降低成本的技术
帮助客户控制成本是我们的责任。我们需要区分单纯的成本和投资,并让客户相信投资是划算的。
以 Scrum 流程为例,我个人认为它没什么用。在一个固定的周期(通常为两周)中,我们有这么多的仪式(计划、站会、演示、回顾),然后根据(猜出来的)估计值做计算,结果 Sprint 完成度 100%只是偶然而非必然。我们需要敏捷和适应,而不是盲目地遵循流程。我们应该减少会议和仪式,这样成本就会下降。我们应该专注于完成工作的本质要素。
测试是必要的投资,快速前进的唯一方法就是正确前进。我们必须说服客户,从长远来看,成本是会下降的。测试会减少错误的数量,从而减少成本。
代码质量是另一项投资。好的代码将带来更好的测试,提高稳健性、可维护性、可调整性等。与难以维护的系统相比,我们的更改花费的时间会更少,成本会下降。
20可存档性
指系统保留历史数据记录的能力。在数据是一等公民的系统中(例如财务系统),这个特征非常重要。数据绝不会删除,而只会归档,这主要是考虑到法律要求。可归档性是对可审计性的支持。
实现可归档性的技术
首先是在数据上使用时间戳(例如 updatedOn、createdOn)。然后要有一个 cron 作业,将所有低于特定阈值的数据移入历史表中。另一种技术是将数据标记为软删除,但这会影响查询性能。
21可审核性 / 可跟踪性
这是支持重构历史的系统特征。我们必须记录所有关键操作(尤其是在安全场景中),以便重现问题并从错误中学习经验。我们也可以将这些记录用作法律依据。
实现可审核性的技术
记录每个关键操作并集中存放这些记录。可以使用 ELK,或 sleuth-zipkin 具。
https://www.elastic.co/what-is/elk-stack
https://sergiuoltean.com/2017/10/04/zipkin-sleuth/
原文链接:
https://sergiuoltean.com/2020/06/26/architecture-characteristics/
PS:欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,欢迎转发分享给更多人。
版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!
猜你还想看
有人靠"抢茅台"月入百万,脚本曝光,开源可用!网友:太强了~
告赢了!程序员拒绝春节带电脑回家工作被开除,判决获赔19.4万!
BAT等大厂Java面试经验总结
别找了,想获取 Java大厂面试题学习资料
扫下方二维码回复「手册」就好了
嘿,你在看吗?