0%

题目

论软件架构风格软件体系结构风格是描述某一特定应用领域中系统组织方式的惯用模式。体系结构风格定义一个系统家族,即一个体系结构定义一个词汇表和一组约束。词汇表中包含一些构件和连接件类型,而这组约束指出系统是如何将这些构件和连接件组合起来的。体系结构风格反应了领域中众多系统所共有的结构和语义特性,并指导如何将各个模块和子系统有效地组织成一个完整的系统。
请围绕“论软件架构风格”论题,依次从以下三个方面进行论述。

  1. 概要叙述你参与分析和设计的软件系统开发项目以及你所担任的主要工作。
  2. 软件系统开发中常用的软件架构风格有哪些?详细阐述每种风格的具体含义。
  3. 详细说明你所参与分析和设计的软件系统是采用什么软件架构风格的,并分析采用该架构风格设计的原因。

摘要

近些年,新能源汽车蓬勃发展,2022 年 6 月我司决定开发一个针对新能源汽车一体化平台,其中包括媒体、社区、选车等功能。我担任该项目的技术负责人,负责系统方案定制及技术指导工作。本文描述了该系统的架构分析与设计工作,其中包括三个主要部分,应用系统,该系统采用 B/S 架构,前后端分离的服务端渲染模式,满足了推广、跨平台等需求,降低了开发成本,明确了职责分工。后端服务,该部分采用层次化架构,通过划分不同的层,实现了一种明确职责,耦合性低,方便测试的应用程序。应用通讯,该部分采用 REST 架构风格,一种约定大于配置的架构,有良好的扩展性,降低了学习与开发成本。该系统于 2023 年 10 月上线运行,运行效果良好。

正文

2022 年,新能源汽车开始蓬勃发展,国家发布了相关政策进行引导规划。此时,市面上并没有针对新能源汽车的应用平台,导致用户在搜索车型时,无法快速准确的找到对应的新能源汽车信息。为响应政府号召,满足用户需求,我司决定开发一个针对新能源汽车的一体化平台。

该项目于 2022 年 6 月开始,团队成员共 17 人,我在该项目中担任技术负责人,主要负责系统方案定制及技术指导工作。该项目主要包括媒体、社区、车型库等主要功能模块,其中媒体模块用于新能源汽车的消息发布,包括了图文、视频、简报及最新车型信息等子模块,可以让用户方便的接收新能源汽车消息。社区模块主要为用户提供讨论渠道,其中包括了车型品牌圈子、车型话题讨论、热点新闻、车型打分与评价等功能。车型库模块是其中的核心,在传统汽车平台的基础上,我们增加了许多新能源汽车特有的功能,比如三电系统、辅助驾驶、智能座舱等,我们针对这些功能做了相应评测,建立了对应的评测系统,并在此基础上增加了榜单与选车等功能。

在实践中,我们使用不同的架构来满足系统的需求,架构风格是对历史工程经验的总结,可以有效的降低设计与沟通成本。传统的架构风格可以分为五大类,数据流风格、调用/返回风格、独立构件风格、虚拟机风格、仓库风格。其中数据流风格包括批处理、管道/过滤器风格。调用/返回风格包括主程序/子程序风格、数据抽象和面向对象风格、层次化结构风格。独立构件风格包括进程通讯风格、事件驱动风格。虚拟机风格包括解释器架构风格与基于规则的系统。仓库风格包括以数据库架构风格、黑板架构风格。其中常用的风格有,批处理风格,该风格的主要特征为一次性输入数据,数据经过不同的节点,每个节点处理完后进入下一个节点,直到处理完毕。层次化架构风格,该模式约定不同的层级,每个层级只做一类事情,一般只调用下一层,具有结构明确、耦合度低、维护方便等优点,同时分层过多也会带来性能降低等问题。数据库架构风格,该风格以数据为中心,进行集中存储,同时共享数据状态。除上述架构外,微服务架构也是一种比较常用的架构风格,该风格颗粒度细,独立部署运行,使用轻量级的通讯协议,如 HTTP,具有耦合度低,合作开发效率高,适合大型项目等特点。

