1.构设计话题

**须知:**在实际的工作中,不管任何一个公司均不会一开始就可以设计出合理的架构方案,而是在满足业务需求的情况下不断带带诱惑出来的这是一个持续的过 程。当然如果一开始有一个好基础系统设计,未来更容易达到一个比较满意的目标。

在设计系统时,要因场景、时间而异,一个系统也不是一下子就能设计的非常完美,在资源有限的情况下,一定是先解决当下最核心的问题,预测现在未来可能出 现的问题,一步步解决最头疼的问题。也就是说一个好的设计要做到,解决现有需求和问题,把控实现和进度风险,预测和规划未来,不要过度设计,从迭代中演 进和完善。

在设计系统时,应该多思考 墨 菲 定 律

1. 任何事都没有表面上看起来那么简单。

2. 所有的事做起来都会比你预计的时间长。

3. 可能出错的事总会出错。

4. 如果你担心某种情况发生,那么它就更有可能发生。

在划分时,也要思考康威定律。

1. 系统架构是公司组织架构的反映。

2. 应该按照业 务闭环进行系统拆分/组织架构划分,实现闭环、高内聚、低耦合,减少沟通成本。

3. 如果沟通出现问题,那么就应该考虑进行系统和组织架构的调整。

4. 在合适时机进行系统拆分,不要一开始就把系统/服务拆得非常细,虽然闭环,但是每个人维护的系统多,维护成本高。

2.架构演变

由 单 机 计 算 机 的 架 构 ——>分 布 式 计 算 机 架 构

前言:一个成熟的大型网站系统架构并不是一开始就设计的非常完美的,世上没有完美的架构,也不是一开始就具备高性能、高可用、安全性等特性,而 是随着用户量的不断增加、业务功能的扩展逐步完善演变过来的。在这个过程中,开发模式、技术架构等都会发生非常大的变化。而针对不同的业 务特征的系统,会有各自的侧重点,比如像淘宝这类网站,要解决的是海量商品搜索、下单、支付等问题;像腾讯,要解决的是数亿级别用户的实 时消息传输;百度所要解决的是海量数据的搜索。每一类的业务都有自己不同的系统架构。

我们以电商系统的发展演变为例,分析架构演变历程。 关注的是数据量、访问量提升,网站结构发生的变化,而不是具体关注业务功能点。其次, 这个过程是为了让大家更好的了,解网站演进过程中的一些问题和应对策略。

假如我们系统具备以下功能: 用户模块:用户注册和管理 商品模块:商品展示和管理 交易模块:创建交易及支付结算

2.1. 单机负载

得回忆公司刚创业那会。那是很多年前,那天,公司成立了,老板兴致勃勃的租了一间民宅,买了一台服务器。然后大伙几个就开干了。 大伙把所有软件和应用都部署在一台机器上,这样就完成一个简单系统的搭建,这个时候的讲究的是效率。 我们在一台机子上装了lnmp,下图描述了我们这台服务器:

最初的架构,应用程序、数据库、文件都部署在一台服务器上:

2.2. 数据库服务器和应用服务器分离

随着网站的上线,访问量逐步上升,服务器的负载慢慢提高,在服务器还没有超载的时候,我们应该做好规划,提升网站的负载能力。假如代码层面的优化已经没 办法继续提高,在不提高单台机器的性能,增加机器是一个比较好的方式,投入产出比非常高。这个阶段增加机器的主要目的是讲 web 服务器和 数据库服务器拆 分,这样不仅提高了单机的负载能力,也提高了容灾能力。并且根据服务器的用途配置不同的硬件,达到最佳的性能效果。

应用、数据、文件分离:

2.3. 利用缓存改善网站性能

在硬件优化性能的同时,同时也通过软件进行性能优化,在大部分的网站系统中,都会利用缓存技术改善系统的性能,使用缓存主要源于热点数据的存在,大部分 网站访问都遵循28原则(即80%的访问请求,最终落在20%的数据上),所以我们可以对热点数据进行缓存,减少这些数据的访问路径,提高用户体验。

利用缓存改善网站性能:

2.4. 使用集群改善应用服务器性能

