Skip to content

一文说清楚双驱动实现软件架构

About 3654 wordsAbout 12 min

架构新书

2026-05-26

​ 软件架构包含了架构风格和质量属性两个部分。也是这俩部分驱动软件架构实现。缺一不可。

​ 架构风格是软件系统架构的抽象,反映了系统所共用的结构和语义特性,并指导如何将各个构件有效地组织成一个完整的系统。特定的软件架构风格本身也包含了能达成的的若干质量属性

​ 质量属性则是系统的非功能性要求,如性能,可用性,安全性等等,质量属性往往决定了软件的架构。

​ 当提到软件架构风格时候,有一个更早期的术语是软件架构模式。俩者共同点都是可以重复指导,如何在一定约束条件下构建一个系统并满足若干质量属性。细微的区别在随着如今对系统的可用性,高性能,可修改性,扩展性等高要求,特定的软件架构风格相比于架构模式,能满足更多质量属性要求。比如提到微服务架构风格,这种架构风格将应用拆分成更细粒度的服务并能单独部署,这些服务拥有自己的技术栈和数据库。这种风格满足了诸多质量属性,如可伸缩性,高可用,高性能,可修改性,故障恢复,以及具备团队解耦,技术解耦等优势。微服务架构风格,需要一组架构模式实现,比如微服务常用代理架构模式,事件驱动架构模式。再比如物联网行业,早有固定的架构风格用来构建系统连接设备和用户,这种网联网架构风格会综合使用分层,代理,流水线,事件驱动等模式实现。

大部分文献认为架构风格相比架构模式,是一种层次更高的系统构建方法,并主要面向系统设计人员和客户的术语。我认为架构风格是一种相对于从单体系统发展起来的架构模式,满足更多架构质量属性的,并从高层次指导如何构建一个系统的解决方案。我认为过于区分架构风格和架构模式没有意义。

因此,本书不区分架构风格和架构模式。

如下是常见软件架构风格

架构风格描述单体分布式出现时间线
无风格架构又成混沌架构,指随意架构,庞大的,草率的,布满了胶带和线路原始
代理此模式用于构造具有解耦组件的分布式系统。这些组件可以通过远程服务调用彼此交互。代理组件负责组件之间的通信协调。古代
分层将系统分为多层,每层完成部分系统功能,并传递到下一层完成剩下的功能。每个层只关注划分到自己层的功能古代
流水线将数据流的处理的每个步骤分装在过滤器里,数据通过相邻管道传输。
微内核统分解为 核心组件和插件。核心组件提供系统基本功能,具备管理插件功能,通过插件来增强和扩展系统功能
事件驱动事件驱动架构风格是一种分布式异步架构风格,经常被用与构建高可伸缩性的应用程序。这种架构风格由一系列高度解耦的、异步接收和处理事件的单一职责的组件所组成
面向服务按照 应用架构拆分系统为多个服务,服务之间的接口,调用方式遵循规范,比如基于WSDL描述服务调用方式,使用SOAP协议调用.最近30年
微服务把应用架构拆分系统为多个细粒度服务,这些服务拥有自己的技术栈,数据库。最近10年
无服务函数即服务,自动扩容,不需要部署和运维。最近10年
云原生在微服务或者无服务基础上,增加了基础设施运维,CI/CD等内容最近10年

​ 有架构师按照架构风格出现的年代,使用术语“第X代架构”来描述架构风格,如微服务架构风格为第三代架构,云原生为第四代架构,作者认为,在架构风格上,并没有所谓后一代比前一代更先进这么一说,只有适合系统的当前架构风格。比如单体系统在小规模用户时候比微服务更适合,无风格架构适合系统早期原型或者功能单一的服务。第二代面向服务架构比第三代微服务架构更适合传统企业系统整体架构(即系统之间面向服务,系统内部采用微服务,参考第二章面向服务架构)。 相比于把架构按照出现年代分为X代架构,使用架构风格能中性的描述软件架构。

架构风格将在第二章详细描述

​ 在1.3的应用架构中,提供了一个高层次的物联网应用架构。其中包含了网关应用,其负责接收设备消息,然后转发到通道或者其他业务系统。在不考虑质量约束的情况下,其网关的软件架构如下,一个简单的分层架构

自下而上,每个组件的含义

分层含义
设备设备通过MQTT或者二进制协议,连接物联网,并上报属性,告警等。
Netty传输层使用Netty作为传输层组件,用于维持网络链接,协议编解码,白名单等功能。当有连接创建,此层负责验证证书。
业务处理层将设备上报的的MQTT,二进制LV报文解码后,封装成Message,根据不同的Message类型,使用不同的Task类来处理。
其他业务系统Task根据业务需要,会使用dubbo协议调用外部系统,如属性上报,会调用影子系统存储设备最近一次的属性

这个物联网的架构能完成设备接入物联网需求,但还未满足诸多质量特性,在稍后介绍完质量特性后,这个系统将逐渐完善。

软件架构不仅仅完成业务功能,还需要实现系统的质量要求,如性能,可用性,安全性,性能,可观测性等。面向质量属性的架构已经成为驱动软件系统建设的主要因素,也是本书的内容。架构师和程序员长期围绕质量属性调整架构, 比如:

  • 建设一个高性能系统,不会出现服务暂停现象(STW),架构师可能需要选择配置现代垃圾回收器的高版本的Java且配置或者使用RUST语言
  • 建设一个分钟级千万的电商系统,架构师需要使用微服务架构而不是单体系统。目标存储系统使用分库分表,或者增加Redis二级缓存
  • 建设一个高可用系统,不会因为系统维护而停机。架构师可能要综合使用代理架构,容器化,以及热部署技术等实现
  • 建设一个系统可以部署到目标客户的任意平台上,架构师选择Java开发系统,且使用支持多库的数据库访问工具