该项目立项后进行需求分析,为了通用性,应用系统使用 B/S 架构,优先满足推广与跨平台等需求并保留未来的扩展性。服务端采用分层架构,明确责任并解耦。同时约定使用类 REST 架构风格进行通讯。

  1. 应用系统
    该系统主要采用 B/S 架构风格,传统 B/S 架构中,客户端与服务端开发人员往往是不同的人,但是要在一个项目中进行开发,会出现分工不明确,责任不清晰等问题,所以使用前后端分离的方式进行架构设计,客户端开发人员可以专注于 UI 的交互,数据通过 HTTP 协议与后端进行通讯,后端开发人员可以专注于业务流程的开发,明确责任,方便维护。一般前后端分离,前端只负责 UI 的交互,数据通过 AJAX 等技术去后端获取,展示效果通过 JavaScript 进行操作渲染,导致最终呈现在浏览器源码上的 HTML 是一个固定的结构,没有业务的相关数据,无法进行 SEO。因为该项目有推广需求,所以决定使用 SSR(服务端渲染)同构技术,客户端服务端都采用相同的 JavaScript 语言,客户端使用浏览器提供的 JS 引擎,服务端使用 NodeJS 运行时。用户或者爬虫初次访问页面的时候,NodeJS 会执行对应的 JavaScript 代码,生成对应的 HTML 与运行上下文返回给客户端,客户端拿到后,可以在客户端进行 UI 展示、路由控制等功能。按照该方案,可以做 SEO,满足推广需求,使用同构模式,同一套代码运行在两端,降低了开发成本。同时前后端分离,明确职责与分工。
  2. 后端服务
    该部分主要采用层次化架构风格,主要包括的层包括:中间件层,守卫层,管道层,控制器层,服务层,数据层。其中中间件层用来处理日志,包括用户请求信息,系统响应时间等。项目使用 Json Web Token 进行登录验证,其中主要的用户权限验证在守卫层进行处理。管道层用于输入输出数据的转换与校验,其中有输入部分可以在该层转化为标准输入,以及安全性的预防,如 XSS 攻击。输出数据的处理包括 HTTP 状态码的处理,返回体数据的格式标准化等功能。控制器层用于处理路由响应以及提供标准出入参模板,并委托给服务层处理业务。服务层为主要的业务逻辑处理空间,提供可复用的功能模块,做好封装,方便调用。数据层,该层主要用于数据的存储与交互,其中包括两个主要部分,一部分是数据的实体映射,该部分标记了数据实体与类的映射关系,简化了数据操作,增加了可维护性。另外一部分是针对数据操作的封装,包括数据库、缓存、队列等数据源的增删改查,由于已标记实体映射关系,可以做到与数据库无关,降低了耦合度。该架构风格可以提供一种职责清晰,低耦合,方便测试的应用程序。
  3. 前后端通讯
    考虑到通用性,通讯协议使用 HTTP,架构采用 REST 风格。REST 风格是一种以资源为中心的架构风格,所有的操作均是对资源的控制。REST 对应的 HTTP 控制操作有 GET、POST、PATCH、PUT、DELETE 等方法,GET 表示对资源的获取,POST 表示对资源的新增,PATCH 表示对资源的部分更新,PUT 表示对资源的整体替换,DEL 表示删除资源。REST 标准中要求使用 HTTP 状态码来表示对操作资源的响应,同时在返回体中标记该资源的状态。但是实际开发中会发现 HTTP 状态码过少,且有些复杂状态需要通过响应体里面的内容去判断如何继续交互。所以我们对 REST 做了一些改动,将请求分为是否到达业务层,如果没有达到业务层,按照标准 REST 风格进行响应。如果达到业务层那么统一状态码为 200,表示操作已经发生,在响应体里面以约定的标准格式表示本次处理的状态。项目中约定,业务状态码为 0,那么表示此次交互成功。如果业务状态码非 0,表示业务处理异常,客户端需要根据响应体里面的状态码、错误信息、参考文档链接等信息定位异常确定后续操作逻辑。这种以约定大于配置的方式降低学习和实现成本,极大简化了开发人员的心智负担。

该项目于 2023 年 10 月上线,目前已运行一年多,在此期间未出现严重生产事故。由于基于 B/S 架构风格,且前后端分离,扩展性较好,在二期工程增加移动设备支持的时候,服务端仅少量改动,便顺利上线,节约了开发成本。项目在运行过程中,遇到过数据库压力比较大的情况,我们在调用频率较高的业务上增加了缓存,并在数据库上做了读写分离、分库分表等操作后趋于稳定。

后续为了部署扩容方便,增加了 CI/CD 流程,因为服务端在设计之初是无状态的,方便横向扩展,我们将所有的应用都打包为 Docker 镜像,部署在云服务平台的 ServerLess 上,使用后才付费,极大降低了运行及维护成本。但同时也遇到了 ServerLess 的冷启动问题,当用户的请求到达云服务后,服务会判断当前的实例是否充足,如果无法满足当前的请求,服务会进入冷启动。冷启动时,服务器会去拉取镜像到本地,并启动该镜像,启动成功后,用户的请求才会被响应,该过程耗时几秒至几十秒不等,用户体验较差。由于 ServerLess的资源准备、镜像拉取和启动是云服务厂商控制,这部分环节我们无法参与,所以方案上,主要分为两部分,一是在流量高峰期提前预热服务,满足峰值流量要求,降低冷启动出现概率。二是优化容器镜像,减少镜像拉取和启动时间。目前冷启动概率已明显减少,镜像优化还有提升空间。

题目

论软件架构风格软件体系结构风格是描述某一特定应用领域中系统组织方式的惯用模式。体系结构风格定义一个系统家族,即一个体系结构定义一个词汇表和一组约束。词汇表中包含一些构件和连接件类型,而这组约束指出系统是如何将这些构件和连接件组合起来的。体系结构风格反应了领域中众多系统所共有的结构和语义特性,并指导如何将各个模块和子系统有效地组织成一个完整的系统。
请围绕“论软件架构风格”论题,依次从以下三个方面进行论述。

  1. 概要叙述你参与分析和设计的软件系统开发项目以及你所担任的主要工作。
  2. 软件系统开发中常用的软件架构风格有哪些?详细阐述每种风格的具体含义。
  3. 详细说明你所参与分析和设计的软件系统是采用什么软件架构风格的,并分析采用该架构风格设计的原因。

