鹅厂架构师谈:如何做好架构设计?OSCHINA

在软件行业,对于什么是架构一直有很多的争论,每个人都有自己的理解。不同的书籍上、不同的作者,对于架构的定义也不统一,角度不同,定义不同。此君说的架构和彼君理解的架构未必是一回事。

因此我们在讨论架构之前,我们先讨论架构的概念定义,因为概念是人认识这个世界的基础和用来沟通的手段,如果对架构概念理解不一样,那沟通起来自然不顺畅。

系统:泛指由一群有关联的个体组成,根据某种规则运作,能完成个别元件不能独立完成的工作能力的群体。提到系统,我们务必了解以下几个关键词:

关联:系统是由一群有关联的个体组成的,没有关联的个体堆在一起不能成为一个系统。例如,把一个发动机和一台PC放在一起不能称之为一个系统,把发动机、底盘、轮胎、车架组合起来才能成为一台汽车。

规则:系统内的个体需要按照指定的规则运作,而不是单个个个体各自为政。规则规定了系统内个体分工和协作的方式。例如,汽车发动机负责产生动力,然后通过变速器和传动轴,将动力输出到车轮上,从而驱动汽车前进。

能力:系统能力与个体能力有本质的差别,系统能力不是个体能力之和,而是产生了新的能力。例如,汽车能够载重前进,而发动机、变速器、传动轴、车轮本身都不具备这样的能力。

子系统:也是由一群关联的个体组成的系统,多半是在更大的系统中的一部分。

它们都是系统的组成部分,从不同角度拆分系统而已。模块是逻辑单元,组件是物理单元。

模块就是从逻辑上将系统分解,即分而治之,将复杂问题简单化。模块的粒度可大可小,可以是系统、几个子系统、某个服务、函数、类、方法、功能块等等。划分模块的主要目的是职责分离。

组件可以包括应用服务、数据库、网络、物理机,还可以包括MQ、容器、Nginx等技术组件。划分组件的主要目的是单元复用。“组件”的英文单词Component,对应中文的“零件”一词,“零件”更容易理解一些。“零件”是一个物理的概念,并且具备“独立且可替换”的特点。现在越来越被的UI设计使用组件化和模块化。

框架通常指的是为了实现某个业界标准或完成特定基本任务的软件组件规范,也指为了实现某个软件组件规范时,提供规范所要求之基础功能的软件产品。

框架是组件实现的规范,例如:MVC、MVP、MVVM等,是提供基础功能的产品,例如开源框架:RubyonRails、Spring、Laravel、Django等,这是可以拿来直接使用或者在此基础上二次开发。

再例如,SpringMVC是MVC的开发框架,除了满足MVC的规范,Spring提供了很多基础功能来帮助我们实现功能,包括注解(@Controller等)、SpringSecurity、SpringJPA等很多基础功能。

框架是规范,架构是结构。

在TOGAF9是这么定义:一个系统基本的构件(子系统,模块,组件),体现在它的各个构件、构件间的相互关系、构件与环境间的关系,以及对系统设计和演进进行治理的原则中。

两种含义:

第一,一个系统的形式化描述,或指导系统实现的构件级的详细计划。

架构从字面意思上,是源于古代的建筑术语。

把架构拆分成两个字“架”和“构”。“架”就是“加”和“木”的结合,把木头加起来、连接起来就是架。“构”就是结构的意思。所以,“架构”就是把“木”按照一定的结构连接起来。

对应到软件架构,“木”代表构件(要素),“结构”代表架构的产物:木就是系统中的要素,我们将它们称之为架构构件(要素)。架构要素可以是子系统、模块、应用服务、组件。结构,是架构的产物。不同的软件系统会有不同的结构,这些结构是为解决不同场景而设计的。

连接,通过定义架构元素之间的接口和交互关系、集成机制,实现架构元素之间的连接。连接可以是分布式调用、进程间调用、组件之间的交互关系等。总结一下架构的组成=要素+结构+连接,将系统要素按照特定结构进行连接交互。

我在这重新定义架构(见仁见智):

软件架构指软件系统顶层结构设计。

架构是经过系统性地思考,权衡利弊之后在现有资源约束下的最合理决策,最终明确的系统骨架:包括子系统、模块、组件,以及他们之间协作关系、约束规范、指导原则,并由它来指导系统各方面的设计和指导团队中的每个人思想层面上的一致。