随着访问量的继续增加,单台应用服务器已经无法满足需求。在假设数据库服务器还没有遇到性能问题的时候,我们可以增加应用服务器,通过应用服务器集群将 用户请求分流到各个服务器中,从而继续提升负载能力。此时多台应用服务器之间没有直接的交互,他们都是依赖数据库各自对外提供服务。应用服务器前面部署 负载均衡服务器调度用户请求,根据分发策略将请求分发到多个应用服务器节点

另外,我们还可以增加缓存服务器集群, 来提高访问速度并降低mysql等数据库的压力

应用服务器集群和缓存服务器集群 :

2.5. 数据库压力变大,数据库读写分离

架构演变到这里,并不是终点。上面我们把应用层的性能拉上来了,但是数据库的负载也在慢慢增大,那么怎么去提高数据库层面的负载呢?有了前面的思路以 后,自然会想到增加服务器。但是假如我们单纯的把数据库一分为二,然后对于后续数据库的请求,分别负载到两台数据库服务器上,那么一定会造成数据库不统 一的问题。 所以我们一般先考虑读写分离的方式, 。

分库分表不是这个阶段要考虑的,是数据库优化的终极技能,因为会带来一些难题,所以能不用就不用.

数据库读写分离:

2.6. 使用NoSQL和搜索引擎缓解读库的压力

数据库做读库的话,常常对模糊查找效率不是特别好,像电商类的网站,搜索是非常核心的功能,即便是做了读写分离,这个问题也不能有效解决。那么这个时候 就需要引入Nosql和搜索引擎了。对于海量数据的查询和分析,我们使用NoSQL数据库加上搜索引擎可以达到更好的性能。并不是所有的数据都要放在关系型数据中。 常用的NoSQL有MongoDB、HBase、Redis,搜索引擎有Lucene、Solr、Elasticsearch。

N oSQ L和搜索引擎

2.7. 使用CDN和反向代理提高网站性能

假如我们的服务器都部署在成都的机房,对于四川的用户来说访问是较快的,而对于北京的用户访问是较慢的,这是由于四川和北京分别属于电信和联通的不同发 达地区,北京用户访问需要通过互联路由器经过较长的路径才能访问到成都的服务器,返回路径也一样,所以数据传输时间比较长。对于这种情况,常常使用CDN 解决,CDN将数据内容缓存到运营商的机房,用户访问时先从最近的运营商获取数据,这样大大减少了网络访问的路径。比较专业的CDN运营商有蓝汛、网宿。

而反向代理,则是部署在网站的机房,当用户请求达到时首先访问反向代理服务器,反向代理服务器将缓存的数据返回给用户,如果没有缓存数据才会继续访问应 用服务器获取,这样做减少了获取数据的成本。反向代理有Squid、Nginx。

使用CDN 和反向代理提高网站性能

2.8. 将应用服务器进行业务拆分

随着业务进一步扩展,应用程序变得非常臃肿,这时我们需要将应用程序进行业务拆分,如百度分为新闻、网页、图片等业务。每个业务应用负责相对独立的业务 运作。业务之间通过消息进行通信或者共享数据库来实现。

业务拆分

2.9. 数据库的水平、垂直拆分

我们的网站演进的变化过程,交易、商品、用户的数据都在同一个数据库中,尽管采取了增加缓存,读写分离的方式,但是随着数据库的压力持续增加,数据库的 瓶颈仍然是个最大的问题。因此我们可以考虑对数据的垂直拆分和水平拆分。

垂直拆分:把数据库中不同业务数据拆分到不同的数据库。

水平拆分:把同一个表中的数据拆分到两个甚至跟多的数据库中,水平拆分的原因是某些业务数据量已经达到了单个数据库的瓶颈,这时可以采取讲表拆分到多个 数据库中。

2.10. 服务拆分

这时我们发现各个业务应用都会使用到一些基本的业务服务,例如用户服务、订单服务、支付服务、安全服务,这些服务是支撑各业务应用的基本要素。我们将这 些服务抽取出来利用分部式服务框架搭建分布式服务。阿里的Dubbo是一个不错的选择。

服务拆分

3.理解分布式和集群以及微服务

分布式