摘要

近些年,新能源汽车蓬勃发展,2022 年 6 月我司决定开发一个针对新能源汽车一体化平台,其中包括媒体、社区、选车等功能。我担任该项目的技术负责人,负责系统方案定制及技术指导工作。本文描述了该系统的架构分析与设计工作,其中包括三个主要部分,应用系统,该系统采用 B/S 架构,前后端分离的服务端渲染模式,满足了推广、跨平台等需求,降低了开发成本,明确了职责分工。后端服务,该部分采用层次化架构,通过划分不同的层,实现了一种明确职责,耦合性低,方便测试的应用程序。应用通讯,该部分采用 REST 架构风格,一种约定大于配置的架构,有良好的扩展性,降低了学习与开发成本。该系统于 2023 年 10 月上线运行,运行效果良好。

正文

2022 年,新能源汽车开始蓬勃发展,国务院也发布了相关政策规划。此时,市面上并没有专门针对新能源汽车的平台,为响应政府号召,满足用户需求,我司决定开发一个关于新能源汽车的一体化平台。

项目于 2022 年 6 月开始,团队成员共 17 人,我在该项目中担任技术负责人,主要负责系统方案定制及技术指导工作。该项目主要包括媒体、社区、选车等功能模块,其中媒体模块用于新能源汽车消息发布,包括了图文、视频、简报及最新的车型信息等子模块。社区模块主要为用户提供讨论渠道,其中包括了车型品牌圈子、话题讨论、车型打分与评价、热点新闻等功能。选车模块是其中的核心,在传统汽车平台的基础上,我们增加了很多新能源汽车特有的功能,比如三电系统、辅助驾驶、智能座舱等,我们针对这些特有功能做了相应评测,建立了对应的评测系统及榜单等功能。

在实践中,我们使用不同的架构风格来满足系统的需求,架构风格是对历史工程经验的总结,当我们在使用某一类架构风格的时候,约定一个名字,可以有效的降低沟通成本。传统的架构风格可以分为五大类,数据流风格、调用/返回风格、独立构件风格、虚拟机风格、仓库风格。其中数据流风格包括批处理、管道/过滤器风格。调用/返回风格包括主程序/子程序风格、数据抽象和面向对象风格、层次化结构风格。独立构件风格包括进程通讯风格、事件驱动风格。虚拟机风格包括解释器架构风格与基于规则的系统。仓库风格包括以数据库架构风格、黑板架构风格。其中常用的风格有,数据流风格中的批处理风格,该风格的主要特征为一次性输入数据,数据经过不同的节点,每个节点处理完后进入下一个节点,直到处理完毕,该风格的典型应用为早期批处理计算机。调用/返回风格中的层次化架构风格,该模式约定不同的层级,每个层级只做一类事情,一般只调用下一层,具有结构明确、耦合度低、维护方便等优点,同时分层过多也会带来性能降低等问题,典型应用为 OSI 七层网络模型。仓库风格中的数据库架构风格,以数据为中心,集中存储,共享数据状态,典型应用为数据库管理系统。除上述架构外,云原生架构中的微服务架构也是一种比较常用的架构风格,该风格颗粒度细,独立部署运行,使用轻量级的通讯协议,比如 HTTP,具有耦合度低,合作开发效率高,适合大型项目等特点。

