上一篇文章,简要介绍了架构的概念和架构设计流程,并简单介绍了需求分析的内容,
并在最后指出:需求分析的产出物,要包括非功能性需求,常见的非功能性需求如下:

  • 完成任务的速度
  • 结果的精度
  • 操作的安全性
  • 产品的容量
  • 允许的值的范围
  • 吞吐量,例如tps
  • 资源使用的效率
  • 可靠性
  • 容错能力和健壮性
  • 伸缩性
  • 可扩展性

红色部分是常见项目的重点关注点(注:根据项目背景不同而不同,比如安全产品最重要的是安全性)。
对一个项目而言,更高的非功能性要求,代表着更高的系统复杂度、更高的成本投入(时间成本、人力成本、硬件及维护成本),需要根据公司/项目/人力/环境等背景因素综合评估。

非功能性需求

需求分析后输出的非功能性需求,必须可量化,基本要求:

  • 非功能性需求必须无二义性,可理解,可测试。
  • 标准先行,否则设计、实现或测试将没有依据。
  • 所有需求都可测量,测量的尺度是用于测试产品符合程度的单位。

作为架构设计人员,对非功能性需求,要关注的最重要的点:不能度量的需求不是真需求

  • 度量的定义如下:
    • 指在软件开发过程中,通过数据收集和数据分析,来评估软件质量和性能的过程。
      这个过程可以帮助开发团队了解软件的现状,开发的进展,发现潜在的问题和风险,并对软件进行定量的评估,及制定改进措施。

无效的非功能性需求举例:

  • 必须支持高并发:系统希望能随1000用户并发,还是10000用户并发?
  • 接口响应要尽可能快:可接受的响应时间100毫秒?200毫秒?还是1秒?有5%的用户超过1秒能不能接受?

下面逐一介绍一下这些非功能性需求的概念,以及部分度量指标,在做架构设计应该评估和采集这些指标,以评估当前系统情况,及未来的优化方向。

1、完成任务的速度

  • 解释:
    即性能/效率,通常是指软件的“时间/空间”效率,而不仅是指软件的运行速度。
  • 度量指标:
    • 响应时间(平均时间/最大时间/95分位时间)
    • CPU使用率
    • 缓存命中率
    • IO次数/IO时长(磁盘IO/网络IO)
    • 最大连接数/并发数
  • 示例:
    用户单次操作的最大响应时间不得高于2秒;
    产品必须每10秒读取一次传感器的值;
    系统应该在0.25秒内识别出一架飞机是敌人还是友军;
    云端配置更新后,产品必须在1分钟内更新到最新配置并完成刷新。
  • 数据举例:
    一个2.5GHz的CPU,每个CPU时钟周期是0.4纳秒,
    假设每个CPU时钟周期为1秒,常见的计算机耗时及相对1秒时钟周期耗时的对比数据如下:

    对比的结果还是挺触目惊心的吧,哈哈。
  • 内存是千兆网速的200倍,所以能用内存缓存时,就不要考虑Redis了;
  • 上下文切换也很耗费CPU性能,所以IO不多的任务,就不要考虑多线程了;
  • 尽快更换SSD硬盘吧;
  • 做了跨数据中心高可用时,尽量保证每个中心都有整套服务,确保同一个数据中心内互访。

2、结果的精度

  • 解释:
    通常指软件输出的结果(例如计算结果、测量结果、数据分析结果等)的精度要求。
  • 度量指标:
    其衡量标准是输出值与真实值之间的误差大小。
  • 说明:
    结果的精度在多数系统内一般不会特别体现出来,但是在一些行业内,精度是特别重要的指标:
    • 银行系统:虽然银行给用户的利息是精确到分,但是内部的计算,必须至少精确到厘,甚至更高的精度,才能保证数据汇总正确;
    • 自动驾驶系统:自动驾驶系统对精度的重要性显然是极高的,障碍物与车的距离判断准确与否,避免重影等非障碍物误判等。
      通常精度用范围区间指示,如 ±1厘米
  • 注:
    所有涉及金额的存储和计算,都建议采用整数存储,例如普通人民币计算,写入DB时,用分为单位写入;
    上面说到的利率计算,可以用厘为单位写入DB及内存计算,以避免二进制问题带来的小数精度问题。

3、操作的安全性

  • 解释:
    指保护系统免受意外访问、破坏和误用的能力。包括:认证和授权、访问控制、数据保护、通信安全、安全日志、定期审计等。
    主要通过方案评审和测试用例进行确认,如:
    密码复杂度、两步验证的算法安全性、角色权限和访问控制策略等、数据加密保护方案评估、备份频率和完整性、灾备方案、通信加密强度、审计日志的完整性和保密性、安全审计的频率和深度
  • 备注:
    • 加密的强度应当充分考虑,例如常规的MD5加盐已经不够安全了,比较好的作法是:MD5( MD5(明文+用户特定盐值1) + 用户特定盐值2)
    • 涉及金额的数据写入DB时,应当增加一个校验字段,根据该行的所有字段进行Hash加盐后计算获得,
      使用时,需要校验该字段,如果不匹配应当禁止该笔交易,避免内部员工篡改数据;
    • 安全性要求高的系统,应部署独立的加解密服务,传入用户ID + 源数据,该服务根据用户ID获取特定密钥加密,返回加密后的数据;
    • 所有敏感数据查看/操作,均应二次验证身份;所有数据导出,均应脱敏处理;
    • 高安全性要求的产品线,应当跟其它产品线网络隔离,避免通过其它产品漏洞,从内网攻击本产品。

4、产品的容量

  • 解释:
    通常是指软件在一定时间内的数据容量要求。
  • 度量指标:
    根据软件要求输出,如已注册用户数;已存储文件大小
  • 示例:
    一个月内系统能支持到1万注册用户,一年内能支撑达到10万注册用户;
    一个月内S3存储能支持10万文件/100GB,一年内能支撑达到10亿文件/5PB。

