论软件体系结构的演化
摘要
2022年3月,我加入了公司的新智慧公交平台项目研发团队,并担任系统架构师角色,负责系统整体架构的设计与评审。该项目采用了物联网三层架构模型,其中设备接入层和网络交互层基于公司的中台战略,我们有效复用了公司中台的S17设备交互平台组件。在公交平台的应用层,我们采纳了领域驱动设计(DDD)的理念,确保了每个模块代码职责的明确性,提升了整体架构的可复用性,为项目的持续演进和维护奠定了坚实基础。至2022年12月,项目顺利上线并稳定运行,凭借其卓越性能和高度可扩展的架构,赢得了广泛赞誉。如今,项目已稳定运行近两年,期间为了适应新需求和新技术,新智慧公交平台架构经历了不断演化的过程,目前已达到稳定成熟的状态。
正文
在“互联网+”时代的大背景下,传统的公共交通行业因其业务复杂性较高和技术发展相对滞后,面临着转型升级的挑战。为了帮助公交行业适应新时代的变革,提升用户的公共交通体验,我们推出了新一代智慧公交平台。该平台以物联网技术为核心,互联网为接入门户,整合了小程序、云原生、大数据分析等前沿技术手段。2022年3月,我有幸参与公司新智慧公交平台项目的研发,担任系统架构师,负责整体架构的设计与评审。项目预计总投资3000万元,预计开发周期为9个月。我们旨在构建一个支持多元化生态的公交行业应用平台,利用新技术推动传统公交行业走向城市信息化的发展之路。
在参与智慧公交平台架构设计的过程中,我们面临了人员流失等挑战,导致公司缺少具备公交行业全局视野的领域专家。鉴于此,我们的架构设计主要参照了现有平台的架构框架。由于缺乏对公交业务新需求的深入设计和建模,我们在设计过程中不得不对架构进行了多次的演化过程,以确保其能够适应不断变化的需求。在架构的演化过程中,我们确立了一系列关键的架构演化原则,其中包括:
- 主体维持原则:软件演化的增量增长应保持稳定,确保软件系统的主要功能和行为的稳定性。
- 平滑演化原则:在整个软件生命周期中,保持软件演化的速率稳定,避免剧烈变动。
- 模块独立演化原则:软件的各个模块应能够独立演化,模块内的修改不应影响整体架构的稳定性。
- 适应新技术原则:软件架构应独立于特定技术,具备良好的可扩展性,实现技术与业务的分离,确保引入新技术不会对整体业务流程造成不利影响。
这些原则指导我们在架构设计和演化过程中,保持系统的灵活性和稳定性,以适应不断变化的市场和技术环境。
在新的系统架构设计中,我们优先考虑保持原有系统的架构设计,以确保公交平台整体架构的稳定性。通过运用再工程技术,我们对老系统的架构设计、关键流程、接口设计等方面进行了详尽梳理。采用面向对象的分析和开发方法,我们利用UML图将这些信息整理成软件体系结构规格说明书、需求概要说明书、设备交互协议解析参考文档等,为后续的设计与开发工作奠定了坚实的基础。在此基础上,我们通过架构和接口的复用策略,在新系统的架构和需求设计中大量借鉴了老系统的设计理念和元素,确保了新系统与老系统在设计上的高度一致性。遵循主体维持老系统架构的演化原则,我们有效减少了新系统上线后可能出现的兼容性问题,如外部接口不匹配、数据迁移困难等,从而保障了系统的平稳过渡和持续运行。
为了实现新系统架构的平稳演进,我们采取了持续的版本迭代策略。我们主要使用Git作为版本控制工具,并实施了大版本用于新增需求,小版本用于需求修改和错误修复的方针。结合敏捷开发理念,我们以较短的开发周期来满足用户和产品经理关注的需求点。每次版本更新时,我们控制新增需求不超过20项,以减少架构变动,遵循平滑演化的原则。通过精确的版本控制手段,我们有效管理了每次升级可能引发的运维问题。即便遇到意外错误,我们也能通过版本回滚迅速将生产环境恢复至前一稳定状态,从而提升了系统的容错能力。由于每次架构变动较小,用户能够轻松掌握系统升级的具体内容,这增强了系统的易用性。得益于这种平滑演化的策略,我们的系统始终保持稳定运行,赢得了用户的高度满意。
在整体架构设计上,我们采纳了模块化的开发理念,并结合了DDD(领域驱动设计)模型。具体来看,我们的架构分为以下几个核心模块:
- Adapter模块:负责封装接口,以满足前端交互需求。
- Service模块:承担数据组装和领域模型的调用,实现具体的业务逻辑。
- Domain模块:封装了领域模型,并通过数据交互层获取所需数据支持。
- Client模块:提供外部调用的API接口,以便其他服务与之交互。
- Wrapper模块:负责封装调用其他模块API接口的逻辑。
这种架构设计有效地解耦了各个模块间的依赖关系,实现了业务逻辑与技术的分离。因此,在后续的项目维护中,我们可以遵循模块独立的演化原则,根据需要单独更新或优化各个模块。得益于这种解耦设计,我们的系统架构具备了更好的灵活性,能够轻松适应新技术的融入,为未来的技术升级和功能扩展打下了坚实的基础。
自2022年12月项目正式上线以来,系统运行稳定,这得益于我们对版本控制的严格实施,以及在架构设计中贯彻模块化理念和DDD(领域驱动设计)模型。在整个架构演化过程中,我们始终遵循架构演化原则,确保了项目的优异性能和高可扩展性,赢得了广泛赞誉。如今,项目已顺利运行近两年。在这期间,为了适应新的业务需求和技术挑战,平台架构经历了持续的优化和演化,目前已达到成熟稳定的状态。通过参与此次架构设计和开发,我深刻理解了遵循架构演化原则的重要性,并在实践中深入掌握了架构演化的18个原则。这次宝贵的经验为我的未来工作奠定了坚实的基础。
相关文章:
论软件体系结构的演化
摘要 2022年3月,我加入了公司的新智慧公交平台项目研发团队,并担任系统架构师角色,负责系统整体架构的设计与评审。该项目采用了物联网三层架构模型,其中设备接入层和网络交互层基于公司的中台战略,我们有效复…...
【go入门】常量
目录 定义枚举iota思考题 定义 go语言常量的定义和其他语言类似,常量中的数据类型只能是布尔型,数字型(整型、浮点型、复数)和字符串型 常量的定义方式和变量一样,只不过变量定义使用 var 关键字,而常量定…...
2.1 HuggingFists系统架构(二)
部署架构 上图为HuggingFists的部署架构。从架构图可知,HuggingFists主要分为服务器(Server)、计算节点(Node)以及数据库(Storage)三部分。这三部分可以分别部署在不同的机器上,以满足系统的性能需求。为部署方便,HuggingFists社区版将这三部…...
工具类:JWT
工具类:JWT 依赖JwtUtil.java 依赖 <!-- 创建、解析 和 验证JSON Web Tokens (JWT)--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependenc…...
王道-计网
2 采用滑动窗口机制对两个相邻结点A(发送方)和B(接收方)的通信过程进行流量控制。假定帧的序号长度为3比特,发送窗口与接收窗口的大小均为7,当A发送了编号为0、1、2、3这4个帧后,而B接收了这4个帧,但仅应答了0、1两个帧,A继续发送4、5两个帧,且这两个帧已进入B的接收…...
【机器学习(十)】时间序列案例之月销量预测分析—Holt-Winters算法—Sentosa_DSML社区版
文章目录 一、Holt-Winters算法原理(一) 加法模型(二) 乘法模型(三) 阻尼趋势 二、Holt Winters算法优缺点优点缺点 三、Python代码和Sentosa_DSML社区版算法实现对比(一) 数据读入和统计分析(二) 数据预处理(三) 模型训练和模型评估(四) 模型可视化 四、总结 一、Holt-Winters…...
Webpack优化问题
目录 打包流程swcthread-loaderhash升级插件 打包流程 webpack 的打包流程大致可以分为以下几个步骤: 初始化:webpack 通过配置文件和 Shell 参数,初始化参数,确定入口文件、输出路径、加 载器、插件等信息。接下来读取配置文件…...
yjs10——pandas的基础操作
1.pandas读入文件——pd.read_cvs() data pd.read_csv("E:/机器学习/data/salary.csv") 注意:1.是pd.read_cvs,不要顺手写成np.read_cvs 2.路径的斜杠方向是/,不是\,如果直接从电脑粘贴路径,路径写法是\&am…...
Squaretest单元测试辅助工具使用
1、idea安装插件 Squaretest 然后关掉idea 2、安装字节码软件(jclasslib) 3、找到idea里面的Squaretest安装目录 找到包含TestStarter的jar包 4、打开 com.squaretest.c.f 打开后选择常量池 5、找到第16个修改 Long value值,修改的数字即为使…...
MFU简介
1、缩写 MFU - Mask Field Utilization(光刻掩膜版有效利用比例) GDPW - Gross Die Per Wafer,每张wafer上die的数量 2、什么是MASK 在光刻机中,光源(紫外光、极紫外光)透过mask曝光在晶圆上形成图…...
十分钟实现内网连接,配置frp
十分钟实现内网连接,配置frp 一.frp是什么?其实是一款实现外网连接内网的一个工具,个人理解,说白了就像是teamviwer一样,外网能访问内网。 利用处于内网或防火墙后的机器,对外网环境提供 http 或 https 服…...
解决MySQL命令行中出现乱码问题
在MySQL命令行中遇到乱码问题通常是由于字符编码设置不正确导致的。以下是一些解决步骤: 1. **检查和设置字符集**: 首先,您需要确保MySQL服务器、客户端和数据库使用的是正确的字符集。您可以通过执行以下命令来查看当前的字符集设置&…...
TS系列(7):知识点汇总
你好,我是沐爸,欢迎点赞、收藏、评论和关注。 一、TS是什么? TypeScript 由微软开发,是基于 JavaScript 的一个扩展语言。TypeScript 包含 JavaScript 的所有内容,是 JavaScript 的超集。TypeScript 增加了静态类型检…...
Unity 查看Inspectors组件时严重掉帧
遇到一个问题,就是运行一个脚本的时候,只要我查看它的Inspectors,就会严重掉帧。 原本是30fps,只要查看这个组件,就掉到5fps。 这还真有点像波粒二象性,一观察就会掉帧,不观察就正常。 using…...
golang学习笔记23-面向对象(五):多态与断言【重要】
本节也是GO核心部分,很重要。 注:由于导包语句已经在19讲(笔记19:面向对象的引入)展示过了,所以这里就不展示了。 一、多态(Polymorphism) 变量(实例)具有多…...
RabbitMQ基础知识
1.1 什么是MQ? 消息队列(Message Queue),是基础数据结构中 “先进先出” 的一种数据结构。 一般用来解决应用解耦、异步消息、流量削峰等问题,实现高性能、高可用、可伸缩和最终一致性架构。 RabbitMQ可以理解为一个邮箱&#x…...
基于Python大数据的音乐推荐及数据分析可视化系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏:Java精选实战项目…...
安达发|太阳能设备行业APS计划排程软件能解决哪些问题
在当今快速发展的太阳能设备行业中,高级计划与排程(APS)软件成为了企业优化生产流程、提高生产效率和满足市场需求的关键工具。APS软件通过集成先进的算法和数据分析技术,为企业提供了一个全面的生产计划和排程解决方案。本文将探…...
CaChe的基本原理
目录 一、Cache的定义与结构 二、Cache的工作原理 三、Cache的映射与替换策略 四、Cache的写操作处理 Cache,即高速缓冲存储器,是计算机系统中位于CPU与主存之间的一种高速存储设备。它的主要作用是提高CPU对存储器的访问速度,从而优化系…...
数据结构-栈(理解版)
一、栈的定义 相信大家对于栈或多或少有一些了解,可能大多数人会告诉你栈是一种先进后出的数据结构。这其实说了跟没说一样(❁◡❁)!当然(last in,first out)是栈最有特色的性质。 这里可以给大家一些比较好理解的例…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