该项目立项后进行需求分析,为了通用性,应用系统使用 B/S 架构,优先满足推广与跨平台等需求并保留未来的扩展性。服务端采用分层架构,明确责任并解耦。同时约定使用类 REST 架构风格进行通讯。

  1. 应用系统
    该系统主要采用 B/S 架构风格,传统 B/S 架构中,客户端与服务端开发人员往往是不同的人,但是要在一个项目中进行开发,会出现分工不明确,责任不清晰等问题,所以使用前后端分离的方式进行架构设计,客户端开发人员可以专注于 UI 的交互,数据通过 HTTP 协议与后端进行通讯,后端开发人员可以专注于业务流程的开发,明确责任,方便维护。一般前后端分离,前端只负责 UI 的交互,数据通过 AJAX 等技术去后端获取,展示效果通过 JavaScript 进行操作渲染,导致最终呈现在浏览器源码上的 HTML 是一个固定的结构,没有业务的相关数据,无法进行 SEO。因为该项目有推广需求,所以决定使用 SSR(服务端渲染)同构技术,客户端服务端都采用相同的 JavaScript 语言,客户端使用浏览器提供的 JS 引擎,服务端使用 NodeJS 运行时。用户或者爬虫初次访问页面的时候,NodeJS 会执行对应的 JavaScript 代码,生成对应的 HTML 与运行上下文返回给客户端,客户端拿到后,可以在客户端进行 UI 展示、路由控制等功能。按照该方案,可以做 SEO,满足推广需求,使用同构模式,同一套代码运行在两端,降低了开发成本。同时前后端分离,明确职责与分工。
  2. 后端服务
    该部分主要采用层次化架构风格,主要包括的层包括:中间件层,守卫层,管道层,控制器层,服务层,数据层。其中中间件层用来处理日志,包括用户请求信息,系统响应时间等。项目使用 Json Web Token 进行登录验证,其中主要的用户权限验证在守卫层进行处理。管道层用于输入输出数据的转换与验证,其中有用户输入参数到标准输入的转换,以及一些安全性方便的预防,如 XSS 攻击。输出数据的处理包括 HTTP 状态码的处理,返回体数据的格式标准化等功能。控制器层用于处理路由响应以及提供标准出入参模板,并委托给服务层处理业务。服务层为主要的业务逻辑处理空间,提供可复用的功能模块,做好封装,方便调用。数据层,该层主要用于数据的存储与交互,其中包括两个主要部分,一部分是数据的实体映射,该部分标记了数据实体与类的映射关系,简化了数据操作,增加了可维护性。另外一部分是针对数据操作的封装,包括数据库、缓存、队列等数据源的增删改查,由于已标记实体映射关系,可以做到与数据库无关,降低了耦合度。该架构风格可以提供一种职责清晰,低耦合,方便测试的应用程序。
  3. 前后端通讯
    考虑到通用性,通讯协议使用 HTTP,架构采用 REST 风格。REST 风格是一种以资源为中心的架构风格,所有的操作均是对资源的控制。REST 对应的 HTTP 控制操作有 GET、POST、PATCH、PUT、DELETE 等方法,GET 表示对资源的获取,POST 表示对资源的新增,PATCH 表示对资源的部分更新,PUT 表示对资源的整体替换,DEL 表示删除资源。REST 标准中要求使用 HTTP 状态码来表示对操作资源的响应,同时在返回体中标记该资源的状态。但是实际开发中会发现 HTTP 状态码过少,且有些复杂状态需要通过响应体里面的内容去判断如何继续交互。所以我们对 REST 做了一些改动,将请求分为是否到达业务层,如果没有达到业务层,按照标准 REST 风格进行响应。如果达到业务层那么统一状态码为 200,表示操作已经发生,在响应体里面以约定的标准格式表示本次处理的状态。项目中约定,业务状态码为 0,那么表示此次交互成功。如果业务状态码非 0,表示业务处理异常,客户端需要根据响应体里面的状态码、错误信息、参考文档链接等信息定位异常确定后续操作逻辑。这种以约定大于配置的方式降低学习和实现成本,极大简化了开发人员的心智负担。

该项目于 2023 年 10 月上线,目前已运行两年多,在此期间未出现严重生产事故。由于基于 B/S 架构风格,且前后端分离,扩展性较好,在二期工程增加移动设备支持的时候,服务端仅少量改动,便顺利上线,节约了开发成本。项目在运行过程中,遇到过数据库压力比较大的情况,我们在调用频率较高的业务上增加了缓存,并在数据库上做了读写分离、分库分表等操作后趋于稳定。

后续为了部署扩容方便,增加了 CI/CD 流程,因为服务端在设计之初是无状态的,方便横向扩展,我们将所有的应用都打包为 Docker 镜像,部署在云服务平台的 ServerLess 上,使用后才付费,极大降低了运行及维护成本。但同时也遇到了 ServerLess 的冷启动问题,当用户的请求到达云服务后,服务会判断当前的实例是否充足,如果无法满足当前的请求,服务会进入冷启动。冷启动时,服务器会去拉取镜像到本地,并启动该镜像,启动成功后,用户的请求才会被响应,该过程耗时几秒至几十秒不等,用户体验较差。由于 ServerLess的资源准备、镜像拉取和启动是云服务厂商控制,这部分环节我们无法参与,所以方案上,主要分为两部分,一是在流量高峰期提前预热服务,满足峰值流量要求,降低冷启动出现概率。二是优化容器镜像,减少镜像拉取和启动时间。目前冷启动概率已明显减少,镜像优化还有提升空间。

案例

alt text

微服务

alt text

题目

论软件架构风格软件体系结构风格是描述某一特定应用领域中系统组织方式的惯用模式。体系结构风格定义一个系统家族,即一个体系结构定义一个词汇表和一组约束。词汇表中包含一些构件和连接件类型,而这组约束指出系统是如何将这些构件和连接件组合起来的。体系结构风格反应了领域中众多系统所共有的结构和语义特性,并指导如何将各个模块和子系统有效地组织成一个完整的系统。
请围绕“论软件架构风格”论题,依次从以下三个方面进行论述。

  1. 概要叙述你参与分析和设计的软件系统开发项目以及你所担任的主要工作。
  2. 软件系统开发中常用的软件架构风格有哪些?详细阐述每种风格的具体含义。
  3. 详细说明你所参与分析和设计的软件系统是采用什么软件架构风格的,并分析采用该架构风格设计的原因。

摘要