5、允许的值的范围

  • 解释:
    软件系统在使用过程中,对一些输入数据的范围限制。
  • 示例:
    用户姓名的最大长度
    交易金额的最小值和最大值,比如餐厅的菜品单价不允许超过1万元

6、吞吐量

  • 解释:
    通常是指软件在单位时间内传输数据的数量。
  • 度量指标:
    • TPS:Transactions Per Second(每秒传输的事物处理个数)
    • QPS:Queries Per Second(每秒查询次数)
      可以理解为服务器收到一次请求,就增加一次QPS。
      假设打开网站首页,向服务器发起了3个请求:首页、登录状态、新闻列表,
      此时TPS加1,QPS加3
    • RT:Response Time(每次请求的响应时间)
    • 并发数:系统同时处理的请求数
      比如某个服务收到了100个请求,都还在处理中没有响应,则此时并发就是100
      很多文章说 并发数 = QPS * 平均响应时间,这其实是不准确的,这是2个不同的性能指标,
      确实:并发越高,可能会导致响应时间变长,QPS也确实会相应变小,
      但是这些性能指标,都跟服务器状态、网络状态、磁盘等的影响,并不能直接互相转换。
  • 示例:
    支付系统TPS达到4000以上
    商城系统TPS达到2000以上, QPS达到10000以上
    营销系统并发数达到10000以上
    订单系统API的RT在100ms以内

7、资源使用的效率

  • 解释:
    通常指定特定硬件组件上的使用量、占用率、释放情况,如需要4核以上CPU、16G以上内存;需要千兆带宽。
  • 度量指标:
    • CPU占用时长
    • 内存使用量
    • 磁盘占用空间
    • IO均值、峰值、总传输数据量等
    • TPS单位时间内能处理完
  • 说明:
    通过良好的架构设计、较优的算法实现可以优化资源使用效率。
    特殊场景无法横向扩容机器时,可以通过简单的单机硬件配置提升来优化。

8、可靠性

  • 解释:
    指的是产品在规定的时间内,在规定的条件下,完成预定功能的能力。
  • 度量指标:
    • MTBF——全称是Mean Time Between Failure,即平均故障间隔时间。
    • MTTR——全称是Mean Time To Repair,即平均故障恢复时间。
    • MTTF——全称是Mean Time To Failure,即平均无故障时间。
    • 可用性Availability=UpTime/(UpTime+DownTime)=MTBF / (MTBF + MTTR)
  • 示例:
    服务平均无故障时间占比应该高于99.9%, 5分钟内请求错误率高于1%即判定为故障。
  • 注:
    • 有些文章说MTBF = MTTF + MTTR,
      我的理解,MTBF是平均故障间隔时间,指系统正常运行的平均时间,不应该包含MTTR。
    • MTTF是指系统平均能够正常运行多长时间,才发生一次故障。系统的可靠性越高,平均无故障时间越长。
      后续我再会专题写一篇文章,介绍可靠性和可用性。

9、容错能力和健壮性

  • 解释:
    指系统在面对错误和异常情况时的处理能力和稳定性。
  • 度量指标:
    通常通过开发规范约束、代码检测质量、设计评审来衡量;
    以及系统崩溃次数、错误日志统计等数据评估
  • 示例:
    用户输入任意数据,系统均能正常处理或提示错误,不会崩溃或产生错误响应,生成错误数据。
    系统出现崩溃时,能记录异常信息,以供问题排查,并能有效响应用户(服务降级)

10、伸缩性

  • 解释:
    不改变系统的情况下,通过简单升降配置/增减服务器来调整系统处理业务的能力。
  • 度量指标:
    • 响应时间:用户数增长/请求数增加,响应时间是否随之增加
    • 错误响应数:用户数增长/请求数增加,错误响应是否随之增加,如超时,网络错误,限流错误等
  • 示例:
    在访问量平滑增长的情况下,能自动扩容达到服务可用性不受影响;
    在访问量下降的情况下,能自动缩容以降低成本,且服务可用性不受影响;

11、可扩展性

  • 解释:
    新增产品或需求时,实现对现有产品无影响,透明上线新产品的能力。
  • 示例:
    系统支持蓝绿发布、滚动发布、灰度发布。

参考知识

对于非功能性需求,已经有不少的业界标准可供学习和参考,提供了更多的非功能性需求和说明,如:

  • Jim McCall 软件质量模型(1977 年)

  • Barry W. Boehm 软件质量模型(1978 年)

  • FURPS/FURPS+ 软件质量模型

  • R. Geoff Dromey 软件质量模型

  • ISO/IEC 9126 软件质量模型(1993 年)

  • ISO/IEC 25010 软件质量模型(2011 年)

下面介绍2个目前比较常用的软件质量模型,建议认真阅读理解一下:

软件质量模型 ISO/IEC 25010

由ISO(国际标准化组织) 和 IEC(国际电工委员会) 联合制订的软件质量标准,替代 ISO/IEC 9126标准;
详细介绍参考: https://iso25000.com/index.php/en/iso-25000-standards/iso-25010

软件质量模型 FURPS/+

FURPS 模型最早是由惠普公司的罗伯特·格雷迪(Robert Grady)及卡斯威尔(Caswell)提出,后来由 Rational Software 进行扩展至 FURPS+。
详细介绍可以参考:https://sceweb.uhcl.edu/helm/RationalUnifiedProcess/process/workflow/requirem/co_req.htm

结语

上面简单介绍了一些非功能性需求和相关指标,后面两篇文章,会对软件系统比较关注的可用性 和 性能优化进行介绍。