涉及四方面:

系统性思考的合理决策:比如技术选型、解决实施方案(包括执行目标计划)、成本评估、性价比评估等等。

结构:明确的系统骨架(结构):明确系统有哪些构件组成。

连接:系统协作关系:各个组成部分如何协作来实现业务请求。

规范:约束规范和指导原则:保证系统有序,高效、稳定运行,包括规范、原则、流程等内容。

如果没有架构设计,说明你的系统不够复杂。随着业务的增长,系统由单体应用渐进演化为分布式和微服务化。

系统整体的复杂性越来越高,技术团队可能从一个团队变成多个专业化团队。假如没有架构设计,系统定会是一个无序失控的状态,带来的问题:

当然,我们还能列举出更多问题。

架构设计的目的是为了解决系统复杂性带来的问题。其本质就是对系统进行有序化地重构以致符合当前业务的发展,并可以快速扩展。

从上面架构的定义,也知道架构设计的作用涉及四方面:系统性思考的合理决策;明确的系统骨架;系统协作关系;约束规范和指导原则。

无论是何种变化,架构师通过理解业务、全局把控,权衡业务需求和技术实现。选择合适技术,解决关键问题并指导研发落地实施,最终促进业务发展,提高效率。

在EA架构领域,有两种常见架构方法RUP和TOGAF,这两个框架也是我们常常了解架构分类的两个维度。

TOGAF9对架构的分类是这样的:

由于不同架构方法论,定义的架构分类也不同,RUP4+1架构方法主要是以架构生命周期为视角进行描述,而TOGAF9按架构涉及内容维度来描述。

因此我结合两者细分为业务架构、应用架构、数据架构、技术架构、代码架构、部署架构。

业务架构是战略,应用架构是战术,技术架构是装备。其中应用架构承上启下,一方面承接业务架构的落地,另一方面影响技术选型。熟悉业务,形成业务架构;根据业务架构作出相应的应用架构,最后技术架构落地实施。

你也可以理解成:业务架构是生产力,应用架构是生产关系,技术架构是生产工具。业务架构决定应用架构,应用架构需要适配业务架构,并随着业务架构不断进化,同时应用架构依托技术架构最终落地。

整体来说,架构演进路程是这样的:

单体应用->分布式应用服务化->微服务

下面我将做简单介绍。

企业一开始业务比较简单,只应用某个简单场景,应用服务支持数据增删改查和简单的逻辑即可,单体应用可以满足要求。

典型的三级架构:前端(Web/手机端)+中间业务逻辑层+数据库层。这是一种典型的JavaSpringMVC或者PythonDjango框架的应用。针对单体应用,非功能性需求的做法:

性能需求:使用缓存改善性能;

并发需求:使用集群改善并发;

读写分离:数据库的读写分离;

使用反向代理和cdn加速;

使用分布式文件和分布式数据库。

单体架构的应用比较容易部署、测试,在项目的初期,单体应用可以很好地运行。然而,随着需求的不断增加,越来越多的人加入开发团队,代码库也在飞速地膨胀。

慢慢地,单体应用变得越来越臃肿,可维护性、灵活性逐渐降低,维护成本越来越高。总体来说,单体架构应用可能会有这些缺点:复杂性高、技术债务积累、部署频率低、可靠性差、扩展能力受限并且可能阻碍技术创新。

为了解决上面提到的这些缺点,我们需要对系统按照业务功能模块拆分,将各个模块服务化,变成一个分布式系统。

业务模块分别部署在不同的服务器上,各个业务模块之间通过接口进行数据交互。该架构相对于单体架构来说,这种架构提供了负载均衡的能力,大大提高了系统负载能力,解决了网站高并发的需求。另外还有以下特点:

随着业务模式越来越复杂,订单、商品、库存、价格等各个模块都很深入,比如价格区分会员等级,访问渠道(app还是PC),销售方式(团购还是普通)等,还有大量的价格促销。

这些规则很复杂,容易相互冲突。我们需要把分散到各个业务的价格逻辑进行统一管理,以基础价格服务的方式透明地提供给上层应用,变成一个微内核的服务化架构,即微服务。

微服务的特点明显:易于开发与维护、单个微服务启动较快、局部修改容易部署、技术栈也不受限制。

然而,微服务虽然有很多吸引人的地方,但它并不是免费的午餐,使用它可能面临这些挑战:

广泛地应用在从数据中心设计到应用服务的部署:

在发生故障时,系统至少要有一个冗余的实例。

必须确保一个为自己,一个为客户、一个为失败。

灾难性的事故,例如损坏客户数据,往往在部署后好几天才出现。

系统最好按照预先的设计,通过发布或回滚解决问题。

通过版本化方式实现回滚设计,一旦发生灾难级别的故障可以通过回滚到最近版本来恢复服务。

降级开关通过配置中心集中化管理,例如:apollo配置中心,通过推送机制把开关推送到各个应用服务。

通过监控发现系统的可用性问题。

通过监控使系统自我诊断、自我修复成为可能。

通过监控确定系统可预留空间的使用情况。

通过监控掌握系统之间的交互关系,发现瓶颈。

数据是否全部集中在一个数据中心?

读写是否分离?

是否所有的客户信息都共享同一个数据结构?

服务调用是否允许延时的存在?

最好争取在多数人采用该技术的时候进入,先把新技术用在对可用性要求不高的功能上,一旦证明它可以可靠地处理日常的交易,再将此技术移植到关键任务领域中去。

避免单一业务占用全部资源,避免业务之间的相互影响。机房隔离避免单点故障。两个重要原则:

不共享原则:理想情况是负载均衡、网络前端、应用服务器、数据库,绝不共享任何服务、硬件和软件。

不跨区原则:不同隔离区之间无通讯,所有服务调用必须发生在同一个故障隔离区。

什么是水平可扩展?平台的水平扩展是指随着业务的发展,当需要扩大平台的服务能力时,不必重构软件系统,通过增加新的设备来满足业务增长的需要。

系统研发要投入资源,系统维护更要长期投入。

影响核心产品到市场的速度。

如果可以形成差异化的竞争优势,那么自己做,否则外购。

在大多数情况下,便宜的是最好的。标准、低成本、可互换、易于商品化是商品化硬件的特征。

如果架构设计得好,就可以通过购买最便宜的服务器轻松地实现水平扩展,前提是所有商品化硬件的总成本要低过高端硬件的总成本。

这里有三个要点:

小构建:小构建的成本较低,可以确保投资可以产生价值。

快试错:可依市场反馈,快速迭代,加快TTM,优化用户体验。

快速迭代需要完善的运维工具,比如从cmdb、持续集成工具、监控等等。

同步系统中个别子系统出现故障会对整个系统带来影响。这里常有2个现象:

同步系统中性能最慢的子系统,成为整个系统性能的瓶颈。

同步系统中扩展性最差的子系统,是整个系统扩展的瓶颈。

无状态定义:是应用服务运行的实例不会在本地存储需要持久化的数据,并且多个实例对于同一个请求响应的结果是完全一致的。比如单实例的mysql,zookeeper集群是有状态,而类似单纯tomcat服务是无状态的。

无状态的系统更利于扩展,更利于做负载均衡。状态是系统的吞吐量、易用性、可用性、性能和可扩展性的大敌,要尽最大可能避免。

Now:目前正使用系统的架构、设计、能力、性能和扩展性。

Now+1:下一代预研系统的架构、设计、能力、性能和扩展性。

Now+2:下一代规划系统的架构、设计、能力、性能和扩展性。

设计和构建自动化的过程。如果机器可以做,就不要依赖于人。人常犯错误,更令人沮丧的是,他们往往会以不同的方式多次犯同样的错误。

架构得再好,最终还是需要代码来落地,并且组织越大这个落地的难度越大。不单单是系统架构,每个解决方案每个项目也由自己的架构,如分层、设计模式等。

如果每一块砖瓦不够坚固,那么整个系统还是会由崩塌的风险。所谓“千里之堤,溃于蚁穴”。

架构不是“空中楼阁”,最终还是要落地的,但是架构师完全不去深入到第一线怎么知道“地”在哪、怎么才能落得稳稳当当?

世上没有最好架构,只有最合适的架构,不要企图一步到位。我们需要的不是一下子造出一辆汽车,而是从单轮车-->自行车-->摩托车,最后再到汽车。

你想象一下2年后才能造出的产品,当初市场还存在吗?

在创业公司初期,业务场景和需求边界很难把握,产品需要快速迭代和变现,需求频繁更新,这个时候需要的是快速实现。不要过多考虑未来的扩展,说不定功能做完,效果不好就无用了。

如果业务模式和应用场景边界都已经比较清晰,是应该适当的考虑未来的扩展性设计。