近些年,新能源汽车蓬勃发展,2021 年 10 月我司决定开发一个针对新能源汽车一体化平台,其中包括媒体、社区、选车等功能。我担任该项目的技术负责人,负责系统方案定制及技术指导工作。本文描述了该系统的架构分析与设计工作,其中包括三个主要部分,应用系统,该系统采用 B/S 架构,前后端分离的服务端渲染模式,满足了推广、跨平台等需求,降低了开发成本,明确了职责分工。后端服务,该部分采用分层架构,通过划分不同的层,实现了一种明确职责,耦合性低,方便测试的应用程序。应用通讯,该部分采用 REST 架构风格,一种约定大于配置的架构,有良好的扩展性,降低了学习与开发成本。该系统于 2023 年 1 月上线运行,运行效果良好。

正文

2021 年,新能源汽车开始蓬勃发展,国务院发布了《新能源汽车产业规划通知(2021-2035)》。此时,市面上并没有专门针对新能源汽车的平台,为响应政府号召,满足用户需求,我司决定开发一个关于新能源汽车的一体化平台。

项目于 2021 年 10 月开始,我在该项目中担任技术负责人,主要负责系统方案定制及技术指导工作。该项目主要包括媒体、社区、选车等功能模块,其中媒体模块用于新能源汽车消息发布,包括了图文、视频、简报及最新的车型信息等子模块。社区模块主要为用户提供讨论渠道,其中包括了车型品牌圈子、话题讨论、车型打分与评价、热点新闻等功能。选车模块是其中的核心,在传统汽车平台的基础上,我们增加了很多新能源汽车特有的功能,比如三电系统、辅助驾驶、智能座舱等,我们针对这些特有功能做了相应评测,建立了对应的评测系统及榜单等功能。

在实践中,我们使用不同的架构风格来满足系统的需求,架构风格是对历史工程经验的总结,当我们在使用某一类架构方案的时候,约定一个名字,可以有效的降低沟通成本。传统的架构风格可以分为五大类。数据流风格,调用/返回风格,独立构件风格,仓库风格,虚拟机风格。其中常用的有,数据流风格中的批处理风格,该风格的主要特征为一次性输入数据,数据经过不同的节点,每个节点处理完后进入下一个节点,直到处理完毕,该风格的典型应用为早期批处理计算机。调用/返回风格中的分层风格,该模式约定不同的层级,每个层级只做一类事情,一般只调用下一层,具有结构明确、耦合度低、维护方便等优点,同时分层过多也会带来性能降低等问题,典型应用为 OSI 七层网络模型。仓库风格中的数据库架构风格,以数据为中心,集中存储,共享数据状态,典型应用为数据库管理系统。

该项目立项后进行需求分析,为了通用性,应用系统使用 B/S 架构,优先满足推广与跨平台等需求并保留未来的扩展性。服务端采用分层架构,明确责任并解耦。同时约定使用类 REST 架构风格进行通讯。

  1. 应用系统
    该系统主要采用 B/S 架构风格,传统 B/S 架构中,客户端与服务端开发人员往往是不同的人,但是要在一个项目中进行开发,会出现分工不明确,责任不清晰等问题,所以使用前后端分离的方式进行架构设计,客户端开发人员可以专注于 UI 的交互,数据通过 HTTP 协议与后端进行通讯,后端开发人员可以专注于业务流程的开发,明确责任,方便维护。一般前后端分离,前端只负责 UI 的交互,数据通过 AJAX 等技术去后端获取,展示效果通过 JavaScript 进行操作渲染,导致最终呈现在浏览器源码上的 HTML 是一个固定的结构,没有业务的相关数据,无法进行 SEO。因为该项目有推广需求,所以决定使用 SSR(服务端渲染)同构技术,客户端服务端都采用相同的 JavaScript 语言,客户端使用浏览器提供的 JS 引擎,服务端使用 NodeJS 运行时。用户或者爬虫初次访问页面的时候,NodeJS 会执行对应的 JavaScript 代码,生成对应的 HTML 与运行上下文返回给客户端,客户端拿到后,可以在客户端进行 UI 展示、路由控制等功能。按照该方案,可以做 SEO,满足推广需求,使用同构模式,同一套代码运行在两端,降低了开发成本。同时前后端分离,明确职责与分工。
  2. 后端服务
    该部分主要采用分层架构,主要包括的层包括:中间件层,守卫层,拦截器层,管道层,控制器层,服务层,数据访问层,数据实体层。其中中间件层用来处理日志,包括用户请求信息,系统响应时间等。项目使用Json Web Token 进行登录验证,当中用户权限验证在守卫层。拦截器层用于数据的接口统一返回处理,其中包括 HTTP 状态码的处理,返回体数据的格式标准化等功能。管道层用于数据转换与验证,比如一些数据类型的转换映射,还有用户输入参数验证、XSS 预防等功能。控制器层用于处理路由响应,委托给服务层处理业务。服务层为主要的业务逻辑处理空间,提供可复用的功能模块,做好封装,方便调用。数据访问层,主要是针对数据的操作,项目中用到的数据库、缓存的操作都在该层。数据库实体层是对数据库实体的映射,标识数据库实体字段与格式等。该架构风格可以提供一种职责清晰,低耦合,方便测试的应用程序。
  3. 前后端通讯
    考虑到通用性,通讯协议使用 HTTP,架构采用 REST 风格。REST 风格是一种以资源为中心的架构风格,所有的操作均是对资源的控制。REST 对应的 HTTP 控制操作有 GET、POST、PATCH、PUT、DELETE 等方法,GET 表示对资源的获取,POST 表示对资源的新增,PATCH 表示对资源的部分更新,PUT 表示对资源的整体替换,DEL 表示删除资源。REST 标准中要求使用 HTTP 状态码来表示对操作资源的响应,同时在返回体中标记该资源的状态。但是实际开发中会发现 HTTP 状态码过少,且有些复杂状态需要通过响应体里面的内容去判断如何继续交互。所以我们对 REST 做了一些改动,将请求分为是否到达业务层,如果没有达到业务层,按照标准 REST 风格进行响应。如果达到业务层那么统一状态码为 200,表示操作已经发生,在响应体里面以约定的标准格式表示本次处理的状态。项目中约定,业务状态码为 0,那么表示此次交互成功。如果业务状态码非 0,表示业务处理异常,客户端需要根据响应体里面的状态码、错误信息、参考文档链接等信息定位异常确定后续操作逻辑。这种以约定大于配置的方式降低学习和实现成本,极大简化了开发人员的心智负担。