分布式服务顾名思义服务是分散部署在不同的机器上的,一个服务可能负责几个功能,是一种面向SOA架构的, 服务之间也是通过rpc来交互或者是webservice来 交互的。逻辑架构设计完后就该做物理架构设计,系统应用部署在超过一台服务器或虚拟机上,且各分开部署的部分彼此通过各种通讯协议交互信息,就可算作分 布式部署,生产环境下的微服务肯定是分布式部署的,分布式部署的应用不一定是微服务架构的,比如集群部署,它是把相同应用复制到不同服务器上,但是逻辑功 能上还是单体应用。

在架构演变中的 3.2. 数据库服务器和应用服务器分离 实际就是一种分布式的方式部署;服务之间的职责各有不同;

集群

集群就是多个服务之间的职责相同,对于集群来说如果一个节点出现了问题,那么就可以让其他的节店顶上

其中MySQL的主从也是属于集群

微服务

微服务关注:架构设计方式;分布式关注:系统部署方式(两者概念不同) 主要是基于项目的业务模块进行细节化的拆分;把整个项目可以基于模块,功能拆分为单独的系统

比如

4. 高并发下拆分的原则

4.1.拆分

在系统设计初期,是做一个大而全的系统还是按功能模块拆分系统,这需要根据环境权衡;如果项目只是一个人就不要拆分,如果是项目比较大如京东,淘宝这样 的系统访问量是非常大的,而且设计时投入的资源足够就可以按功能拆分系统

系 统 维 度 :按照系统功能业务拆分,比如商品系统、购物车、结算、订单系统等。 功 能 维 度 :对一个系统进行功能再拆分,比如,优惠券系统可以拆分为后台券创建系统、领券系统、用券系统等。 读 写 维 度 :根据读写比例特征进行拆分。比如,商品系统,交易的各个系统都会读取数据,读的量大于写,因此可以拆分成商品写服务、商品读服务;读服务可以考

虑使用缓存提升性能:写的量太大时,需要考虑分库分表;有些聚合读取的场景,如商品详情页,可考虑数据异构拆分系统,将分散在多处的数据聚合到一处存储,

以提升系统的性能和可靠性。

模  维 度 :比如,按照基础或者代码维护特征进行拆分,如基础模块分库分表、数据库连接池等:代码结构般按照三层架构 (Web、Service、 MODEL)进行划分。

AOP维 度 :根据访问特征,按照AOP进行拆分,比如,最典型的例子就是权限,配置

如下是对应拆分体系图:

AKF扩展立方体(参考《The Art of Scalability》),是一个叫AKF的公司的技术专家抽象总结的应用扩展的三个维度。理论上按照这三个扩展模式,可以将一个单体 系统,进行无限扩展。

X 轴 :指的是水平复制,很好理解,就是讲单体系统多运行几个实例,做个集群加负载均衡的模式。

Z 轴 :是基于类似的数据分区,比如一个互联网打车应用突然或了,用户量激增,集群模式撑不住了,那就按照用户请求的地区进行数据分区,北京、上海、四川 等多建几个集群。

Y 轴 :就是我们所说的微服务的拆分模式,就是基于不同的业务拆分。 场 景 说 明 :比如打车应用,一个集群撑不住时,分了多个集群,后来用户激增还是不够用,经过分析发现是乘客和车主访问量很大,就将打车应用拆成了三个乘

客服务、车主服务、支付服务。三个服务的业务特点各不相同,独立维护,各自都可以再次按需扩展

4.1. 服务化

基于5.1的方式与规则进行系统的拆分,接下来需要做的就是系统服务化; 服务主要是指相对独立、功能内聚的一组业务,数据自我包含,对外提供标准化的业务功能或业务数据接口。不同服务之间是松耦合的,而服务自身也能获得更好

的复用。

服务化架构就是将原有的统一型架构按业务特点进行服务拆分,再通过服务注册以及企业服务总线将服务进行串联,从而构建出整个系统。

1. 服务和组件的区别

组件在功能上和服务有一定的相似性,都是完成一定的业务功能,都有内聚性。 两者不同之处主要在使用.上,组件要求包含在业务系统内部,需要业务系统进行集成,如果组件的功能发生了修改,则所有弓|用此组件的业务系统都需要进行组件

