架构分解之道_分布式系统架构的博客-程序员秘密

这篇文章将从架构分解的作用、分解的原则、分解的维度、分解的战术逐步给大家介绍架构分解之道。

640?wx_fmt=jpeg

开篇

开篇我们先讲两个成语:『好高骛远』和『高瞻远瞩』,如果一个人做一些不切实际的事情,我们称之为好高骛远;如果一个人有眼界视野,我们称之为高瞻远瞩。

同样是高、远,为何描述着两种完全不同的人?因为前者的好、骛讲的都是追求,而后者的瞻、瞩,指的却是具体的行动。当我们把高远的目标只作为一种追求,而不付诸于实践的时候,就是不切实际;当我们把它变成“时时顾看”这样的行动时,我们就渐渐地变得有眼界视野了。

所以志存高远并没有错,只是要切忌不务实。“着眼于高远”这就是作为一个架构师所需的基本修养,而所有的架构设计思维都是从这修养中汲取而来。

概述

所有的系统开发方法都要解决从需求到实践的转换问题,为了提高系统的质量,前人提出了需求分析工程和各种建模技术,但是在需求和设计之间还是很难逾越,也就是说缺乏能够反映做决策的中间过程,于是系统架构设计应运而生。

对于架构设计人们已经提出了许多方法,分类为:工件驱动的方法;用例驱动的法;模式驱动的方法;领域驱动的方法。一个经典的架构设计过程模型,沿用了RUP中迭代增量的思想,由分析、描述、选择、构造和组合5个阶段组成,如图:

640?wx_fmt=png

(有兴趣的可以学习一下架构设计的元模型来设计属于自己领域或者产品线的设计过程模型,其实下面的模型也是元模型的实例化)

依据需求规格说明书分析出功能需求和架构需求,通过用例和场景的描述,把需求分为关键的,次要的和可选的3类。关键需求决定架构,结合软件架构风格和通用知识选择最关键、影响最大的子系统分析设计并产生构件。

组合就是定义构件接口,构件作为一个封闭的功能实体,对外提供交互接口,并通过连接件将构件连接起来形成最终的软件架构描述。5个阶段是不断迭代的过程,在每一次迭代中,都选取并实现一组用例和场景来确认并完善架构。

这个过程模型看似很流畅,但是,架构师在设计时很难把握他的正确性和精准性,而且用它架构的系统是否对后续设计开发形成一种原则上的指导是很难说的。

但是对于架构师来说有些思路可以进行参考,大致将架构思维可以分为:分解、集成、分离、复用、分层、模式、抽象、结构化、迭代、勿做过度设计这几部分,按照这个思维方式来设计系统架构。

架构设计思维 - 分解

640?wx_fmt=jpeg

分而治之是一种处理复杂问题的通用方法,在系统架构中也是一种很重要的手段,例如多层架构、OSI 七层模型都体现了分而治之思想。

在架构设计过程中,通过将关注点分离对架构进行多层次分解,将系统层层分解为多个架构元素,进而识别架构元素。同时保证分解后的各个部分还能够高内聚,松耦合,最终又集成为一个完整的整体。分解核心是定义问题,因此架构首先仍然需要理解清楚需求。

分解的作用

架构分解是架构师接到需求到完成架构设计中最关键的一步,分解可以帮助架构师了解需求中未呈现出来的隐性需求要素,分解也是架构师解决非功能层面需求的重要手段,架构要解决高性能、高可用、伸缩性、可扩展性等问题,针对这些问题,我们一般从几个方面进行入手:

  • 应用层

按照功能或者微服务进行分解,将系统划分未若干子系统,低耦合存在,在业务角度可以将单个应用独立为应用单元(应用单元是无状态的),这样可以灵活地进行伸缩。

  • 数据层

对数据库进行垂直拆分按照子系统维度进行分库和水平拆分按照业务维度进行分表;但是进行分库分表中要避免分布式事务,实在无法避免可利用消息系统来进行规避。

  • 代码结构层

代码层一般分为三层,从下至上分别为:数据访问层、业务逻辑层(又或称为领域层)、表示层。这也是Java Web中重要的三层架构中的三个层次。区分层次的目的即为了“高内聚低耦合”的思想。

分解的原则

  业务原则

  • 单一责任原则

对于一个微服务而言,具有有限的业务范围,可以帮助我们满足服务开发和交付的敏捷性;

  • 适当的边界

