破解高并发难题:百万到亿级系统架构实战指南

参考书籍《架构真意-企业级应用架构设计方法论与实践》作者 范刚 孙玄  机械工业出版社

        本书通过架构设计方法论、分布式架构设计与实践和大数据架构设计三部分内容,系统阐述了在软件开发的时候,如何设计软件架构,并且对1000万级、5000万级、亿级等不同量级流量的系统平台给出了不同的技术架构方案。书籍对于想快速熟悉软件架构构建思想和理念的从业者,有较大的帮助。

第一部分 架构设计方法论

架构设计按照“5视图法”分为逻辑架构设计、数据架构设计、开发架构设计、运行架构设计、物理架构设计。

第一章 架构师的修炼

架构师的职责:架构师是介于需求和研发中间的人,既要技术好,又要懂业务;架构师是统领全局的将军;架构师要作为“技术大牛”攻克技术难题;架构师要作为战略规划师去规划未来。

顶级架构师的三个特征:

1、顶级架构师在成长历程中,依次跨越愚昧之巅、绝望之谷、开悟之坡与持续平衡的高原这四个关键阶段,实现认知的逐步提升。在这一过程中,他们脚踏实地,扎实积累基础知识,积极投身实践,在丰富的项目历练中积累了宝贵的实操经验。

2、他们始终保持勤于思考的习惯,善于从复杂的现象中抽丝剥茧,学会运用抽象思维,精准抓取事物的本质特征。凭借长期的磨砺,他们逐渐具备了举一反三的能力,能够快速吸收新知识、掌握新技能。

3、尤为突出的是,即便涉足全新领域,他们也能凭借深厚的知识积淀与敏锐的思维洞察力,迅速获取比常人更为深刻的认知与领悟。此时,他们已深谙架构设计的哲学本质,能够站在更高的层次、更宏观的视角去思考问题,为项目的架构规划与决策提供极具前瞻性与战略性的指导 。

第二章节  逻辑架构设计

逻辑架构就是基于客户的需求,设计好软件要为客户提供哪些功能。

需求分析方法:用例模型。

用例模型是一套基于UML用例图进行需求分析的实践方法。用例模型包括三个元素:用例(use case)、参与者(actor)、系统边界(boundary)。用例描述的是系统为用户提供哪些功能,也就是系统能为用户做什么,通常绘制成一个椭圆。参与者,就是使用本系统的人,他们按照职责而被划分成不同的角色。

用例编写中,最重要的就是编写事件流,包括基流、分支流和替代流。基流又叫成功流或者主流程,指的是在所有流程都操作成功的时候,整个流程是怎么走下来的。分支流和替代流的区别是如果走了分支流,一定还会回到主流程,替代流又叫异常流,如果走了替代流就会结束流程,不再回到主流程。

业务需求列表,又称为需求跟踪表,是用户对业务需求的最原始描述。

需求规格说明书 在用户编写的原始需求的基础上,经过业务和需求两方面确认后的业务需求。

原型法:全名快速原型法,是指当捕获了一批业务需求后,立即使用可视化工具快速开发出一个原型,交给用户去试用、去补充、去修改。典型工具有Axure、墨刀、VUE等。

软件退化:在软件上线后,往往会经历各种各样的需求变更,需求变更一次,软件就修改一次,软件修改一次,质量就下降一档,不论第一次的设计质量有多高,经过几次变更后软件都会进入一种低质量、难以维护的状态,这就叫软件退化。

软件退化的根源 软件的本质就是对真实世界的模拟,每个软件都能在真实世界中找到它的影子。因此软件中业务逻辑正确与否的唯一标准就是是否与真实世界一致。软件做成什么样子,即不由我们决定,也不由客户决定,而是由客观世界决定。客户总在改需求,是因为他们也不确定客观世界的规则,只有遇到问题了才能想的起来。因此,对于我们来说,与其唯唯诺诺的按照客户的要求去做软件,不如主动的在理解业务的基础上去分析软件,而后者更有利于我们降低变更的成本。

那么,真实世界是怎么样,我们就怎样开发软件,不是就简单了吗?其实并非如此,因为真实世界非常复杂,而深刻理解真实世界中的这些业务逻辑是需要一定的时间的。因此,我们最开始只能认识真实世界中哪些简单,清晰,易于理解的业务逻辑,把他们做到我们的软件里。所以,每个软件的第一个版本总是那么清晰明了,易于设计。然而,当我们把第一个版本的软件交付用户使用的时候,用户会发现还有很多不简单、不明了、不易于理解的业务逻辑,还有些需求没有做到软件里。这使得用户在使用软件的过程中不方便、和真实世界不一致。因此,客户就会提Bug,提新需求。