升级。而服务则是在业务系统外部独立部署的,业务系统仅需要调用服务的接口来完成功能即可,如果服务内部的功能发生了修改,只将该服务升级即可,其期调用

服务的业务系统并不要修改。

2. 服务和子系统的区别

服务和子系统在业务上都可完成一定的业务功能, 都可对外提供接口接入。两者的区别主要还是在系统功能的独立性上,子系统可以独立的安装部署,提供完整的 一-块业务功能供用户使用,而服务则还是需要依托业务系统,它无法独立于业务系统或其他服务单独给用户使用。

需要注意:服务化需要思考的点 首先,判断是不是只需要简单的单点远程服务调用,单机不行集群是不是就可以解决?在客户端注册多台机器并使用Nginx进行负载均衡是不是就可以解决?随着调

用方越来越多,应该考虑使用服务自动注册和发现(如Dubbo使用ZooKeeper)。 其次,还要考虑服务的分组/隔离,比如,有的系统访问量太大,导致把整个服务拖

垮,因此,需要为不同的调用方提供不同的服务分组,隔离访问。后期随着调用量的增加还要考虑服务的限流、黑白名单等。还有一.些细节需要注意,如超时时

间、重试机制、服务路由(能动态切换不同的分组)、故障补偿等,这些都会影响到服务的质量。

总结为:进程内服务→单机远程服务→集群手动注册服务→自动注册和发现服务→服务的分组/隔离/路由→服务治理放在括号内。

4.1. 无状态

如果设计的应用是无状态的,那么应用比较容易进行水平打展。实际生产环境可能是这样的:应用无状态,配置文件有状态。比如,不同的机房需要读取不同的数据 源,此时,就需要通过配置文件或配置中心指定。

有状态:如果一个数据需要被多个服务共享,才能完成一笔交易,那么这个数据被称为状态。进而依赖这个“状态”数据的服务被称为有状态服务,反之称为无状态 服务。

那么这个无状态服务原则并不是说在微服务架构里就不允许存在状态,表达的真实意思是要把有状态的业务服务改变为无状态的计算类服务,那么状态数据也就相 应的迁移到对应的“有状态数据服务”中。

场景说明:例如我们以前在本地内存中建立的数据缓存、Session缓存,到现在的微服务架构中就应该把这些数据迁移到分布式缓存中存储,让业务服务变成一个无 状态的计算节点。迁移后,就可以做到按需动态伸缩,微服务应用在运行时动态增删节点,就不再需要考虑缓存数据如何同步的问题。

4.2.消息队列/rpc/restful

1. RestFul - REST over HTTP(S)

2. 消息队列

3. RPC (跨语言或单语言)

• 理 解 通 信

RestFul - REST over HTTP(S)

自Roy Fielding提出RESTful架构自提出以来,一直都是备受欢迎的方案,特别是在Web应用的开发中。Fielding提出的约束虽然不是标准,但在声明我们的API为 RESTful之前,应该始终遵循这些约束。

HTTP上有各种各样的REST,因为没有强制执行的标准。开发人员可以自由选择以JSON、XML或某种自定义格式形成请求有效负载。 REST over HTTP(S)仅意味着使用REST架构风格并通过HTTP(S)发送请求

消息队列

消息队列用来解耦此不需要同步调用的服务或者订阅一些自己系统关心的变化。使用消息队列可以实现服务解耦(- 对多消费)、异步处理、流量削峰/缓冲等。比 如,电商系统中的交易订单数据,有非常多的系统关心并订阅该数据,比如,订单生产系统、定期送系统、订单风控系统等等。如果订阅者太多,那么订阅单个消 息队列就会成为瓶颈,此时,需要考虑对消息队列进行多个镜像复制。

使用消息队列时,还要注意处理生产消息失败,以及消息重复接收时的场景。有些消息队列产品会提供生产重试功能,在达到指定重试次数还未生产成功时,会对 外通知生产失败。这时,对于不能容忍生产失败的业务场景来说,一定 要做好后续的数据处理工作,如持久化数据要同时增加日志、报警等。对于消息重复问 题,特别是一” 些分布式消息队列,出于对性能和开销的考虑,在一-些场景下会发生消息重复接收,需要在业务层面进行防重处理。

