1.事件驱动架构概述
1.1定义
事件是指:状态的显著变化
事件来源: 可以是内部、外部;软件、硬件层面
事件通知:将事件通知到架构其他部分的一种特殊消息事件驱动架构, 是通过事件进行通信的软件架构,是常用的架构范式中的一种,其关注事件的产生、识别、处理("消费")、响应。
1.2组件
事件(通知) :由于内/外事件引发/触发/产生的特殊的消息事件队列
一组数据结构和对应的处理逻辑,用于接收缓存接收到的事件(通知)
事件分发器 :对事件进行预处理,分类地将事件转发到对应的处理逻辑中;有事件流式处理 和 注册/发布式处理两种实现方式
事件通道 :是分发器将事件分发到事件处理逻辑的通道事件处理逻辑,实现具体业务逻辑
1.3事件流式处理
所有的事件像流水一进入事件队列并能被所有的事件处理逻辑读取;事件处理逻辑根据需要读取事件队列中的任意事件,或删除处理过的事件
数据流:所有数据注入一个通过数据流平台实现的事件队列 中,可用来在输入事件流中识别事件的某种有意义的模式
简单的事件处理:事件到来后立即触发对事件的处理
复杂的事件处理:要求事件处理机制能处理和缓存多个事件来识别其模式
1.4注册/发布式处理
事件处理逻辑向事件分发器订阅某个/类事件通知
1.4.1优点
天然为事件的发生和处理建立了模型
事件与事件处理逻辑、事件处理逻辑之间都得到了充分的解耦
交互式的响应性能较好
1.4.2缺点
要考虑异步通信中的常见问题
开发相对复杂 ,与事件处理相关的缺陷也非常常见
同时在实践中,此类缺陷导致的失效往往比较难以复现和定位
1.4.3支持的功能
事件通知的编码解码(可选)
事件通知的发送与接收
事件队列的管理与维护
事件的注册/注销
事件的优先级(可选)
事件与注册记录的匹配和过滤
事件的广播/转发
事件通道的创建、管理与维护(可选)
事件处理机制的调用方法
事件处理后的返回和/或后续处理(可选)
2.事件驱动架构质量特性
2.1功能性
功能完备性:基本与架构无关。但事件驱动架构能帮助简化复杂交互响应的实现
功能正确性:基本与架构无关。由具体的业务逻辑实现决定
功能适合性:与架构无关。由功能的交互设计和使用场景决定
2.2可靠性
事件驱动架构与可靠性及其子质量特性密切相关。在大多数情况下,正确实现的事件驱动架构虽然与成熟性、可用性这两个子特性相关,但相对而言更容易出现问题的是容错性和易恢复性
2.3容易出现的缺陷:
1.事件通知的编码解码 : 编码解码库可能出现缓存溢出,数据编码错误,数据的解码错误,解码缓存溢出
测试方法:边界值、等价类对事件通知的消息内容参数取值;决策表、语法分析对消息内容中有意义或易出错的参数取值组合
2.事件通知的发送与接收:消息的丢失/重复
测试方法:场景法
3.事件队列的管理与维护 :事件队列溢出
测试方法:边界值分析法
4.事件的注册与注销: 事件注册遗漏,未注册事件进行注销,重复注册
测试方法:代码评审
5.事件的优先级(可选):优先级倒挂(高优先级的可能依赖某些低优先级的)
测试方法:场景法,静态分析
6.事件与注册记录的匹配和过滤: 对合法的事件识别有误,注册列表上注册模块的事件转发逻辑容易出错
测试方法:单元测试中采用基于代码的覆盖技术;对通知匹配数--等价类、决策表
7.事件的广播和转发:事件广播和转发出现异常后所有未出现异常的处理逻辑被锁定
测试方法:静态分析设计逻辑覆盖
8.事件处理后的返回/后续处理(可选):未定义事件处理逻辑的错误返回码,对事件处理逻辑返回的错误码处理不符合功能逻辑要求;多个事件处理逻辑之间存在依赖关系导致失效
测试方法:前者:静态测试、代码评审;后者:场景分析
2.4性能效率
1.事件驱动架构同样与性能和效率及其子质量特性密切相关。性能和效率的3个子质量特性都受到事件驱动架构各个环节的影响容易出现的缺陷
2.事件通知的编码解码: 编码解码库出现故障,导致编码解码耗时过长
测试方法:等价类、边界值
3.事件通知的发送与接收:消息延迟
测试方法:边界值
4.事件队列的管理与维护:优先级高事件长时间得不到处理
测试方法:场景法,等价类、边界值
5.事件的注册/注销: 事件注销后未对其进行删除,而占用资源
测试方法:场景法
6.事件的优先级(可选):优先级设置错误,优先级处理代码逻辑的错误导致事件得不到及时处理,甚至溢出
测试方法:场景法
7.事件与注册记录的匹配和过滤: 时间上达不到实施性要求
8.事件的广播/转发:事件广播/转发慢,导致资源占用过度以及超过系统缓存容量
测试方法:场景法
9.事件通道的创建、管理与维护(可选):由于在系统启动或初始化时候,一般影响比较小
测试方法:场景法
10.事件处理机制的调用方法:调用缓慢不能满足时间特殊性要求﹣﹣等价类、边界值
11.事件处理后的返回 和/或 后续处理(可选):事件后续处理过慢或堵塞,导致不能满足时间特殊性要求
测试方法:静态分析、评审
2.4.易用性
易用性质量特性与一般的系统使用的用户基本无关
程序员也可以作为软件系统的一种用户。这时架构的易用性有一定的体现
容易出现的缺陷
1.事件通知的编码解码:进行编码解码前未能检查合法性 以及编码解码错误时未能给出合适的错误返回代码
测试方法:测试技术发现代价比较大,一般结合静态分析
2.事件通知的发送与接收:对异常的数据发送未做保护
测试方法:场景法
3.事件的注册/注销: 当收到重复注册或出现未注册却收到注销请求时出现处理异常或者异常的后续事件通知出现意外结果
测试方法:场景法
2.5信息安全性
常见的与信息安全性质量特性相关的缺陷集中在接口的处理上
2.6兼容性
兼容性相关的质量要求主要与具体的业务和运行环境相关。对于事件驱动架构而言,与外部系统发生联系的组件更容易在兼容性上存在缺陷
容易出现的缺陷
1.事件通知的编码解码:编码解码处理逻辑理解不一致,导致误读、解码错误等(互操作性)
测试方法:通过标准化的回归测试
2.事件通知的发送与接收:容易出现语义不一致(石操作性)﹣通过标准化的同收测试事件的注册/注销:涉及多个子系统,事件注册/注销由其他系统发起时,导致注册/注销时间有误,请求的内容格式不一致(互操作性)
测试方法:通过标准化的回归测试
3.事件的优先级(可选):内外部的优先级定义不一致(互操作性)
测试方法:集成测试阶段采用场景法
4.事件的广播/转发:转发事件的内容格式兼容性问题,在不必要的范围进行广播
测试方法:场景法
2.7维护性
只要很好地遵循了事件驱动架构的架构范式要求,在事件驱动框架(甚至引擎)下编程,一般很少出现维护性问题
可测试性方面:
1.事件收发机制:植入对事件的监控、修改、比对等测试功能
2.事件队列和分发器组件:提供日志信息
3.事件的注册/注销:提供隐含的测试模块注册能力
4.事件处理机制的调用:提供钩子
2.8可移植性
事件驱动架构也通过架构范式提供了很好的可移植性
3.事件驱动架构测试策略
通常采用分层测试策略
++3.1.单元测试++
各个组件
事件收发模块/函数
编解码模块/函数
事件队列的管理模块/函数
通过功能和代码进行覆盖
++3.2集成测试++
围绕核心功能来设计
++3.3系统测试++
一般不安排
4.对事件驱动架构实现的业务逻辑
++4.1单元测试++
集中在事件处理逻辑中
++4.2集成测试++
优先级机制
集成测试可以跳过
业务逻辑依赖的事件驱动架构组件未经测试,必须完成集成测试
++4.3系统测试++
基于规格说明书的测试技术
通过用户界面或系统接口来实现测试执行