由于大公司巨大成功的光环效应,再加上从大公司挖来的技术高手的影响,网站在讨论架构决策时,最有说服力的一句话就成了“xx就是这么搞的”。

大公司的经验和成功模式固然重要,值得学习借鉴。但如果因此而变得盲从,就失去了坚持自我的勇气,在架构演化的道路上迟早会迷路。

技术是为业务而存在的,除此毫无意义。在技术选型和架构设计中,脱离网站业务发展的实际,一味追求时髦的新技术,可能会将技术发展引入崎岖小道,架构之路越走越难。

THE END
1.商品下架啥意思商品下架该词一般用于网店,用于提示用户不要再下单购买此件商品,已经卖光了。在现实生活中的一些店铺里偶尔也会出现“此商品已经下架”,一般用于出问题的商品,以此提示用户商店对此商品做了处理,将不再对外销售。下架,是一个汉语词语,意思是典当期满。 更多精彩资讯请关注七彩丝,我们将持续为您更新最新资讯! 查看...http://m.qicaisi.com/bk-1078144.shtml
2.库存中心操作指引文档注意:直邮模式的货品不可以使用预售,仅保税bbc模式的商品支持下文中的预售模式 0.创建货品 1.货品备案 2.注册登陆账号 3.如何操作货品预约入库/提货出库 4.如何修改库存(分配库存到商品宝贝) 4.1场景: 4.2路径: 4.3 SKU/商品链接的编辑变更 4.4 重点备注: 5.已经在途的库存赶不及入库要预售如何申请 5.1场景: 5.2...https://school.jinritemai.com/doudian/web/article/aHNuKGpC9fH1
3.饿了么餐饮服务商平台(3)企业应用承载的是大型商户的整体解决方案,平台应用承载的是中小型商户的痛点需求,平台应用会以商品的形式面向全量商户出现在应用市场中,企业应用仅对授权商户展示; (4)目前,平台应用仅面向1万家以上商户服务规模的ISV开放申请。 Q:饿了么API中的地理位置经纬度坐标是什么坐标系? https://open.shop.ele.me/base/documents/faq
4.分布式详解一致性算法全局唯一ID分布式锁分布式事务...这时,我们就可以建一张去重表,并且把唯一标识作为唯一索引,在我们实现时,把创建支付单据和写入去去重表,放在一个事务中,如果重复创建,数据库会抛出唯一约束异常,操作就会回滚。 插入或更新 这种方法插入并且有唯一索引的情况,比如我们要关联商品品类,其中商品的ID和品类的ID可以构成唯一索引,并且在数据表中也增加了...https://developer.aliyun.com/article/1416839
1.高效有序商品流通新模式,最新清货群介绍家政服务摘要:最新的清货群作为一种高效、有序的商品流通新模式,致力于优化商品流通环节,提高销售效率。通过加入清货群,商家能够更快速地处理存货,减少库存积压,实现商品快速流通。该模式组织有序,确保商品流通的顺畅和高效,为商家和消费者带来更加便捷、高效的购物体验。 https://www.jiuzichankang.cn/post/29616.html
2.淘宝api商品详情返回值说明淘宝api商品详情返回值说明 淘宝API商品详情返回值提供了商品的详细信息,这些信息对于商家进行商品展示、库存管理、价格监控以及用户行为分析等工作至关重要。以下是对淘宝API商品详情返回值的详细说明: 一、请求状态与错误信息 status:表示请求的状态,0为成功,非0为失败。https://blog.itpub.net/70042344/viewspace-3050338/
3.学编程多看多动手系列:Haskell事件溯源模式实现购物篮这段Haskell代码实现了一个基于事件溯源(Event Sourcing)模式的购物篮系统。事件溯源是一种软件架构模式,其中系统的状态不是直接存储的,而是通过一系列不可变的事件(记录了系统状态的变化)来重建的。主要功能包括: 定义基本类型:定义了产品(Product)、价格(Price)和折扣(Discount)等基本类型。 https://blog.csdn.net/gzjimzhou/article/details/143923938
4.Java商品自动下架解决方案java商品超卖首先想到的解决办法就是通过事务来解决,先更新后查询,然后判断是否超库存,若发生超卖则抛出异常,通过spring事务回滚处理。但最后分析了这种方案的缺陷:spirng事务不能严格保证数据一致性和业务逻辑正确性,而且减库存的压力全部落在数据库身上,不能保证高并发。https://blog.51cto.com/u_16099343/7114915
5.2024年最新加密货币的行话术语大全币种百科区块链暗网不能够被常规的网络协议访问,只可使用非常规协议和端口以及可信节点进行连接的私有网络。 API 在数字货币交易中,API能够让用户和应用程序或服务数据进行即时沟通,从而自行操作交易、获取行情数据等。 阿尔法 常用于指软件开发的第一阶段内部测试的版本,含义与“开始”、“第一个”相近。 https://www.jb51.net/blockchain/931845.html
6.大数据常见面试问题汇总江阴雨辰互联2.15.7 哪个商品卖的好? 2.15.8 数据仓库每天跑多少张表,大概什么时候运行,运行多久? 2.15.9 哪张表数据量最大 2.15.10 哪张表最费时间,有没有优化 2.15.11 并发峰值多少?大概哪个时间点? 2.15.12 分析过最难的指标 2.15.13 数仓中使用的哪种文件存储格式 ...https://www.yc00.com/news/1698791689a880360.html
7.gpmall/PRDatmaster·qfmx/gpmall·GitHub共有7个状态来控制商品的上架流程分别是:刚创建、提交审核、审核通过、申请驳回、商品删除、上架、下架,只有处于已上架状态的产品,用户才可能看到商品,各个细节形成一个完整的闭环 二、交易管理 1. 全部订单 功能描述 查看所有的订单,并可以打印订单详情,查看订单具体内容,货到付款的订单可以设置为已经收款。 https://github.com/qfmx/gpmall/tree/master/PRD
8.MySQL三万字精华总结写在之前:不建议那种上来就是各种面试题罗列,然后背书式的去记忆,对技术的提升帮助很小,对正经面试也没什么帮助,有点东西的面试官深挖下就懵逼了。 个人建议把面试题看作是费曼学习法中的回顾、简化的环节,准http://it.sdmtkj.net/cbs/caodneg7-p-13353659
9.ES亿级商品索引拆分实战腾讯云开发者社区伴随政府采购业务的快速发展,政采云的商品数据量也在快速膨胀,其中由 ES 进行提供的商品检索服务压力,也越来越大。由于商品模型中基础商品和交易商品的定义,导致商品本身的量会相对一般的电商场景多出一倍。 商品模型简介 基础商品 真实的商品,拥有仓库,主图,属性等商品主体信息。 https://cloud.tencent.com/developer/article/2321886
10.《亿级流量网站架构核心技术》——读书笔记重试(等一会再试、尝试其他分组服务、尝试其他机房服务,重试算法可考虑使用如指数退避算法) 摘掉不存活节点(负载均衡/分布式缓存场景下) 托底数据(返回历史数据/静态数据/缓存数据/) 等待页或者错误页 第7章:回滚机制 1、回滚概念 当程序或数据出错时,将程序或数据恢复到最近的一个正确版本的行为。最常见的如事务回...https://maimai.cn/article/detail?fid=1314479668&efid=FAc2Rl0U8HrqVe_nhjXoZg
11.KingbaseEs事务支持DDL回滚吗?()环控专业大风机控制柜(软启动控制柜,变频控制柜)与电力专业双电源接口界定:大风机控制柜进线断路器上口三相固定螺丝为界,以上为电力专业负责,以下由环控专业负责,螺丝的紧固由环控专业负责,电力专业配合停、送电。https://www.shuashuati.com/ti/23084f7c535244d9a3e84389130a922fa1.html
12.MySql面经原子性(Atomicity):一个事务中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节,而且事务在执行过程中发生错误,会被回滚到事务开始前的状态,就像这个事务从来没有执行过一样,就好比买一件商品,购买成功时,则给商家付了钱,商品到手;购买失败时,则商品在商家手中,消费者的钱也没花出去。 https://www.jianshu.com/p/5244fc598cd0
13.微信,爆更!三?视频号商品可“先买后付” 这次更新后,视频号内商品可以先购买,收货后再付款。 不过这一功能有微信支付分的要求,如果微信支付分没有达标,无法使用这一功能。 四?个人名片显示视频号名称 有网友爆料,这次更新后如果你的好友有开通视频号功能,那么会在他的个人名片上显示视频号的名字以及认证信息。 https://m.jrj.com.cn/madapter/finance/2023/09/24131237902350.shtml