RPC(跨语言或单语言)

远程过程调用在分布式系统中并不新鲜,它通过在网络上的另一个设备上执行函数/方法/过程来工作。

1. 超时和重新连接需要处理服务器崩溃,即使使用了面向连接的协议(TCP)

2. 不指定服务和客户机的绑定,具体由实现人员决定

3. RPC实现的强制性要求:

被调用过程的唯一规范 响应消息与请求消息匹配的规定 对调用方进行服务身份验证的规定,反之亦然

• 消 息 队 列 与 rpc选 择

RestFul:一般是对外提供服务提供给web端或者其他系统调用

rpc:实时性强 要实时返回数据用rpc, 比如查看商品列表,订单列表等等,通过rpc同步实时获取数据。

mq队列:下单那里,牵涉到减库存,发短信等,这些东西用户并不需要你实时返回,用户也不关心,就放到队列mq里面,采用异步的方式处理就行了。

4.3.数据异构

• 数 据 异 构

订单分库分表一般按照订单ID进行,如果要查询某个用户的订单列表,则需要聚合多个表的数据后才能返回,这样会导致订单表的读性能很低。此时需要对订单表 进行异构,异构一套用户订单表,按照用户ID进行分库分表。另外,还需要考虑对历史订单数据进行归档处理,以提升服务的性能和稳定性。而有些数据异构的意 义不大,如库存价格,可以考虑异步加载,或者合并并发请求。

• 数 据 闭 环

如商品详情就需要获取:商品品牌,商品价格(要求实时性),图片,店铺,评价等等;这些数据在微服务的拆分下可能会分为如“用户服务,商品服务,交易服 务,评价服务,店铺服务,订单服务”

实现数据闭环,如商品详情页,因为数据来源太多,影响服务稳定性的因素就非常多。最好的办法是把使用到的数据进行异构存储,形成数据团环,基本步骤如 下。

因素:1. 核心就是速度需要,2. 数据分撒需要调用不同的服务,3. 网络及服务问题等

数 据 异 构 :通过如MQ机制接收数据变更,然后原子化存储到合适的存储引擎,如Redis或持久化KV存储。

数 据 聚 合 : 这一步是可选的,数据异构的目的是把数据从多个数据源数据聚合的目的是把这些数据做聚合,这样前端就可以个调用拿到此步骤般存储到KV存储 中。

前 端 展 示 : 前端通过一次或少量几次调用拿到所需要的数据。 这种方式的好处就是数据的闭环,任何依赖系统出了问题,还是能正常工作, 只是更新会有积压,但是不影响前端展示。

数据闭环和数据异构其实是一个概念,目的都是事先数据的自我控制,当其他系统出现问题的时候不影响自己的系统,或者自己出问题的时候不影响其他系统。一 般通过消息队列来实现数据分发.

4.4. 缓存银弹

缓存对于度服务来说可谓抗流量的银弹,可总结为下:

4.4.1.浏 览 器 端 缓 存

设置请求的过期时间,如对响应头Expires、Cache-control 进行控制。这种机制适用于对实时性不太敏感的数据,如商品详情页框架、商家评分、评价、广告词等: 但对于价格、库存等实时要求比较高的数据,就不能做浏览器端缓存。

4.4.2.APP客 户 端 缓 存

在大促时为了防止瞬间流量冲击,一般会在大促之前把 APP需要访问的一些素材(如jssimage等)提前下发到客户端进行缓存,这样在大促时就不用去拉取这些素 材。另外,如首屏数据也可以缓存起来,在网络异常情况下还是有拖地数据给用户展示;如APP题图一般也会做地图的离线缓存

4.4.3.接 入 层 缓 存

如NGINX搭建一层接入层,该接入层可以考虑

使用如下机制实现: proxy+cache:代理缓存

4.4.4.并 发 化

假设一个读服务需要如下数据

如果 串行执行获取,那么需要60ms

如果A数据,B数据,数据D 三者不会依赖谁;而数据C 依赖A和B,数据E需要C的数据;那么可以通过如下方式获取。

如果并发化获取,则需要30ms,提升一倍的性能

5. 高可用原则