该项目于 2023 年 1 月上线,目前已运行两年多,在此期间未出现严重生产事故。由于基于 B/S 架构风格,且前后端分离,扩展性较好,在二期工程增加移动设备支持的时候,服务端仅少量改动,便顺利上线,节约了开发成本。项目在运行过程中,遇到过数据库压力比较大的情况,我们在调用频率较高的的业务上增加了缓存,并在数据库上做了读写分离、分库分表等操作后趋于稳定。

后续为了部署扩容方便,增加了 CI/CD 流程,因为服务端在设计之初是无状态的,方便横向扩展,我们将所有的应用都打包为 Docker 镜像,部署在云服务平台的 ServerLess 上,使用后才付费,极大降低了运行及维护成本。但同时也遇到了 ServerLess 的冷启动问题,当用户的请求到达云服务后,服务会判断当前的实例是否充足,如果无法满足当前的请求,服务会进入冷启动。冷启动时,服务器会去拉取镜像到本地,并启动该镜像,镜像启动成功后,用户的请求才会被响应,该过程耗时几秒至几十秒不等,用户体验较差。由于 ServerLess的资源准备、镜像拉取和启动是云服务厂商控制,这部分环节我们无法参与,所以方案上,主要分为两部分,一是在流量高峰期提前预热服务,满足峰值流量要求,降低冷启动出现概率。二是优化容器镜像,渐少镜像拉取和启动时间。目前冷启动概率已明显减少,镜像优化还有提升空间。

软件架构评估

ATAM

阶段划分1
阶段划分2

构建与中间件技术

概念

概念

构建的复用

alt text
alt text
alt text
alt text

分类

alt text

中间件

alt text

优点

alt text

经典中间件

alt text

构建标准

alt text

CORBA

alt text

论文题 示例

试题:

论软件架构风格软件体系结构风格是描述某一特定应用领域中系统组织方式的惯用模式。体系结构风格定义一个系统家族,即一个体系结构定义一个词汇表和一组约束。词汇表中包含一些构件和连接件类型,而这组约束指出系统是如何将这些构件和连接件组合起来的。体系结构风格反应了领域中众多系统所共有的结构和语义特性,并指导如何将各个模块和子系统有效地组织成一个完整的系统。
请围绕“论软件架构风格”论题,依次从以下三个方面进行论述。

  1. 概要叙述你参与分析和设计的软件系统开发项目以及你所担任的主要工作。
  2. 软件系统开发中常用的软件架构风格有哪些?详细阐述每种风格的具体含义。
  3. 详细说明你所参与分析和设计的软件系统是采用什么软件架构风格的,并分析采用该架构风格设计的原因。

摘要

本文描述了一个新能源汽车媒体、社区、选车等一体化平台的架构分析与设计过程。该项目始于 2020 年,弥补了当时市面上没有新能源汽车平台的空缺,响应了国家对于新能源汽车的政策向导。本文介绍了 C/S架构风格,B/S架构风格,分层架构风格等常用软甲架构风格。详细说明了该系统软件组成部分的架构分析与设计,其中应用系统采用 B/S 架构,前后端分离的服务端渲染模式,满足了推广、跨平台等需求,降低了开发成本,明确了职责与分工。后端服务采用分层架构,通过划分不同的层,实现了一种明确自责,耦合性低,方便测试的应用程序。前后端通讯采用 REST 架构风格,一种约定大于配置的架构风格,降低了学习与开发成本,减轻了开发人员的心智负担。

背景

2020年,新能源汽车开始蓬勃发展,国务院发布了《新能源汽车产业规划通知(2021-2035)》。此时,市面上并没有专门针对新能源汽车的平台,于是,我司决定开发一个关于新能源汽车的一体化平台,其中包括媒体、社区、选车等功能。该项目于 2020 年 10 月开始规划,系统主要分为三个部分,其中前端应用采用 B/S 架构风格,后端服务采用分层架构风格,前端与后端通信采用 REST 架构风格。我在该项目中担任技术经理,负责架构设计与技术选型工作。

