论软件体系结构的演化
摘要
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)是栈最有特色的性质。 这里可以给大家一些比较好理解的例…...
NAND Flash虚拟层初始化
在整个NAND Flash初始化过程中,其主要过程由NAND_Init()函数来完成的,因此以下以NAND_Init()函数作为入口,对NAND Flash虚拟层初始化进行全面分析: NAND_Init()NAND_PhyInit()FMT_Init()FMT_FormatNand()LML_Init() NAND_Init()函数首先调用NAND_PhyInit()函数…...
zabbix7.0监控linux主机案例详解
前言 服务端配置 链接: rocky9.2部署zabbix服务端的详细过程 环境 主机ip应用zabbix-server192.168.10.11zabbix本体zabbix-client192.168.10.12zabbix-agent zabbix-server(服务端已配置) 具体实现过程 zabbix-client配置 安装zabbix-agent 添加扩展包 dnf -y instal…...
2024重生之回溯数据结构与算法系列学习(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
欢迎各位彦祖与热巴畅游本人专栏与博客 你的三连是我最大的动力 以下图片仅代表专栏特色 专栏跑道一 ➡️ MYSQL REDIS Advance operation 专栏跑道二➡️ 24 Network Security -LJS 专栏跑道三 ➡️HCIP;H3C-SE;CCIP——LJS[华为、华三、思科高级网络]…...
django drf 过滤器
排序 代码: from rest_framework.generics import ListAPIView from rest_framework.filters import OrderingFilterclass TestListAPIView(ListAPIView):queryset models.Course.objects.filter(is_deleteFalse).all()serializer_class serializers.TestModelS…...
蓝桥杯—STM32G431RBT6(RTC时钟获取时间和日期)
一、RTC是什么,有什么用? 在 STM32 中,RTC(Real-Time Clock,实时时钟)主要有以下作用: 时间保持:即使在系统断电情况下,也能持续记录时间。(需要纽扣电池供电…...
DriveVLM 论文学习
论文链接:https://arxiv.org/abs/2402.12289 解决了什么问题? 自动驾驶对交通行业有着革命性的作用,实现 FSD 的一个主要障碍就是场景理解。场景理解涉及在复杂且不可预测的环境中进行导航,这些环境可能包括恶劣的天气条件、复杂…...
Unity3D 客户端多开
Unity3D 实现客户端多开 客户端多开 最近在做好友聊天系统,为了方便测试,需要再开一个客户端。 简单的方法,就是直接拷贝一个新的项目,但是需要很多时间和占用空间。 查阅了网络资料,发现有一种软链接,…...
使用代理IP数据采集都需要注意那些?
“在当今大数据时代,数据采集成为了企业决策和个人研究的重要依据。然而频繁访问目标网站往往会引发IP被封锁的风险,这时使用代理IP就显得尤为重要。但代理IP的使用并非毫无风险,以下是使用代理IP进行数据采集时需要注意的几个关键事项。” 一…...
城市大脑:智慧城市的神经中枢——典型实践与经验启示
随着信息技术的飞速发展,智慧城市已成为全球城市转型升级的重要方向。“城市大脑”作为智慧城市的核心引擎,正以其强大的数据处理能力、智能决策支持和跨领域协同优势,引领着城市管理与服务的深刻变革。本文将深入探讨几个具有代表性的“城市…...
嵌入式中CW32多功能测试笔实现
前言 起心动念 在日常的硬件调试工作中,我们最常使用的仪器仪表可能就是万用表了,虽然万用表号称“万用”,但大部分时候,我们需要使用到的功能无非是电压测量和通断测量。 作为调试的“得力干将”,万用表有时候也会存在存在一些缺点和局限性,比如:体积较大不便于携带…...
备案域名买卖/竞价关键词优化软件
HTTP Servlet继承了GencenServlet类 GencenServlet实现了两个接口一个用于ServletConfig设置接口,一个为Servlet接口只要是(1) init() 方法 控制Servlet的生命周期重点记忆8个方法HTTP Servlet 使用一个 HTML 表格来发送和接收数据。要创建一个 HTTP Servlet&…...
abc网站建设/seo工作流程图
CVE漏洞爬虫java代码依赖-TestNGTestNG是Java中的一个测试框架,而该CVE漏洞爬虫示例中所涉及到的java代码中, \Crawler\src\com\***\ThreaderRun.java文件在导入import org.t ...Android+clipse导入工程提示:invalid project description今天遇到一个奇怪的…...
wordpress 自动上传插件/郑州搜狗关键词优化顾问
我有一个PHP REST API,可以托管Amazon S3中的所有图像.我正在寻找一个插件或技巧,使用GET参数来调整图像大小.例如:http://my-bucket.s3.amazon.com/image.jpg?width300&height300我找到了this plugin,但我的团队成员说它是基于ASP.NET的,不适合我的PHP API项目…...
网站建设优化服务案例/大数据培训班需要多少钱
IISphp环境搭配一、以PHP6为标准 因为PHP5 PHP4 有文件夹的差异,为了标准化的学习,本着我为人人,人人为我的精神,特此把自己的实践经验SHOW一下。1.下载php6-win32压缩包,解压之后重新命名为php放至D:\ 。2.进去D:\php…...
服务器建设网站/链接交换平台
需求:动态修改二维码以及标题头像等内容 1.海报(海报标题超过两行省略,副标题超过三行省略,头像圆角) 海报效果如下: 具体代码如下: <template><view class"page"><…...
短网址压缩/重庆seo排名优化
ClassJava 程序汇总的各个 Java 类属于同一类事物,描述这类事物的 Java 类名就是 Class。Class 表示在内存中存储的字节码。(1)获取字节码的三种方式:1 、类名.class。 例如:System.class;2 、对象.getClass()。例如:new Date().g…...