微服务的雪崩效应 除了对服务可用性的追求,微服务架构一个绕不过去的问题就是服务雪崩。 在一个调用链路上,微服务架构各个服务之间组成了一个松散的整体,牵一发而动全身,

服务雪崩是一个多级传导的过程,首先是某个服务提供者不可用,由于大量超时等待,继而导致服务调用者不可用,并且在整个链路上传导,继而导致系统瘫痪。

5.1.限流

限流的目的是防止恶意请求流量,恶意攻击,或防止流量超出系统峰值的策略 思路:

1. 恶意请求流量只访问到cache

2. 对于穿透到后端应用的流量可以考虑使用NGINX的limit模块处理

3. 对于恶意IP可以使用nginx deny进行屏蔽。

原则是限制流量穿透到后端薄弱的应用层

5.2. 降级

什么是降级:就是原原本需要考虑高校实时性相应数据,但是因为服务扛不住改为读缓存;或者需要获取的数据很多但是没有办法处理好则选择降级返回少量数 据。

典型生活例子:车站购票,平常与高峰期的处理 对于一个高可用服务,很重要的一个设计就是降级开关,在设计降级开关时,主要依据如下思路。

1. 开关集中化管理:通过推送机制把开关推送到各个应用

2. 可降级的多级读服务:比如

3. 开关前置化:如架构师Nginx->swoft,可以讲开关前置到NGINX接入层,在nginx层做开关,请求流量不回源后端swoft应用或者只是一小部分流量回源。

4. 业务降级:当高并发流量来袭,在电脑系统打出设计时保障用户能下单、能支付是核心要求,并保障数据最终一致性即可。这样就可以把一些同步调用改成异 步调用,优先处理高优先级数据或特殊特征的数据,合理分配进入系统的流量,以保障系统可用。

5.3.熔断

理解熔断

如果某个目标服务调用慢或者有大量超时,此时熔断该服务的调用,对于后续调用请求,不在继续调用目标服务,直接返回,快速释放资源。 服务隔离与前面的三个略有区别,我们的系统通常提供了不止一个服务,但是这些服务在运行时是部署在一个实例,或者一台物理机上面的, 如果不对服务资源做隔离,一旦一个服务出现了问题,整个系统的稳定性都会受到影响!服务隔离的目的就是避免服务之间相互影响。 一般来说,隔离要关注两方面,一个是在哪里进行隔离,另外一个是隔离哪些资源。

何处隔离 一次服务调用,涉及到的是服务提供方和调用方,我们所指的资源,也是两方的服务器等资源,服务隔离通常可以从提供方和调用方两个方面入手。

隔离什么 广义的服务隔离,不仅包括服务器资源,还包括数据库分库,缓存,索引等,这里我们只关注服务层面的隔离。

降级和熔断的区别

服务降级和熔断在概念上比较相近,通过两个场景,谈谈我自己的理解。

熔断,一般是停止服务 典型的就是股市的熔断,如果大盘不受控制,直接休市,不提供服务,是保护大盘的一种方式。

降级,通常是有备用方案 从北京到济南,下雨导致航班延误,我可以乘坐高铁,如果高铁票买不到,也可以乘坐汽车或者开车过去。

两者的区别

降级一般是主动的,有预见性的,熔断通常是被动的,服务A降级以后,一般会有服务B来代替,而熔断通常是针对核心链路的处理。在实际开发中,熔断的下一步 通常就是降级。

5.4.切流量

对于一个大型应用,切流量是非常重要的,比如多机房环境下某个机房挂了,或者某个机架挂了,或者某台服务器挂了,都需要切流量,可以使用如下手段进行切 换。

1. DNS:切换机房入口。

2. HttpDNS:主要在APP场景下,在客户端分配好流量入口,绕过运营商LocalDNS并实现更精准的流量调度。

3. LVS/HaProxy: 切换故障的Nginx接入层。

4. Nginx:切换故障的应用层。

另外,有些应用为了更方便切换,还可以在Nginx接入层做切换,通过Nginx进行一些流量切换,而没有通过如LVS/HaProxy做切换。

5.5. 可回滚

