质量属性
参考视频:【13.5质量属性-架构评估】
在软件架构中,质量属性是衡量系统设计优劣的关键指标,通常分为运行时属性和非运行时属性。以下是一些常见的质量属性:
一、软件架构中的质量属性
运行时属性:
- 性能(Performance):系统在指定时间内处理请求的能力(如响应时间、吞吐量)。
- 可用性(Availability):系统在需要时可正常运行的时间比例(如避免宕机)。
- 可靠性(Reliability):系统在一定时间内无故障运行的能力。
- 安全性(Security):保护数据和系统免受攻击的能力。
- 可伸缩性(Scalability):系统通过增加资源应对负载增长的能力。
- 容错性(Fault Tolerance):在部分故障时仍能继续运行。
非运行时属性:
- 可维护性(Maintainability):系统易于修改和修复。
- 可扩展性(Extensibility):系统支持新增功能的便利性。
- 可测试性(Testability):系统易于验证功能正确性。
- 可移植性(Portability):系统在不同环境中迁移的能力。
二、12306系统中最重要的两个质量属性
对于中国铁路客户服务中心(12306)这类高并发、高负载的在线票务系统,最关键的两个质量属性是:
1. 性能(Performance)
2. 可用性(Availability)
为什么是这两个属性?
性能(Performance)
- 原因:
12306在春运、节假日等高峰期需应对每秒数百万级并发请求(如查询余票、下单支付)。若性能不足,会导致响应延迟、交易失败,甚至系统崩溃。 - 实际改进:
12306通过引入分布式架构、云计算资源弹性扩展、异步处理(如排队机制)、缓存优化(如余票信息缓存)等技术,显著提升了吞吐量和响应速度。
- 原因:
可用性(Availability)
- 原因:
系统需保障7×24小时不间断服务,尤其是在购票高峰期,短暂的宕机会导致大量用户无法购票,引发社会影响。 - 实际改进:
通过多数据中心容灾、负载均衡、服务降级(如流量高峰时简化非核心功能)等策略,确保核心服务始终可用。
- 原因:
其他属性的权衡
- 安全性:虽重要(需防止黄牛刷票、数据泄露),但相比性能和可用性,可通过独立的安全层(如风控系统)补充。
- 可扩展性:是性能的支撑手段,但最终目标仍是保障高性能和高可用。
三、总结
12306作为公共服务平台,其核心使命是在极端负载下稳定、高效地提供服务。性能确保海量请求被及时处理,可用性保障系统持续运行,二者直接决定了用户体验和社会效益,因此是最关键的质量属性。
可靠性计算
- 计算1:所有组件都是必需情况下,整个系统可靠性
- 计算2:至少一条路径可运行的概率
CPM计算最小执行时间
参考视频:【2 六时计算】
- FF = 紧后工作ES - EF
- 最晚结束时间LF从后向前算:min(紧后工作LS)
- TF = LS - ES
关键路径 A → C → E → F A→C→E→F A→C→E→F.最小总时间 160 160 160.
软件架构风格
分类
- 管道过滤风格:面向数据流,按照一定的顺序从前向后执行程序。
- 主程序_子程序风格:构建之间存在相互调用的关系,一般是显式地调用。
- 事件驱动风格:构建之间是相互独立的,不存在显式的调用关系,而是 通过某个时间触发、异步的方式来执行。
- 黑板风格:与数据为中心,所有的操作都是围绕 建立的数据中心 进行的。
管道-过滤器:每个构件都有一组输入和输出,构件读取输入的数据流,经过内部处理,产生输出数据流。前一个构件的输出作为后一个构件的输入,前后数据流关联。过滤器就是构件,连接件就是管道。
主程序/子程序风格
如果从质量属性上答,可以从以下几个方面回答:
- 模块化:每个子程序独立实现,便于单独测试和维护(可维护性)。因为每个子程序是独立的,可以直接给其他项目使用,具有可重用性。
- 可扩展性:新增功能只需增加新的子程序,无需修改主程序逻辑。
- 清晰的控制流:主程序明确管理逻辑处理,确保每一步按预期执行。
优点
- 结构清晰:主程序负责流程控制,子程序专注于具体功能,逻辑分层明确。
- 易于开发调试:模块化设计简化了单元测试和问题定位。
- 低技术门槛:适合小型团队或简单业务场景。
缺点
- 高耦合性:主程序与子程序之间依赖性强,修改主程序可能影响全局。
- 扩展性差:新增功能需修改主程序逻辑,难以适应复杂需求变化。
- 性能瓶颈:主程序集中调度可能成为单点性能瓶颈。
CS风格和BS风格的4个不同点
客户端依赖:CS需安装独立客户端软件;BS仅需浏览器,无需额外安装。
维护复杂度:CS需同步更新所有客户端;BS仅更新服务端代码,用户无感知。
跨平台能力:
BS天然支持多终端(PC/移动端);CS需适配不同操作系统。技术侧重:CS侧重客户端性能与本地计算(如C++/Java);BS聚焦Web技术栈(HTML/JS)与网络传输优化。
1. 安装与部署方式
CS 架构 | BS 架构 |
---|---|
客户端需要独立安装软件(如桌面应用),服务器端部署服务逻辑。 | 客户端无需安装,直接通过浏览器访问(如网页应用)。 |
示例:早期的银行柜台系统、单机游戏。 | 示例:Gmail、在线办公工具(如飞书)。 |
2. 客户端计算负载
CS 架构 | BS 架构 |
---|---|
客户端承担较多业务逻辑和计算(“胖客户端”),如数据校验、本地缓存。 | 客户端仅负责展示和简单交互(“瘦客户端”),核心逻辑在服务器端完成。 |
优势:减少服务器压力,适合复杂本地操作(如图形渲染)。 | 优势:轻量化客户端,依赖服务器算力。 |
3. 维护与升级
CS 架构 | BS 架构 |
---|---|
客户端需手动更新版本(用户主动下载安装包),维护成本高。 | 服务端更新后,浏览器自动同步最新版本,无需用户操作。 |
劣势:版本碎片化风险(如旧版本兼容性问题)。 | 优势:统一用户体验,快速迭代。 |
4. 跨平台能力
CS 架构 | BS 架构 |
---|---|
客户端需为不同操作系统(Windows/macOS/Linux)分别开发。 | 浏览器作为统一运行环境,天然支持跨平台访问。 |
示例:Photoshop(需下载对应系统版本)。 | 示例:Figma(浏览器中直接使用)。 |
总结:如何选择?
- CS 适用场景:
需要高性能本地计算(如设计软件)、离线操作(如工业控制)、复杂交互(如游戏)。 - BS 适用场景:
强调便捷访问(如电商平台)、快速迭代(如SaaS应用)、跨平台兼容性(如在线文档)。
现代系统常结合两者优势(如“混合架构”):
- 核心业务逻辑用 BS 实现(易维护),
- 特定功能(如文件上传、硬件交互)用 CS 插件补充。
软件架构设计
分层架构设计购票系统
分层架构通过将系统划分为多个层次(如表示层、业务逻辑层、数据层等),实现职责分离和高内聚低耦合,适合购票系统的模块化设计和高并发需求。
(1)软件架构图设计
(2)架构元素标注说明
客户端(表示层)
• Web前端:基于浏览器的用户界面(如React/Vue)。• 移动端App:Android/iOS应用程序,提供购票功能。
应用服务器(业务逻辑层)
• 购票管理:处理用户选座、锁座、生成订单等逻辑。• 支付处理:集成第三方支付(如支付宝、微信支付),完成交易流程。
• 库存管理:实时更新票务库存,防止超卖。
数据库/外部服务(数据层)
• 票务数据库:存储演出/车次信息、座位库存等。• 用户数据库:存储用户账户、订单记录。
• 第三方支付接口:与支付宝、微信支付等对接,完成支付验证。
架构特点
• 职责分离:各层专注于特定功能(如表示层负责交互,业务层负责逻辑)。
• 可扩展性:可通过横向扩展应用服务器应对高并发购票请求。
• 安全性:通过HTTPS加密通信,数据库隔离敏感数据。
• 容错性:数据库主从复制、支付接口重试机制提升可靠性。
主程序/子程序风格设计购票系统
开发基于主程序子程序的购票系统
要求,名称,该软件架构风格优缺点,画出该程序的软件架构图并在其中标注主要元素
主程序-子程序架构的优缺点
优点
- 结构清晰:主程序负责流程控制,子程序专注于具体功能,逻辑分层明确。
- 易于开发调试:模块化设计简化了单元测试和问题定位。
- 低技术门槛:适合小型团队或简单业务场景。
缺点
- 高耦合性:主程序与子程序之间依赖性强,修改主程序可能影响全局。
- 扩展性差:新增功能需修改主程序逻辑,难以适应复杂需求变化。
- 性能瓶颈:主程序集中调度可能成为单点性能瓶颈。
软件架构图
主要元素说明
- 主程序(绿色模块):核心调度中心,负责调用子程序并协调流程。
- 子程序(蓝色模块):独立功能单元(如用户验证、支付处理等)。
- 数据库(橙色模块):存储用户、票务和订单数据。
工作流程
- 用户发起请求 → 主程序调用子程序链。
- 子程序返回结果 → 主程序更新数据库并响应。
- 异常由主程序统一处理(如支付失败重试)。
基于发布订阅风格设计系统
发布-订阅架构的优缺点
优点
- 解耦性:发布者与订阅者无需直接交互,通过消息代理(Broker)通信,降低系统耦合。
- 动态扩展:可灵活新增发布者或订阅者,无需修改现有组件。
- 异步通信:支持高并发场景,订阅者按需消费消息,提升吞吐量。
- 广播能力:一条消息可被多个订阅者同时接收(如新闻分类推送)。
缺点
- 复杂性:需依赖消息代理(如Kafka、RabbitMQ),增加运维成本。
- 消息延迟:异步传递可能导致订阅者接收消息不及时。
- 可靠性风险:消息代理若宕机,可能丢失未持久化的消息。
软件架构图
主要元素说明
- 发布者(橙色模块):
- 新闻发布者、广告发布者等,负责生成事件(如新闻内容)。
- 消息代理(紫色模块):
- 核心中间件(如Kafka),管理主题(Topic),按规则路由消息。
- 订阅者(绿色模块):
- 消费者(如用户端、数据分析服务),订阅特定主题并处理消息。
工作流程
- 发布阶段:新闻/广告发布者将消息发送到消息代理的指定主题(如
tech_news
)。 - 路由阶段:消息代理根据主题匹配订阅者,推送消息。
- 消费阶段:订阅者异步接收消息(如用户App展示新闻)。
基于管道过滤器设计系统
管道-过滤器架构的优缺点
优点
- 模块化与复用性:
- 每个过滤器(如查询、支付)独立运行,可单独开发、测试和复用。
- 高内聚低耦合:
- 过滤器之间仅通过标准数据格式(如JSON)通信,无直接依赖。
- 灵活扩展:
- 新增功能(如优惠券核验)只需插入新过滤器,无需修改现有逻辑。
- 并行处理能力:
- 支持多用户并发购票,不同过滤器可并行处理不同请求。
缺点
- 事务一致性挑战:
- 跨过滤器的原子操作难实现(如支付成功后订单生成失败需回滚)。
- 性能瓶颈风险:
- 线性管道可能导致延迟累积(如多个过滤器串行处理)。
- 数据格式强约束:
- 管道间需严格定义数据格式,修改可能影响全链路。
软件架构图
主要元素说明
- 用户终端(灰色模块):用户交互入口(Web/App)。
- 过滤器链(绿色模块):
- 请求解析过滤器:标准化用户输入。
- 票务查询过滤器:查询可用票务数据。
- 座位选择过滤器:锁定用户所选座位。
- 订单生成过滤器:生成订单明细。
- 支付处理过滤器:调用第三方支付接口。
- 订单持久化过滤器:将订单写入数据库。
- 数据库(紫色模块):存储票务、订单和用户数据。
工作流程
- 数据流动:
- 用户请求 → 请求解析 → 票务查询 → 座位选择 → 订单生成 → 支付处理 → 订单持久化 → 返回结果。
- 异常处理:
- 任一过滤器失败(如支付超时),终止流程并触发补偿(如释放锁定座位)。
基于事件驱动设计系统
事件驱动架构的优缺点
优点
- 解耦与灵活性:
- 服务(如订单、支付、库存)通过事件异步通信,无直接依赖,可独立扩展和部署。
- 高吞吐与实时性:
- 事件队列(如Kafka)支持高并发处理,适合秒杀等高流量场景。
- 容错与可恢复性:
- 事件持久化后重试机制可保障最终一致性(如支付失败后自动回滚库存)。
- 动态扩展:
- 新增服务(如数据分析)只需订阅相关事件,无需修改现有系统。
缺点
- 复杂性高:
- 需管理事件总线、消费者组、重试策略,开发与运维成本较高。
- 调试困难:
- 分布式追踪复杂,事件链路长时问题定位耗时。
- 数据一致性延迟:
- 异步处理可能导致短暂的数据不一致(如库存显示延迟)。
软件架构图
主要元素说明
- 用户终端(灰色模块):用户购票入口(App/Web)。
- API网关(橙色模块):请求路由、鉴权与限流。
- 微服务(绿色模块):
- 订单服务:生成订单并发布
OrderCreated
事件。 - 库存服务:订阅订单事件,锁定库存并发布
StockLocked
事件。 - 支付服务:订阅库存事件,处理支付并发布
PaymentCompleted
事件。 - 通知服务:订阅支付事件,发送短信/邮件通知。
- 审计服务:订阅所有关键事件,记录操作日志。
- 订单服务:生成订单并发布
- 事件总线(紫色模块):消息中间件(如Kafka),负责事件存储与路由。
- 数据库(红色模块):各服务私有数据库(遵循领域驱动设计)。
工作流程
- 用户下单:
- 用户请求 → API网关 → 订单服务生成订单 → 发布
OrderCreated
事件。
- 用户请求 → API网关 → 订单服务生成订单 → 发布
- 库存锁定:
- 库存服务消费事件 → 锁定座位 → 发布
StockLocked
事件。
- 库存服务消费事件 → 锁定座位 → 发布
- 支付处理:
- 支付服务消费事件 → 调用第三方支付 → 发布
PaymentCompleted
事件。
- 支付服务消费事件 → 调用第三方支付 → 发布
- 后续操作:
- 通知服务发送购票成功短信,审计服务记录日志。