关注微服务的功能范围,一个服务的大小应该等于满足某个特定业务能力所需要的大小;

  • 业务分层

从整体规划上把业务分层,形成单向依赖,避免微服务之间的网状依赖关系;

  • 颗粒度递增

设计初期先把业务划分到尽可能细,然后依据其它原则合并到适当颗粒度;

  • 非唯一依赖

至少被2个以上其它微服务依赖的功能模块,才有必要独立成一个微服务。

   技术原则

  • 部署独立性,能独立于其它微服务部署,一个微服务故障不影响其它微服务;

  • 动态扩展,每个微服务都可以动态的进行x轴和z轴的扩展,并适应云环境下的自动化部署;

  • 领域和应用解耦,提供数据操作能力的领域服务和执行业务逻辑的应用服务解耦;

  • 避免产生频繁的跨库查询;

  • 避免产生频繁的分布式事务。

  治理原则

  • 在业务分层的基础上,根据业务细分规则,对微服务分组;

  • 各个分组之间通过API网关集成;

  • 通过API网关实现级轻量级消息路由,鉴权;

  • 运行时管理,如服务降级,限流,监控等可在API网关实现,让微服务功能纯粹;

  • 避免通过数据库集成;

  • 避免部署多个版本来兼容。

640?wx_fmt=jpeg 电商架构设计模型

分解的过程

面对一个系统,特别是前人没有做过的新系统,通常难以一下子设计出合适的架构。在架构设计的初期,通常都要经历一个不断探索的阶段。在架构设计过程中,架构分解是必不可少的的关键步骤。如何进行架构分解?从哪里入手开始进行分解?我们需要有一个架构分解的过程模型来指导分解过程,启发和探索架构分解的维度和线索,提高架构分解的效率。

架构分解过程如下图所示,是一个迭代的模型。通过这个迭代的分解,从无到有、从粗到细、从模糊到清晰,一步步精(细)化、丰富架构。迭代的过程也是一个否定之否定的过程,随着分解的逐步推进或系统的架构演化,后面的分解除了会识别出隐性需求,也可能会对先前识别出的架构作出调整。

640?wx_fmt=png

依次从 4 个域中进行架构分解,基本顺序是先业务后技术,通过多维度多层次的分解将关注点分离。

  • 业务需求分解

先从业务需求进行分解,一般业务需求来源有几个方面:

  • 一线业务员

  • 产品优化

  • 公司战略目标

  • 技术要求

首先是从业务需求入手,寻找业务需求中的分解维度,将架构从业务需求层面进行大粒度的分解。在业务域中进行分解,通常采用的分解维度是根据业务主题,将系统分解为多个子系统,每个子系统聚焦于一个独立的业务主题,子系统间具有清晰的边界。

例如对某电商系统,我们可以根据业务需求维度进行架构分解,初步划分出:订单系统、用户中心、购物车系统、搜索系统、广告系统、库存系统、物流系统、商品中心、支付系统等模块。

640?wx_fmt=png

对业务需求分解不应只局限于基于业务需求的分解,根据具体情况,还可能有其他的分解维度。一个通用的发现分解维度的方法是试着从领域模型和需求分析文档中寻找名词和形容词,将文档中的核心概念(名词和形容词)作为分解的候选分解维度或分解线索。

业务需求的分解中,我们要和产品经理密切交流,适当考虑企业战略,这样可在一定程度上保证架构分解的合理性。

  • 业务功能需求分解

通过对业务流程和用例进行分析,根据功能职责,进行垂直和水平分解,识别出业务功能或业务服务,将它们归类到子系统中相应模块中去。

对业务功能需求分解,一个通用的方法是试着通过动词来将子系统拆分为多个服务;另一个是根据资源类型(名词)来将系统拆分为服务,每个服务负责实现对应资源上的一组操作。例如根据资源类型(用户、商品等),对电商系统,可分解识别出用户查询服务和用户管理模块、商品服务等。

  • 技术需求分解

是从技术角度对系统和模块进行分解。在该阶段,通常会选取关键的需求(包括功能需求和非功能性需求)和已分解出的模块或子系统,结合当前的 IT 技术(技术框架、架构模式、参考架构、中间件、业务平台)和架构思想、架构经验、开发人员的技能以及系统的上下文环境等,进一步进行架构分解。