版本化的目的是实现可审计前面加顿号,并且可回滚。当程序或数据出错时,如果有版本化机制,那么就可以通过回滚恢复到最近-个正确的版本, 比如事务回 滚、 代码库回滚、部署版本回滚、数据版本回滚、静态资源版本回滚等。通过回滚机制可保证系统在某些场景下的高可用。

6. 业务设计原则

6.1.防重设计

比如,结算页需要考虑重复提交,还有如下单扣减库存时需要防止重复扣减库存。解决方案可以考虑防重key、防重表。而有些场景如重复支付,是因为有的电商 网站同时支持微信支付、京东支付,渠道不样是无法防止重复 支付的。但是,在系统设计时,需要将支付的每笔情况记录下来。

6.2.幂等设计

在交易系统中,经常会用到消息,而现有消息中间件基本不保证不发生重复消息的消费。因此,需要业务系统在重复消息消费时进行幂等处理。还有在使用第三方 支付时,第三方支付会进行异步回调,也要考虑做好回调的幂等处理。

6.3. 流程可定义

如果接触过保险业务,就会发现不同保险的理赔服务是不一样的。我们在系统设计时就设计了一套理赔流程服务。而承保流程和理赔流程是分离的,在需要时进行关联,从而可以复用一些理赔流程,并提供个性化的理赔流程。

6.4. 状态与状态机

在设计交易订单系统时,会存在正向状态(待付款、待发货、已发货、完成)和逆向状态(取消、退款)等,正向状态和逆向状态应该根据系统的特征来决定要不要分离 存储。状态设计时应有状态轨迹,方便用户跟踪当前订单的轨迹并记录相关日志,万一出问题时可回溯问题。

另外,还有订单状态的变迁,比如待支付、已支付待发货、待收货、完成的迁移。要考虑要不要使用状态机来驱动状态的变更和后续流程节点操作,尤其当状态很 多的时候使用状态机能更好地控制状态迁移。

还要 考虑并发状态修改问题,如一个订单同时只能有一个修改:状态变更的有序问题,以及状态变更消息的先到后到问题,如支付成功消息和用户取消消息的时间 差。

6.5. 后台系统操作可反馈

良好的系统中,很多场景都需要反馈,比如,修改了某些内容后想预览看看最终效果,即想得到一些反馈:还有一些是在规则系统中,希望看到这些规则在系统数据 下的反馈。因此,在设计后台系统时,需考虑效果的可预览、可反馈。

6.6. 后台系统审批化

对于有些重要的后台功能需要设计审批流,比如调整价格,并对操作进行记录日志,从而保证操作可追溯、可审计。

6.7. 文档和注释

实际中有些系统是完全没有文档、代码没有注释的,完全是人传人。这将导致后来人接手很痛苦,而对有些代码是完全不敢改动的, 比如,有些代码完 全是因为 业务的一些特 殊情况而写的,可以说没有注释是完全不懂为什么那么做的。因此,在一个系统发展的一开始就应该有 文档库(设计架构、设计思想、数据字典/业 务流程、现有问题),业务代码和特殊需求都要有注释。

6.8. 备份

备份包括代码备份和人员备份。代码主要提交到代码仓库进行管理和备份,代码仓库应该至少具备多版本的功能。人员备份指的是一一个系统至少应该有两名开发 人员是了解情况的,即使其中一名离职了 也不会出现新人接手之后手忙脚乱事故频发的状况。 还有一些是“核心人员”,写着系统的核心代码,被认为是“不可替代 的”,这种情况也尽可能地让他带一名兄弟 起开发核心代码 (业务系统),即使他离职,另一个 人也还是可以努力一下克服困难。

