软件架构评估
意义
为什么评估?
- 识别结构性、框架性层面的缺陷,以在高层级上更好满足业务需求
评什么?
- 着重考虑非功能的需求,主要看需求的东西能否被架构的方案所覆盖
怎么评?
- 一般采取基于场景的架构评估方式
质量属性
**性能
系统的响应能力,单位时间内能处理的事件的个数,精度
应对方法
资源需求
- 提高计算的效率、减少计算开销、管理事件率、控制采样频率
资源管理
- 引入并发、维持多副本、增加可用资源
资源仲裁
- 采用适当的资源调度策略,如先进先出,固定优先级,动态优先级,静态调试等
**可用性
系统能够正常运行的时间比例,经常用两次故障之间的时间长度或在出现故障时系统能够恢复正常的时长来表示
应对方法
错误检测
- ping/pong检测、心跳、异常检测
错误恢复
- 表决、冗余(主动/被动)、备件
错误预防
- 进程监视器、事务、从列表删除不可用的服务器
**安全性
系统在向合法用户提供服务的同时能够组织非授权用户使用的企图或拒绝服务的能力,但是没有绝对的安全
应对方法
抵抗攻击
- 身份验证、用户授权、数据加密、数据完整性校验、限制访问等
检测攻击
- 入侵检测、流量检测
从攻击中恢复
- 识别:审计追踪,恢复:冗余
**可修改性
可维护性、可扩展性、结构重组、可移植性
能够快速地以较高的性价比或效率对系统进行变更的能力,通常以某些具体的变更为基准,通过考察这些变更的代价衡量可修改性
应对方法
局部化修改
- 维持语义的一致性、泛化模块、限制可能的选择、抽象通用服务,接口-实现分离
防止连锁反应
- 信息隐藏、维持现有接口、限制通信路径、使用仲裁者,限制访问
推迟绑定时间
- 运行时注册、配置文件、多态、组件更换、遵守已有协议
易用性
- 主要体现用户使用软件的学习成本问题,关注用户体验和界面友好
可测试性
- 通过测试揭示软件缺陷的容易程度,关注测试的时间成本和人力成本
评估方法
评估考虑的因素
敏感点
- 为了实现某种特定的质量属性,一个或多个构件所具有的特征
权衡点
- 影响多个互相冲突的质量属性的特性,是多个质量属性的敏感点
风险点
- 架构中潜在的、存在问题的架构决策带来的隐患
非风险点
- 不会带来隐患,一般通过“某某需求是可以实现或接受的”来表述
三种方式
基于问卷调查(检查表)的方式
基于度量的方式
基于场景的方式,应用最广泛
软件架构分析法(SAAM)
从针对可修改性的基础上发展而来架构权衡分析法(ATAM)
主要针对性能、实用性、安全性和可修改性成本效益分析法(CBAM)
- 基于成本效益进行的架构分析
对比
工具
- 质量效用树:(重要程度,实现难易)
L ~ Low
M ~ Medium
H ~ High
Web架构综合
负载均衡(传输层性能优于应用层)
算法
静态算法
(不考虑动态负载)- 轮询算法
- 加权轮询算法
- 源地址哈希散列算法
- 目标地址哈希散列算法
- 随机算法
动态算法
(考虑动态负载)最小连接数算法
- 考虑最小连接数,按最小优先分配
加权最小连接数算法
- 考虑加权后的最小连接数,按最小优先分配
加权百分比算法
- 考虑了节点利用率、硬盘速率、进程个数等因素
软/硬件分类
- 硬件:F5
- 软件:LVS、Nginx、HAproxy
Session一致性问题
成因
- 前后两次访问的session定位到不同的主机,造成session间信息不一致
解决
- 1、将session信息存入cookie中
- 2、服务器间同步session信息
- 3、将session信息存入redis等中间存储中
有状态和无状态
- 无状态:对单次请求的处理,不依赖其他请求
- 有状态:会在自身保存一些数据,先后的请求是有关联的
持久化技术ORM
数据库读写分离
- 主节点写,从节点读
- 日志的方式完成数据同步,写操作先写日志,从库接收到日志后,解析做数据同步
缓存机制
常见的缓存
MemCache
Redis
分片方案
- 范围分片,按照某个字段的值的范围进行分片
- 哈希分片,将某个字段求取hash后按照模取余后确定所指向的分片
- 一致性hash分片,画一个圆,每个节点取hash后确定该节点的数据范围(弧形),等一份数据过来时,计算数据的hash,按照规则将数据指向到对应的节点存储,读取时按照既定规则进行读取即可。这种方式对于增减节点较为友好,一定程度上解决了普通哈希分片在节点增减时的数据重建问题。
存储方案
主从
- 一主多从,手动切换
哨兵
- 监听主节点,主节点故障后重新选主并切换
集群
- 分节点对等集群,分slots,不同slots的信息分配到不同的节点上
缓存淘汰策略
不淘汰 noeviction
- 内存不足时,新写入的key会报错,系统默认策略
设置了过期时间的键空间
volatile-random
- 随机移除某个key
volatile-lru
- 优先移除最近未使用的key
volatile-ttl
- 优先移除ttl小的key
全键空间
allkeys-random
- 随机移除某key
allkeys-lru
- 优先移除最近未使用的key
二者对比:
与数据库的协作
数据读取
- 先尝试从缓存读,如果读不到就从数据库读,读数据库之后需要把结果更新到缓存。
数据写入
- 先根据key写到数据库,然后根据key将缓存内容更新