在技术需求分解中,对功能需求,横切(分层)竖割是一种常用的分解手法。对非功能需求,可将性能、伸缩性、可用性等作为维度对系统进行分解,在非功能需求分解战术中将专门说明这些维度的分解技术(称为战术)。

在技术需求的分解中,对公共的技术需求应全盘考虑,抽象出底层的公共技术基础设施,例如定时任务在许多子系统中都存在,此时可能会规划一个定时任务框架和定时任务执行系统。也可能会采用一些成熟的框架和中间件技术,如消息中间件、RPC 等。

技术需求分解通常是比较复杂的,这一方面来源于问题域的本质复杂性,特别是各种非功能性需求的复杂性,需要架构师掌握应对这些需求的常见模式。另一方面也是由于 互联网技术的日新月异,要求架构师对技术敏感,与时俱进。要注意的是,当在技术域分解中碰到困难时,可以再回到业务域中去寻找答案和线索。

  • 架构需求分解

全面考虑各类涉众在架构层面的关键需求,特别是非功能需求,例如性能需求、可伸缩性需求等,进一步对系统进行分解。

架构需求分解包括了前面说的业务需求分解、业务功能需求分解、技术需求分解,通常架构需求分解和它们有部分是重叠的,例如在技术需求和架构需求中都有性能方面的架构分解。架构需求分解保证我们的分解是完备的,没有遗漏。

分解维度

架构分解就是从多个维度多层次对系统进行分解,识别出架构元素,逐步精化、丰富系统架构的过程。从上面可以总结出,维度大致有,业务维度、业务功能维度、技术维度,涉众维度。

根据具体的系统,还可发掘出许多分解维度,如时间维度、物理空间维度、优先级维度、职责角色维度(不同的角色)、客户端维度、调用方维度(不同的调用方)、请求类型维度、数据维度、数据处理维度。维度就看架构师对于需求的理解程度多深刻

分解的战术

640?wx_fmt=png

将在架构层面应对非功能需求特性的架构模式或架构策略称为战术,例如对可用性,常用的战术包括:冗余、错误检测。

分解的粒度

多维度多层次分解到什么粒度才停止?这个没有统一的标准,通常要能进行并行开发,能指导后续的详细设计。需要根据具体的产品或项目来定,有的到模块级别就行,对关键的部分,可以到类级别。

分解的时机

640?wx_fmt=jpeg

架构分解的时机通常就是架构改造演化的时机。当架构出现腐化和臭味,已经难以满足关键涉众的关键需求。

例如用户的响应速度越来越慢已经接近临界值,并且根据预见,响应速度还有可能继续较低;开发人员越来越难以维护,这个时候可以考虑进行架构演化,对架构进行改造。当然如果能提前预见系统的问题,经过慎重评估后,在问题发生之前,提前一段时间进行架构演化也是可以的。

要注意的问题是不要过度分解,过早分解,这样做除了增加成本,还可能带来风险。例如很多系统在建设初期,考虑到规模较小和快速上线,通常都是一个整体的系统,不会进行大的架构分解,以后随着需求和规模的逐渐增加,会逐步进行架构改造和架构分解。

总结

分解作为架构设计中关键的步骤,架构分解没有成熟的方法体系来指导架构师,但是以上的过程和维度可以作为一定的参考来进行架构分解,架构分解的关键点在于分解维度和分解战术,希望能帮助架构师们。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u014714618/article/details/101368903

智能推荐

发布源码及依赖到网络maven仓库_chichou9946的博客-程序员秘密

目的: 通过eclipse工具,使用maven命令,将maven工程编译后的jar、源码、依赖环境,都发布到网络maven仓库; 方便其他工程引用,查看源码,及自动下载依赖环境; maven关键命令 deploy -- 发布到远程仓库 ...

matlab 二进制写入文件,在Matlab中读取/写入二进制文件_花菌子的博客-程序员秘密

如Bill the Lizard所写,您可以使用fread将数据加载到向量中.我只想扩大一点他的答案.阅读数据>> fid=fopen('data.bin','rb') % opens the file for reading>> A = fread(fid, count, 'int16') % reads _count_ elements and stores them ...

iOS开发之点击空白处退出键盘_旭日猎鹰的博客-程序员秘密

###一、以前使用的退出键盘方法UIScrollView 上如果有UITextField的话,结束编辑(退出键盘)直接用touchesBegan方法无效,需要再给UIScrollView加一个分类,重写几个方法。- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [[self nextResponder] touchesBegan:touches withEvent:event]; [super touch

