案例特训专题 - 架构设计篇
大家好呀!我是小笙,本章我主要分享系统架构设计师 - 案例特训专题 - 架构设计篇知识,希望内容对你有所帮助!!
架构设计篇
软件架构风格 ★★★★
五大架构风格 | 子风格 |
---|---|
数据流风格 | 批处理、管道-过滤器 |
调用/返回风格 | 主程序/子程序、面向对象、层次结构 |
独立构件风格 | 进程通信、事件驱动系统(隐式调用) |
虚拟机风格 | 解释器、规则系统 |
仓库风格 | 数据库系统、黑板系统、超文本系统 |
例题
1、某软件公司为其新推出的字处理软件设计了一种脚本语言,专门用于开发该字处理软件的附加功能插件
为了提高该语言的编程效率,公司组织软件工具开发部门为脚本语言研制一套集成开发环境。软件工具开发部门根据字处理软件的特点,对集成开发环境进行了需求分析,总结出以下3项核心需求:
- 集成开发环境需要提供对脚本语言的编辑、语法检查、解释、执行和调试等功能的支持,并要实现各种功能的灵活组合、配置与替换
- 集成开发环境需要提供一组可视化的编程界面,用户通过对界面元素拖拽和代码填充的方式就可以完成功能插件核心业务流程的编写与组织
- 在代码调试功能方面,集成开发环境需要实现在脚本语言编辑界面中的代码自动定位功能。具体来说,在调试过程中,编辑界面需要响应调试断点命中事件,并自动跳转到当前断点处所对应的代码
针对上述需求,软件工具开发部门对集成开发环境的架构进行分析与设计,王工认为该集成开发环境应该采用管道-过滤器的架构风格实现,李工则认为该集成开发环境应该采用以数据存储为中心的架构风格来实现。公司组织专家对王工和李工的方案进行了评审,最终采用了李工的方案
【问题1】 请用200字以内的文字解释什么是软件架构风格,并从集成开发环境与用户的交互方式、集成开发环境的扩展性、集成开发环境的数据管理三个方面说明为什么最终采用了李工的设计方案
软件架构风格是指描述特定软件系统组织方式的惯用模式。组织方式描述了系统的组成构件和这些构件的组织方式,惯用模式则反映众多系统共有的结构和语义
- 从集成开发环境与用户的交互方式看,用户通常采用交互式的方式对脚本语言进行编辑、解释执行与调试。在这种情况下,采用以数据存储为中心的架构风格能够很好地支持交互式数据处理,而管道-过滤器架构风格则对用户的交互式数据处理支持有限
- 从集成开发环境的扩展性来看,系统核心需求要求实现各种编辑、语法检查、解释执行等多种功能的灵活组织、配置与替换。在这种情况下,采用以数据存储为中心的架构风格,以数据格式解耦各种功能之间的依赖关系,并可以灵活定义功能之间的逻辑顺序。管道-过滤器架构风格同样以数据格式解耦数据处理过程之间的依赖关系,但其在数据处理逻辑关系的灵活定义方面较差
- 从集成开发环境的数据管理来看,集成开发环境需要支持脚本语言、语法树(用于检查语法错误)、可视化模型、调试信息等多种数据类型,并需要支持数据格式的转换。以数据存储为中心的架构将数据存储在统一的中心存储器中,中心存储器能够表示多种数据格式,并能够为数据格式转换提供各种支持。管道-过滤器架构风格通常只能支持有限度的数据格式,并且在数据格式转换方面的灵活性较差
【问题2】 在对软件系统架构进行设计时,要对架构需求进行分析,针对特定需求选择最为合适的架构风格,因此实际的软件系统通常会混合多种软件架构风格。请对核心需求进行分析,说明为了满足需求(2)和(3),分别应采用何种架构风格,并概要说明采用相应架构风格后的架构设计过程
- 为了满足需求(2),应该采用解释器架构风格。具体来说,需要:①为可视化编程元素及其拖拽关系定义某种语言,并描述其语法与语义;②编写解释器对该语言进行解释;③生成对应的脚本语言程序
- 为了满足需求(3),应该采用隐式调用架构风格。具体来说,首先需要定义“断点在调试过程中命中”这一事件,并实现当断点命中后的屏幕定位函数。集成开发环境维护一个事件注册表结构,将该事件与屏幕定位函数关联起来形成注册表中的一个记录项。在调试过程中,集成开发环境负责监听各种事件,当“断点在调试过程中命中”这一事件发生时,集成开发环境查找事件注册表,找到并调用屏幕定位函数,从而实现脚本语言编辑界面与调试代码的自动定位
质量属性与架构评估 ★★★★★
主要考察性能、可用性、安全性以及可修改性
- 敏感点是一个或多个构件(和/或构件之间的关系)的特性
- 权衡点是影响多个质量属性的特性,是多个质量属性的敏感点
- 风险点是指架构设计中潜在的、存在问题的架构决策所带来的隐患
- 非风险点是指不会带来隐患,一般以"XX要求是可以实现【或接受】的"方式表达
例题
1、某网上购物电子商务公司拟升级正在使用的在线交易系统,以提高用户网上购物在线支付环节的效率和安全性。在系统的需求分析与架构设计阶段,公司提出的需求和关键质量属性场景如下:
- (a)正常负载情况下,系统必须在0.5秒内对用户的交易请求进行响应(性能)
- (b)信用卡支付必须保证99.999%的安全性(安全性)
- ©对交易请求处理时间的要求将影响系统的数据传输协议和处理过程的设计(敏感点)
- (d)网络失效后,系统需要在1.5分钟内发现错误并启用备用系统(可用性)
- (e)需要在20人月内为系统添加一个新的CORBA中间件(可修改性)
- (f)交易过程中涉及到的产品介绍视频传输必须保证画面具有600*480的分辨率,20帧/秒的速率(性能)
- (g)更改加密的级别将对安全性和性能产生影响(权衡点)
- (h)主站点断电后,需要在3秒内将访问请求重定向到备用站点(可用性)
- (i)假设每秒用户交易请求的数量是10个,处理请求的时间为30毫秒,则“在1秒内完成用户的交易请求”这一要求是可以实现的(非风险点)
- (j)用户信息数据库授权必须保证99.999%可用(安全性)
- (k)目前对系统信用卡支付业务逻辑的描述尚未达成共识,这可能导致部分业务功能模块的重复,影响系统的可修改性(风险点)
- (l)更改Web界面接口必须在4人周内完成(可修改性)
- (m)系统需要提供远程调试接口,并支持系统的远程调试(可测试性)
在对系统需求和质量属性场景进行分析的基础上,系统的架构师给出了三个候选的架构设计方案。公司目前正在组织系统开发的相关人员对系统架构进行评估
【问题1】在架构评估过程中,质量属性效用树是对系统质量属性进行识别和优先级排序的重要工具。请给出合适的质量属性,填入下图中(1)、(2)空白处;并选择题干描述的(a)(m),填入(3)(6)空白处,完成该系统的效用树
【问题2】在架构评估过程中,需要正确识别系统的架构风险、敏感点和权衡点,并进行合理的架构决策。请用300字以内的文字给出系统架构风险、敏感点和权衡点的定义,并从题干(a)~(m)中各选出1个对系统架构风险、敏感点和权衡点最为恰当的描述
答案如上
Web 架构综合考查 ★★★★★
高性能、高可用、可维护、应变、安全
维度 | 涉及技术内容 |
---|---|
从架构来看 | MVC,MVP,MVVM,REST,Webservice,微服务 |
从并发分流来看 | 集群(负载均衡)、CDN |
从缓存来看 | MemCache,Redis,Squid |
从数据来看 | 主从库(主从复制),内存数据库,反规范化技术,NoSQL,分区(分表)技术,视图与物化视图 |
从持久化来看 | Hibernate,Mybatis |
从分布存储来看 | Hadoop,FastDFS,区块链 |
从数据编码来看 | XML,JSON |
从Web应用服务器来看 | Apache,WebSphere,WebLogic,Tomcat,JBOSS,llS |
从安全性来看 | SQL注入攻击 |
其他 | 静态化,有状态与无状态,响应式Wb设计,中台 |
单台机器到数据库与Web服务器分离
应用服务器集群
系统演变到这里,将会出现下面几个问题
- 用户的请求由谁来转发到具体的应用服务器?
- 用户如果每次访问到的服务器不一样,那么如何维护 session 的一致性?
负载均衡技术
应用层负载均衡
-
HTTP重定向,HTTP重定向就是应用层的请求转发。用户的请求其实已经到了HTTP重定向负载均衡服务器,服务器根据算法要求用户重定向,用户收到重定向请求后,再次请求真正的集群
特点:实现简单,但性能较差
-
反向代理服务器,在用户的请求到达反向代理服务器时(已经到达网站机房),由反向代理服务器根据算法转发到具体的服务器。常用的apache、nginx都可以充当反向代理服器
特点:部署简单,但代理服务器可能成为性能的瓶颈
传输层负载均衡
-
DNS域名解析负载均衡,DNS域名解析负载均衡就是在用户请求DNS服务器,获取域名对应的 IP地址时,DNS服务器直接给出负载均衡后的服务器 IP
特点:效率比HTTP重定向高,减少维护负载均衡服务器成本。但一个应用服务器故障,不能及时通知 DNS,而且 DNS 负载均衡的控制权在域名服务商那里,网站无法做更多的改善和更强大的管理
-
基于NAT的负载均衡,基于NAT的负载均衡将一个外部 IP 地址映射为多个 IP 地址,对每次连接请求动态地转换为一个内部节点的地址
特点:技术较为成熟,一般在网关位置,可以通过硬件实现。像四层交换机一般就采用了这种技术
静态算法
- 轮转算法:轮流将服务请求(任务)调度给不同的节点
- 加权轮转算法:考虑不同节点处理能力的差异
- 源地址哈希散列算法:根据请求的源 IP地址,作为散列键从静态分配的散列表找出对应的节点
- 目标地址哈希散列算法:根据请求目标 IP 做散列找出对应节点
- 随机算法:随机分配,简单,但不可控
动态算法
- 最小连接数算法:新请求分配给当前活动请求数量最少的节点,每个节点处理能力相同的情况下
- 加权最小连接数算法:考虑节点处理能力不同,按最小连接数分配
- 加权百分比算法:考虑了节点的利用率、硬盘速率、进程个数等,使用利用率来表现剩余处理能力
Session共享机制
- 携带 session 的 cookie
- 服务器间同步 session
- 将 session 存入 redis
有状态与无状态
- 无状态服务:对单次请求的处理,不依赖其他请求,也就是说,处理一次请求所需的全部信息,要么都包含在这个请求里,要么可以从外部获取到(比如说数据库),服务器本身不存储任何信息
- 有状态服务:它会在自身保存一些数据,先后的请求是有关联的
判断以下构件是有状态服务还是无状态服务
- Identification Bean(身份认证构件)有状态服务
- ResPublish Bean(资源发布构件)无状态服务
- ResRetrieval Bean(资源检索构件)无状态服务
- OnlineEdit Bean(在线编辑构件)有状态服务
- Statistics Bean(统计分析构件)无状态服务
持久化技术 ORM
ORM:对象与关系数据之间的映射
映射关系表
- 类 对应 数据库的表
- 对象 对应 记录(行数据)
- 对象的属性 对应 字段
实现技术对比表
维度 | Hibernate | MyBatis |
---|---|---|
简单对比 | 强大,复杂,间接,SQL无关 | 小巧,简单,直接,SQL相关 |
可移植性 | 好 | 差 |
复杂多表关联 | 不支持 | 支持 |
数据库读写分离化
主从数据库结构特点
- 一般一主多从,也可以多主从
- 主库做写操作,从库做读操作
主从复制步骤
- 主库更新数据完成前,将操作写 binlog 日志文件
- 从库打开 l/O 线程与主库连接,做 binlog dump process,并将事件写入中继日志
- 从库执行中继日志事件,保持与主库一致
缓存
常见缓存技术
- MemCache:一个高性能的分布式的内存对象缓存系统,用于动态Web应用以减轻数据库负载。通过在内存里维护一个统一的巨大的 hash 表,它能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等
- Redis:一个开源的使用 ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key - Value数据库,并提供多种语言的 APl
- Squid:一个高性能的代理缓存服务器,Squid支持FTP、gopher、HTTPS和HTTP协议
Redis 与 Memcache 比较
工作 | MemCache | Redis |
---|---|---|
数据类型 | 简单key/values结构 | 丰富的数据结构 |
持久性 | 不支持 | 支持 |
分布式存储 | 客户端哈希分片/一致性哈希 | 多种方式,主从、Sentinel、Cluster等 |
多线程支持 | 支持 | 不支持(Redist6.0开始支持) |
内存管理 | 私有内存池/内存池 | 无 |
事务支持 | 不支持 | 有限支持 |
有限支持 | 不支持,不能做数据恢复 | 支持,可以在灾难发生时,恢复数据 |
Redis 集群切片的常见方式
集群切片方式 | 核心特点 |
---|---|
客户端分片 | 在客户端通过key的hash值对应到不同的服务器 |
中间件实现分片 | 在应用软件和Redis中间,例如:Twemproxy、Codis等,由中间件实现服务到后台Redis节点的路由分派 |
客户端服务端协作分片 | Redis Cluster模式,客户端可采用一致性哈希,服务端提供错误节点的重定向服务 slot 上。不同的 slot 对应到不同服务器 |
Redis 数据分片方案
范围分片:按数据范围值来做分片
哈希分片:通过对key进行hash运算分片
一致性分片:哈希分片的改进
Redis 分布式存储方案
主从模式:一主多从,故障时手动切换
哨兵模式:有哨兵的一主多从,主节点故障自动选择新的主节点
集群模式:分节点对等集群,分 slots,不同slots的信息存储到不同节点
Redis 数据类型
类型 | 特点 | 示例 |
---|---|---|
String(字符串) | 存储二进制,任何类型数据,最大512MB | 缓存、计数、共享Session |
Hash(字典) | 无序字典,数组+链表,适合存对象 Key对应一个HashMap | 存储、读取、修改用户属性 |
List(列表) | 双向链表,有序,增删快,查询慢 | 消息队列、文章列表(记录前N个最新登录的用户ID列表) |
Set(集合) | 键值对无序,唯一,增删查复杂度均为0(1),支持交/并/差集操作 | 独立 IP、标签 |
Sorted Set(有序集合) | 键值对有序,唯一,自带按权重排序效果 | 排行榜 |
Redis 淘汰机制
Redis 持久化
主要有两种方式:RDB和AOF
- RDB:传统数据库中快照的思想。指定时间间隔将数据进行快照存储
- AOF:传统数据库中日志的思想,把每条改变数据集的命令追加到AOF文件末尾,这样出问题了,可以重新执行AOF文件中的命令来重建数据集
对比维度 | RDB持久化 | AOF持久化 |
---|---|---|
备份量 | 重量级的全量备份,保存整个数据库 | 轻量级增量备份,一次只保存一个修改命令 |
保存间隔时间 | 保存间隔时间长 | 保存间隔时间短,默认1秒 |
还原速度 | 数据还原速度快 | 数据还原速度慢 |
阻塞情况 | save会阻塞,但bgsave或者自动不会阻塞 | 无论是平时还是AOF重写,都不会阻塞 |
数据体积 | 同等数据体积:小 | 同等数据体积:大 |
安全性 | 数据安全性:低,容易丢数据 | 数据安全性:高,根据策略决定 |
Redis 常见问题
缓存雪崩
大部分缓存失效 => 数据库崩溃
解决方案
- 使用锁或队列:保证不会有大量的线程对数据库一次性进行读写,从而避免失效时大量的并发请求落到底层存储系统上
- 为 key 设置不同的缓存失效时间:在固定的一个缓存时间的基础上 + 随机一个时间作为缓存失效时间
- 二级缓存:设置一个有时间限制的缓存 + 一个无时间限制的缓存。避免大规模访问数据库
缓存穿透
查询无数据返回 => 直接查数据库
解决方案
- 如果查询结果为空,直接设置一个默认值存放到缓存,这样第二次到缓冲中获取就有值了。设置一个不超过5分钟的过期时间,以便能正常更新缓存
- 设置布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力
缓存预热
系统上线后,将相关需要缓存数据直接加到缓存系统中
解决方案
- 直接写个缓存刷新页面,上线时手工操作
- 数据量不大时,可以在项目启动的时候自动进行加载
- 定时刷新缓存
缓存更新
除 Redis 系统自带的缓存失效策略,常见采用以下两种:
- 定时清理过期的缓存
- 当有用户请求过来时,再判断这个请求所用到的缓存是否过期,过期的话就去底层系统得到新数据并更新缓存
缓存降级
- 降级的目的是保证核心服务可用,即使是有损的,而且有些服务是无法降级的(如电商的购物流程等)
- 在进行降级之前要对系统进行梳理,从而梳理出哪些必须保护,哪些可降级
内容分发网络 CDN
基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输得更快、更稳定
XML 与 JSON
扩展标记语言 XML
用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言
XML的优点
- 格式统一,符合标准
- 容易与其他系统进行远程交互,数据共享比较方便
XML的缺点
- XML文件庞大,文件格式复杂,传输占带宽
- 服务器端和客户端都需要花费大量代码来解析 XML,导致服务器端和客户端代码变得异常复杂且不易维护
- 客户端不同浏览器之间解析 XML 的方式不一致,需要重复编写很多代码
- 服务器端和客户端解析 XML 花费较多的资源和时间
JSON
一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性。可在不同平台之间进行数据交换
JSON的优点
- 数据格式比较简单,易于读写,格式都是压缩的,占用带宽小
- 易于解析,客户端 JavaScript 可以简单的通过 eval() 进行JSON数据的读取
- 支持多种语言,包括Java,JavaScript等服务器端语言,便于服务器端的解析
- 因为JSON格式能直接为服务器端代码使用,大大简化了服务器端和客户端的代码开发量,且完成任务不变,易于维护
JSON的缺点
- 没有XML格式这么推广得深入人心和使用广泛,没有XML那么通用
Web 应用服务器
WEB应用服务器可以理解为两层意思:
WEB服务器:其职能较为单一,就是把浏览器发过来的Request请求,返回 Html 页面
应用服务器:进行业务逻辑的处理
常见的 Web服务器
- Apache:Web服务器,市场占有率60%左右。它可以运行在几乎所有的Unix、Windows、Linux系统平台上
- Tomcat:开源、运行servlet和JSP Web应用软件的基于Java的Web应用软件容器
- JBOSS:是基于J2EE的开放源代码的应用服务器。一般与Tomcat或Jetty绑定使用
- Jetty:是一个开源的servlet容器,它为基于Java的web容器
响应式Web设计
一种网络页面设计布局,其理念是:集中创建页面的图片排版大小,可以智能地根据用户行为以及使用的设备环境进行相对应的布局
方法与策略
- 采用流式布局和弹性化设计:使用相对单位,设定百分比而非具体值的方式设置页面元素的大小
- 响应式图片:不仅要同比的缩放图片,还要在小设备上降低图片自身的分辨率