理论

在日常实践中,系统常用的软件风格有:C/S 架构风格,B/S 架构风格,分层架构风格等。C/S 架构风格,该架构分为客户端与服务端,使用约定的协议进行通信,具有分工明确、耦合度低、客户端性能好等优点,但同时因为需要开发两个端,会出现开发成本高,升级维护困难等缺点。B/S 架构风格,主要使用浏览器,传统 B/S 架构会在一个服务端进行渲染,现代开发流程中,考虑到分工问题,会分为浏览器客户端与服务端,是一种瘦客户端模式,具有开发成本低,跨平台等优点,但因为需要浏览器支持,所以可能出现兼容性问题。分层架构风格,该模式约定不同的层级,每个层级只做一类事情,一般只调用下一层,具有结构明确、耦合度低、维护方便等优点,同时分层过多也会带来性能降低等问题。

正文

该项目立项后进行需求分析,为了通用性,应用系统使用 B/S 架构,优先满足推广与跨平台等需求并保留未来的扩展性。服务端采用分层架构,明确责任并解耦。同时约定使用类 REST 架构风格进行通讯。

  1. 应用系统
    该系统主要采用 B/S 架构风格,传统 B/S 架构中,客户端与服务端开发人员往往是不同的人,但是要在一个项目中进行开发,会出现分工不明确,责任不清晰等问题,所以使用前后端分离的方式进行架构设计,客户端开发人员可以专注于 UI 的交互,数据通过 http 协议与后端进行通讯,后端开发人员可以专注于业务流程的开发,明确责任,方便维护。一般前后端分离,前端只负责 UI 的交互,数据通过 AJAX 等技术去后端获取,展示效果通过 JavaScript 进行操作渲染,导致最终呈现在浏览器源码上的 HTML 是一个固定的结构,没有业务的相关数据,无法进行 SEO。因为该项目有推广需求,所以决定使用 SSR(服务端渲染)同构技术,客户端服务端都采用相同的 JavaScript 语言,客户端使用浏览器提供的 JS 引擎,服务端使用 NodeJS 运行时。用户或者爬虫初次访问页面的时候,NodeJS 会执行对应的 JavaScript 代码,生成对应的 HTML 与运行上下文返回给客户端,客户端拿到后,可以在客户端进行 UI 展示、路由控制等功能。按照该方案,可以做 SEO,满足推广需求,使用同构模式,同一套代码运行在两端,降低了开发成本。同时前后端分离,明确职责与分工。
  2. 后端服务
    该部分主要采用分层架构,主要包括的层包括:中间件层,守卫层,拦截器层,管道层,控制器层,服务层,数据访问层,数据实体层。其中中间件层用来处理日志,包括用户请求信息,系统响应时间等。项目使用Json Web Token 进行登录验证,当中用户权限验证在守卫层。拦截器层用于数据的接口统一返回处理,其中包括 http 状态码的处理,返回体数据的格式标准化等功能。管道层用于数据转换与验证,比如一些数据类型的转换映射,还有用户输入参数验证、XSS 预防等功能。控制器层用于处理路由响应,委托给服务层处理业务。服务层为主要的业务逻辑处理空间,提供可复用的功能模块,做好封装,方便调用。数据访问层,主要是针对数据的操作,项目中用到的数据库、缓存的操作都在该层。数据库实体层是对数据库实体的映射,标识数据库实体字段与格式等。该架构风格可以提供一种职责清晰,低耦合,方便测试的应用程序。
  3. 前后端通讯
    考虑到通用性,通讯协议使用 http,架构采用 REST 风格。REST 风格是一种以资源为中心的架构风格,所有的操作均是对资源的控制。REST 对应的 http 控制操作有 GET、POST、PATCH、PUT、DELETE 等方法,GET 表示对资源的获取,POST 表示对资源的新增,PATCH 表示对资源的部分更新,PUT 表示对资源的整体替换,DEL 表示删除资源。REST 标准中要求使用 HTTP 状态码来表示对操作资源的响应,同时在返回体中标记该资源的状态。但是实际开发中会发现 HTTP 状态码过少,且有些复杂状态需要通过响应体里面的内容去判断如何继续交互。所以我们对 REST 做了一些改动,请求分为是否到达业务层,如果没有达到业务层,按照标准 REST 风格进行响应。如果达到业务层那么统一状态码为 200,表示操作已经发生,在响应体里面以约定的标准格式表示本次处理的状态。项目中约定,业务状态码为 0,那么表示此次交互成功。如果业务状态码非 0,表示业务处理异常,客户端需要根据响应体里面的状态码、错误信息、参考文档链接等信息定位异常确定后续操作逻辑。这种以约定大于配置的方式降低学习和实现成本,极大简化了开发人员的心智负担。

结束