系统架构专题(1):大型互联网系统架构演变相关推荐

  1. 大型互联网系统架构演进之路

    作者丨老农小江 来源丨网址:https://blog.csdn.net/cndmss/article/details/123636370 一.前言 说到互联网系统架构,在互联网行业日渐成熟的今天,一谈 ...

  2. 架构杂谈——也谈互联网系统架构演进

    Tips: 说到互联网系统架构,随便网上一搜都有大量的相关文章/书籍,而这些,得益于过去几年互联网行业的快速发展与繁荣,在今天看来,这些技术/解决方案似乎早已不是什么新鲜的东西了,但是,本文笔者仍想简 ...

  3. 移动互联网系统架构特点及实践--手机凤凰网

    本文整理自:http://www.cnblogs.com/sunli/archive/2011/02/19/mobile_architecture.html 今天参加了InfoQ组织的百度技术沙龙活动 ...

  4. 《程序员》 -- 互联网系统架构的演进

    自己非常喜欢<程序员>杂志,<程序员>杂志在一定程序上很能开阔我们的视野.因此,一直都想推荐给大家. 方便大家相互学习交流,本文转自<程序员>杂志 http://w ...

  5. 互联网系统架构的演进--作者杨光辉,淘宝北京研发中心技术专家

    发表于2013-08-29 09:27| 25337次阅读| 来源<程序员>| 79 条评论| 作者杨光辉 <程序员>杂志2013年9月刊特别策划互联网系统架构技术架构性能系统 ...

  6. 互联网系统架构演变之一

    1. 程序三高 1)高并发 高并发(High Concurrency)是互联网分布式系统架构设计中必须考虑的因素之一.当多个进程或线程同时(或着说在同一段时间内)访问同一资源时会产生并发问题,因此需要 ...

  7. 电脑端京东的我的订单html+css页面_互联网系统架构前后端分离技术体系

    点击「京东数科技术说」可快速关注 「摘要」随着互联网技术的发展以及终端设备的不断增多,前后端分离技术已成为移动互联网领域不可或缺的技术.前后端分离技术的不断完善,让前后端的分工与系统边界划分越来越清晰 ...

  8. 互联网系统架构的演进

    多终端接入.开放平台给互联网带来了前所未有的用户量级和访问规模,SNS网站产生了海量的UGC(用户产生内容),而且这些内容依托关 系链扩散速度之快.传播范围之广是传统网站难以想象的,海量数据的计算存储 ...

  9. 【架构零】大型网站的架构的目标与挑战

    一.大型网站的特点 用户多,分布广泛 大流量,高并发 海量数据,服务高可用 安全环境恶劣,易受网络攻击 功能多,变更快,频繁发布 从小到大,渐进发展 以用户为中心 免费服务,付费体验 二.大型网站架构 ...

最新文章

  1. 如何使‘CREATE TABLE AS SELECT’能支持ORDER BY ?
  2. python 图像计算方位角
  3. boost::range模块sliced相关的测试程序
  4. 解决方案和项目的区别_沃尔玛用大数据提高销售额,云计算和大数据技术之间的区别汇总...
  5. kafka系列九、kafka事务原理、事务API和使用场景
  6. 2013年网络安全事件盘点
  7. linux cgoup内存限制,Linux Cgroup系列(05):限制cgroup的CPU使用(subsystem之cpu)
  8. 广西2021高考成绩位次查询,2020年广西高考一分一段表及高考位次成绩排名查询(理科+文科)...
  9. mysql 性能优化 20 条建议
  10. grails 私有库相关设置
  11. c语言编程中的幂函数如何编写,c语言幂函数_C语言循环与递归实现整数幂函数...
  12. Java连接数据库实现增删改;查。
  13. Windows自带工具提取颜色得到十六进制颜色码
  14. 计算机本地网络给手机使用吗,电脑共享网络给手机用的方法步骤
  15. 51单片机用1602液晶屏实现可调时钟
  16. android空指针异常Attempt to invoke virtual method
  17. IP地址、子网掩码、默认网关和DNS服务器之间的联系与区别
  18. 【SqlServer系列】子查询
  19. 题解 P2089 【烤鸡】
  20. android biz,魔轮(lcb.android.biz) - 2.6.7 - 应用 - 酷安

热门文章

  1. er图 navicat_navicat如何导出er图
  2. LVGL学习笔记 20 - 滚轮Roller
  3. rhce考试试题以及答案_rhce 考试题目总结
  4. 利用face-landmark估计pitch, yaw, roll
  5. 安全模式启动服务安全模式加载驱动.sys
  6. 使用Python编写微信自动回复脚本
  7. 复盘年度十大商业事件:不卓越,王难当!
  8. Chrome浏览器安装插件
  9. 安全测试工具之Hping3
  10. C语言制作电子时钟程序(内附代码)