在我们不断地修复Bug,实现新需求的过程中,软件的业务逻辑会越来越接近真实世界,使得我们的软件越来越专业,让用户感觉越来越好用。但是,在软件越来越接近真实世界的过程中,业务逻辑也会变的越来越复杂,软件规模越来越庞大。

为了避免或者减少软件退化,需求变更和设计需要遵守“开放封闭原则OCP”和“两顶帽子”的设计方式:

开放封闭原则OCP:

1、开放原则:我们开发的软件系统,对于功能扩展是开放的(Open for Extension),即当系统需求发生变更时,我们可以对软件功能进行扩充,使其满足客户的新需求。

2、封闭原则:对软件代码的修改应该是封闭的(Close for Modification),即在修改软件的同时,不要影响到系统原有的功能,新代码和老代码应该隔离,不能在同一个类、同一个方法中。

两顶帽子设计方式

1、在不增加新功能的情况下,重构代码,调整原有程序结构,以适应新功能;

2、实现新的功能。

DDD-Domain Driven Design 领域驱动设计:将真实世界和软件世界对应起来的设计思想,包括三个方面的内容:

1、真实世界有什么事物,软件世界就有什么对象;

2、真实世界中这些事物都有哪些行为,软件世界中这些对象就有哪些方法;

3、真实世界中这些事物间都有哪些关系,软件世界这些对象间就有什么关联。

领域驱动设计DDD的设计遵守“单一职责原则”:软件系统中的每个元素只完成自己职责范围内的事,而将其他的事交给别人去做,自己只是去调用。

第三章节  数据架构设计

数据架构就是对功能性需求进行分析,抓住功能性需求的核心。

传统的软件设计过程:需求文档---->数据库设计---->程序设计

面向对象的软件设计过程:需求文档---->用例设计---->领域模型设计---->数据库设计+程序设计

要将领域模型映射到程序设计,最终都会落实到三种类型的对象设计:服务、实体和值对象。

服务:领域对象之外的操作和行为。服务通常承担两种职责:接受用户的请求、执行某些操作。

实体:通过唯一一个标识字段来区分真实世界中的每一个个体的领域对象。比如学员对象就是一个实体。可变性是实体的特点。

值对象 Value Object:真实世界中些那一成不变的、本质性的事物。比如地理位置、行业、职位。不变性是值对象的特点。

聚合:DDD中的一个重要概念,真实世界中那些整体和部分的关系,如订单和订单明细,当整体不存在时,部分就没有了意义。聚合的好处,当聚合内部的业务逻辑发生变更时候,只和聚合内部有关,只需要对聚合内部进行更新,而与外部程序无关,从而有效降低变更的维护成本,提高系统的设计质量。

聚合根:在聚合关系中,对部分的操作必须要通过整体,整体成为了外部访问的唯一接口,整体被称为聚合根。

仓库(Repository),采用DDD后,通常会实现一个仓库(Repository)去完成对数据库的访问。

工厂  DDD中通过装配来创建领域对象,是领域对象生命周期的起点,如订单工厂会将装配好的订单对象返回给订单仓库。

问题域:真实世界的问题和业务叫做问题域。

限界上下文Context Bound:对一个复杂系统的领域驱动设计,就是以子域为中心进行领域建模,比如在线订餐系统包含了用户下单、饭店接单、骑士派送等子域。这样绘制出的一张一张的领域模型,称为限界上下文。

第四章节  开发架构设计

开发架构就是系统性的规划软件代码的层次骨骼。

开发设计阶段,架构师主要完成以下几项工作:系统规划、接口定义、系统分层、技术选型、代码规范。

MVC设计模式:MVC(Model-View-Controller)设计模式是一种广泛应用于软件开发的架构模式,它将软件应用程序分为三个主要部分:模型(Model)、视图(View)和控制器(Controller),通过明确的职责划分,提高了代码的可维护性、可扩展性和可测试性。MVC模式被J2EE架构所广泛采用,如今MVC主要负责完成系统前后端交互,即完成前端提交的请求参数,并将其塞入值对象中,或者将执行结果返回给前端。在这个过程中,不包含任何业务逻辑与判断,仅仅进行一些数据转换。

整洁架构(The Clean Architecture),以圆环的形式把架构分成了几个不同的层次,因此又被称为洋葱架构(The Onion Architecture),中心是业务实体(Entity)与业务应用(Application),业务实体就是那些核心业务逻辑,而业务应用就是面向用户的服务(Service),他们合起来构成了业务领域层,也就是通过i领域模型形成的业务代码的实现。

整洁架构的最外层是各种技术架构,包括与用户界面的交互、客户端与服务器的网络交互、与硬件设备和数据库的交互以及与其他外部系统的交互。而整洁架构的精华在于其中间的适配器层,他通过适配器将核心的业务代码与外围的技术架构进行解耦。因此,如何设计这个适配层,让业务代码与技术框架解耦,让业务开发团队和技术开发团队各自独立的工作,就成了整个整洁架构落地的核心。在整洁架构设计中,适配器层通过数据接入层、数据访问层与接口层等几个部分的设计,实现与业务的解耦。