arcmap拓扑错误检查器不亮_ARCGIS拓扑检查步骤与修正拓扑错误技巧_weixin_39537397的博客-程序员秘密

摘自http://www.3snews.net/bbs/viewthread.php?tid=3006 和 http://blog.sina.com.cn/s/blog_4d0d397d0100aasm.html一副人工或自动矢量化后的数据,在正式应用数据之前,应根据要求检查和修正各种拓扑错误!地理数据是庞大和海量的数据,无乱是人为的还是自动的矢量化,都可以出现错误,对于数据量很大的数据来说,检查...

8*8LED点阵横向滚动显示_ambitious_0_0_的博客-程序员秘密

#includesbit ADDR0 = P1^0;sbit ADDR1 = P1^1;sbit ADDR2 = P1^2;sbit ADDR3 = P1^3;sbit ENLED = P1^4;unsigned char code image[30][8] = { {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, //动画帧1{0xFF,0x7F,0xFF,0

oracle 的 import,ORACLE import工具参数_学习中的小包的博客-程序员秘密

import工具windows中文界面:C:\Documents and Settings\yeyj>imp -helpImport: Release 10.2.0.1.0 - Production on星期二12月20 13:11:20 2011Copyright (c) 1982, 2005, Oracle.All rights reserved.通过输入IMP命令和您的用户名/口令,导...

随便推点

WINDOWS环境下CloudCompare2.11.3+VS2019+QT5.15+cmake配置错误解决方案_Echo_Echo_.的博客-程序员秘密

WINDOWS环境下CloudCompare2.11.3+VS2019+QT5.15+cmake配置错误解决方案今天在用cmake编译CloudCompare2.11.3时,出现了一个问题点击configure后一直报如下的错误:解决方案:在CloudCompare2.11.3的安装路径下新建文件夹命名为prefix,然后在cmake编译界面找到CMAKE下的CMAKE_INSTALL_PREFIX。如图所示,将刚刚新建的文件夹路径添加进入再次configure就能.

面试官:说一下公平锁和非公平锁的区别?_程序猿微刊的博客-程序员秘密

前言上次我们提到了乐观锁和悲观锁,那我们知道锁的类型还有很多种,我们今天简单聊一下,公平锁和非公平锁两口子,以及他们在我们代码中的实践。正文开始聊之前,我先大概说一下他们两者的定义,帮大家回顾或者认识一下。公平锁:多个线程按照申请锁的顺序去获得锁,线程会直接进入队列去排队,永远都是队列的第一位才能得到锁。优点:所有的线程都能得到资源,不会饿死在队列中。 缺点:吞吐量会下降很多...

【ESP32】【ESP32-PICO 系列】_iMr_Stone的博客-程序员秘密_esp32 pico

ESP32-PICO-D4ESP32 系统级封装 (SiP),3.3V 4 MB flash,无内置 PSRAM,双核 MCU,Wi-Fi & 蓝牙双模工作电压 3.0 ~ 3.6VLGA48-pin,7x7x0.94 mm–40 °C ~ +85 °C有以下几点需要注意:嵌入式 flash 连接至 VDD_SDIO,由 VDD3P3_RTC 通过约 6 Ω 电阻直接供电。因此,VDD_SDIO 相对 VDD3P3_RTC会有一定电压降IO16、IO17、CMD、CLK、S.

量子计算机的定义,量子信息的基本概念_weixin_39927799的博客-程序员秘密

《量子信息的基本概念》由会员分享,可在线阅读,更多相关《量子信息的基本概念(35页珍藏版)》请在人人文库网上搜索。1、Chapter One Ocean University of China Content: 量子信息简介量子信息简介 1.1 量子隐形传态量子隐形传态 1.5 量子克隆量子克隆 1.4 量子计算量子计算 1.3 量子比特量子比特 1.2 量子算法量子算法 1.6 Ocean Un...

OpenGL扩展的使用_happypretty的博客-程序员秘密

扩展名每个扩展都有一个扩展名,扩展名类似如下形式:GL_ARB_multitexture 第一段GL,用来表示针对OpenGL哪部分开发的扩展,有以下几个值:GL – 针对OpenGL核心的扩展WGL – 针对Windows平台的扩展GLX – 针对Unix / Linux平台的扩展GLU – 针对OpenGL Utility Library的扩展第