常见的系统的质量属性如下表

属性名称描述本书覆盖
性能系统的响应时间.,常见衡量性能的指标TP95 ,TP99 和 吞吐量。本书涉及单机,分布式性能优化的战术实现
可用性是系统能够正常运行的时间比例。可用性999,即99.9% ,一年出故障时间为8.76小时。本书涉及到高可用的战术实现。
可伸缩性随着用户,请求量增长,系统能扩容适应流量增加。微服务架构,云原生,无服务架构均能支持可伸缩性。事件驱动架构风格也支持订阅端的可伸缩性。
可观测性类似机械传感器,可观测性是收集关于程序执行、模块内部状态及组件间通信的数据的能力。为了提高可观测性,可以使用各种测试跟踪技术和工具。可观测性不同于传统监控,前者属于微观,后者属于宏观
故障恢复指系统自身或者依赖的系统出现故障的情况下,系统能快速恢复。比如主库宕机下可以切换到从库
安全性是指系统拒绝非法用户使用,无安全漏洞 . 用户操作可审计。限于篇幅,本书不会介绍安全。
跨平台指系统可以在不同平台运行,比如不同的操作系统或者云服务,或者前端页面可以使用不同的浏览器。本书不会介绍
可修改指系统容易修改且容易部署。比如使用微内核架构,事件驱动架构都能让模块容易修改。使用脚本完成经常调整的业务逻辑以避免编写代码和部署系统
可扩展性系统易于扩展新的功能,比如接入网关可以扩展接入不同的设备协议,支持不同的证书。微内核架构,事件驱动架构有良好的可扩展性。
灵活性指系统的特性易于修改,尤其被非程序员修改,通过配置文件,配置业务规则,或者轻量级脚本实现
国际化和本地化系统可以国际化部署,根据不同的使用者具备本地化的功能,如日期,钱币的计算和现实
可测试性系统在开发,部署都是易于测试的。比如通过Junit+Mock+Cucumber来实现微服务单体测试,测试人员通过JMeter脚本验收测试。运维人员可能还会录制生产系统的流量用于验收系统的测试
易用性用户能容易得掌握系统功能,用户使用出错的情况下能给出明确的指示。比如Web系统的基础协议是HTTP,它就是一个非常易用的协议,它构建出Web系统的易用性。本书不涉及这部分内容,但会在REST API 规范里涉及此内容

质量属性驱动软件架构,将在第三章详细描述

接着上图的物联网网关架构,提出如下问题:

  • 当证书文件需要更换的时候,是否不需要重启系统,以提高系统的可用性,灵活性
  • 如果网关下游系统出现故障导致调用延时,如何避免影响网关的性能或者可用性。
  • 设备的上下线业务是最为重要的业务,即使其他业务繁忙,也需要保证设备上下线功能正常
  • 系统是否灵活,当新增业务的时候,是否可以不用开发和重新部署系统,以增强可用性和可修改性
  • 协议处理是否灵活,当协议增减内容时候,是否不需要频繁修改编解码和部署系统。

每个问题都涉及到网关系统的质量属性,需要调整其架构,如下是针对上述问题的一个新的架构图。总体上改成事件驱动架构风格,其内部也采用了此架构模式。架构还综合应用了许多质量特性实现战术。黄色部分为调整内容

改进描述提高
Kafka对外调用一律采用发送到Kafka。实现与其他系统解耦,以及调用量削峰功能。即使其他业务故障,也不会对网关系统造成影响可用性,可靠性,高性能
增加多个线程池上线状态和命令下行使用单独线程池,如果线程池满,则进入延迟重发线程池。其他类型对应的线程池采用丢弃策略,如属性上报如果线程次满,则直接丢弃可用性,高性能
限流Netty 增加设备接入限流以及设备报文限流,此限流阈值配置在apollo中并能实时修改生效可用性,可靠性
证书管理网关不再重本地加载证书而是通过证书管理组件完成证书的加载和更新。证书统一存放在证书服务器上可用性,灵活性
编解码自动化工具对于二进制协议,可以配置其规范,并自动解析为JSON或者Java对象,不需要手工编码和部署。可用性,可修改性,灵活性
热部署Bean容器对于Task的修改可以自动部署生效而不需要重启网关,新增的Task也可以通过此部署可修改性,可用性
脚本引擎允许Task以脚本方式执行,以快速实现业务功能。比如,对于新的协议,可以在协议配置库配置解析规范,并使用JS来执行解析后的JSON内容可修改性,灵活性
Tracer使用可观测性客户端组件,记录设备链接,设备上报等业务信息,也记录线程池使用,任务处理时长等运行信息。可观测性

对于系统属性质量要求,通常都有具体的战术方法,比如,你想系统调整而不需要重启,通常就有配置、脚本,Classloader、换DceVM JVM等技术。本书的重点将是使用适当的战术,技术框架来实现系统的质量属性要求。

作为软件架构师,切记平时工作一定要养成架构风格和质量属性双驱动的习惯。

知行合一