命令与查询职责分离(Command Query Responsibility Segregation,CQRS)是软件大师Martin Follow在《企业应用架构模式》提出来的一种架构设计模式,该模式将系统按照职责划分为命令(即增删改操作)和查询两部分。所有命令部分的增删改操作都应该采用DDD的思想进行软件设计,从而更好的应对大规模复杂应用;所有的查询功能则不适用于DDD,而应该采用事物脚本(Transaction Script)模式,即直接通过SQL语句进行查询。

第五章节  运行架构设计

运行架构就是软件在运行过程中所体现出来的非功能性需求。

软件重构的几个简单易行的方法:抽取方法、抽取类、抽取接口。

第六章节  物理架构设计

物理架构就是软件的物理部署及网络拓扑。

网络架构图:网络架构图将系统建设分为四个区域,分别是互联网区域、数据隔离区区域、外网区域和内网区域。

数据隔离区域主要负责入侵检测、漏洞扫描和负载均衡。外网区域负责CA网关检查、身份认证、安全审计和病毒防护。内网系统主要是各业务系统的处理端。同时内部的员工也是通过企业内网访问内部的管理系统,完成对用户业务的受理、审批、核准等操作。

系统架构(SA)或者应用架构(AA):架构师站在全局的角度,给用户绘制一张总体架构图,包括逻辑架构、数据架构、开发架构、运行架构和物理架构。

第二部分 分布式架构设计与实践

第七章 分布式架构设计

1、1000万以内的流量的软件架构设计:

客户端+CDN节点+Nginx反向代理+本地缓存应用集群+数据库;

2、1000万以上的流量的软件架构设计:

客户端+CDN节点+Nginx反向代理+本地缓存应用集群+数据库集群RAC+配合微服务进行数据库的纵向切分加如hash求余的横向切分);

3、5000万以上的流量的软件架构设计:

客户端+应用服务其+内存数据库+数据库;

4、10000万以上的流量的软件架构设计:

服务网关+业务层+服务层+数据层

其中服务网关要考虑负载均衡、身份鉴权、限流措施和安全防护;

业务层需要考虑动静分离、异步化设计和熔断机制;

服务层需要考虑横向扩容、故障转移、服务降级、数据缓存;

数据层需要考虑读写分离、数据拆库、分布式数据库、大数据转型技术。

GemFire:一种比Redis更强大的分布式内存数据库,被12306网站所采用,提供了一整套的数据持久化方案,可以将GemFire数据库中的数据同步到传统的关系型数据库、Hadoop大数据平台等存储设备,唯一的缺点是其为商用软件而非开源开源框架,且价格不菲。

第八章 微服务架构设计

什么是微服务架构:

1、是一种架构风格和设计模式;

2、提倡将大的应用分割成一系列的小的服务;

3、每个服务专注于各自单一的业务功能;

4、每个服务运行于独立的进程中,有清晰的服务边界;

5、采用轻量级的通信机制(HTTP/REST)来实现互通、协作。

一个典型的在线商城的微服务架构的数据库设计为:

对于商品微服务和客户微服务,这两类的微服务典型的特征是数据量小且需要反复读取,因此采用一个小型的Mysql数据库,平且在前面设计一个Redis缓存;

对于交易微服务,其特点是高并发和大数据写入,一个数据库肯定不能满足他的数据要求,因此采用分布式的NewSQL数据库(如TiDB),这样既可以使用分布式来分散用户的压力,又可以利用NewSQL数据库保障数据的一致性。

对于经营分析和业务查询微服务,其特定是对海量数据的数据分析和秒级查询,首先要通过读写分离,将数据从生产库抽到NoSQL数据库或者大数据平台组成的查询库中,然后通过OLAP建模(如Kylin),或者建立分布式索引(如ElasticSearch),就能很好的满足这类微服务的数据需求。

第九章 基于云端的分布式部署

DevOPS运维平台架构:各个开发团队彼此独立地开发各自的微服务,并上传到各自的Git服务器,接着,持续集成工具Jenkins每天自动从各Git服务器中下载代码,将其打包并制作成Docker镜像,发布到镜像仓库中。然后,在Kubernetes中定义每个微服务的节点个数,并将其自动化部署到云端服务平台中。

Docker和Kubernetes的关系:二者是共生关系,不是k8s要替代docker,K8s是构建与Docker之上的分布式管理工具,让Docker能够更好地完成分布式部署,促进docker的发展,因此他们是互相促进的关系。

你可能感兴趣的:(架构,数据结构,软件需求,软件工程,微服务,软件构建)