该项目于 2022 年 7 月上线,项目在运行过程中,遇到过数据库压力比较大的情况,我们在调用较为频繁的流程上增加了缓存,并在数据库上做了读写分离、分库分表等操作后趋于稳定。后续为了部署扩容方便,增加了 CI/CD 流程,因为服务端在设计之初是无状态的,方便横向扩展,我们将所有的应用都打包为 Docker 镜像,部署在云服务平台的 ServerLess 上,使用后才付费,极大降低了运行成本。但同时也遇到了 ServerLess 的冷启动慢的问题,目前方案是根据日常流量大小,预留启动实例并适当裁剪镜像。目前该项目已运行三年多,未出现严重生产事故,后续二期工程增加了移动平台适配,由于该项目架构扩展性良好,目前已成功上线运行。

质量属性

alt text

  • 性能
  • 可用性
  • 安全性
  • 可修改行

alt text

性能

alt text

可用性

正常运行的时间比例

安全性

alt text

可修改性

较高性价比的对系统进行变更

简单评测:修改需要花多少时间
alt text

易用性、可测试性

alt text

评估

alt text

  • 敏感点:影响某一个质量属性
  • 权衡点:多个质量属性的敏感点
  • 风险点:架构设计中的隐患
  • 非风险点: 可接受的功能或业务

方法

alt text

场景

alt text

场景构成

alt text

可修改性

alt text

性能

alt text

可测试性

alt text

易用性

alt text

安全性

alt text

论文写作技巧

技巧

摘要(300)

  1. 项目背景
  2. 点题
  3. 体现分论点
  4. 总结

    背景(400)

  5. 系统的背景、发起单位、目的、开发周期、交付的产品等
  6. 你的主要岗位职责等,我的角色和单人的主要工作
  7. 系统功能模块划分,主要功能介绍

理论(300-400)

可以有个开头,介绍一下对主题的理解,然后再继续写
优先准确反应,其次至少部分准确放映,少量涉及响应

过度(100)

承上启下,引入主题内容(核心论点)

项目(1200-1500)

建议 三个分论点
1、某种特定风格的3个阶段、3个维度
2、3种架构分别展开SS
3、按3种子系统

分论点

  • 总起句
  • 编号+标题

结论(400)

先分析项目运行效果

再总结项目不足,针对不足提出解决方案或思路(最好是解决的,不是我的问题)

展望未来

基于架构的软件开发方法(ABSD)

alt text

开发过程

alt text

  • 架构需求
  • 架构设计
  • 架构文档化
  • 架构复审
  • 架构实现
  • 架构演化

alt text

alt text

alt text

软件架构风格

alt text

数据流风格

alt text
alt text

区别

  • 批处理:整体处理,没有用户交互
  • 管道-过滤器:流式处理,少量用户交互

调用/返回风格

调用返回风格

  • 面向过程
  • 面向对象
  • 分层架构
    分层架构风格

独立构件风格

独立构建风格

虚拟机风格

虚拟机风格

  • 解释器,自定义规则
    解释器

  • 规则为中心(再解释器的基础上,增加了经验规则),专家系统
    规则为中心

以数据为中心

以数据为中心

区别

区别

闭环控制架构(过程控制)

闭关控制架构

经典应用

  • 空调温控
  • 定速巡航

模型驱动架构(MDA Model Driven Architecture)

alt text

软件架构复用

软件架构复用

角度1

  • 机会复用(只要发现可复用的资源)
  • 系统复用(规划进行复用)

角度2

  • 横向复用(通用的)
  • 垂直复用(垂类、行业相关)

特定领域架构(DSSA)

聚焦某个行业
特定领域架构

  • 水平:不同领域,平移
  • 垂直:相同领域,深入

参与人员

参与人员

有领域经验的人员

  • 领域专家
  • 领域分析人员
  • 领域设计人员
  • 领域实现人员

三层次模型

三次模型

软件产品线

软件产品线

结构化需求分析

数据流图

数据流图

四要素

  • 数据流:数据流向,没有控制信息
  • 加工:功能块
  • 数据存储:数据库、数据表
  • 外部实体:使用这个系统的实体

数据平衡

  • 父子平衡
  • 没有输入有输出
  • 没有输出有输入
  • 输入输入不对版

面向对象分析 UML

用例图

用例图

  • 参与者(使用者,外部实体)
  • 用例(加工,功能块)
  • 流程

  • 识别参与者
  • 合并需求获得用例
  • 细化用例描述(需要细节才知道做什么)
  • 调整用例模型(包含、扩展、泛化关系优化)

用例关系

用例关系
用例关系

  • 包含(使用关系):多个功能的共性抽取出来,都涉及到公共用例,必然
  • 扩展关系: 有时要用到某种职能,可选
  • 泛化:提高通用性,父子关系,如果没有父子关系就是包含

类图和对象图

类图与对象图

  • 类名
  • 多重度
  • 关系

关系

alt text
语义强度(两者之间关系的稳定度),从弱到强

  • 依赖关系:一个事物影响到另外一个事物
  • 关联关系:描述了一组链,链是对象之间的连接
    • 聚合关系:部分与整体生命周期不同
    • 组合关系:部分和整体生命周期相同
  • 实现关系:接口和类的关系,父类改成给你了接口(抽象类,实现类的关系)
  • 泛化关系:特殊(子类)和一般(父类)关系

菱形,箭头部分是整体,另外一遍是部分