好久没写技术类的文章了,整理下最近发现的一些非功能需求类的缺陷及对应的解决方案,仅供参考,技术类的缺陷与技术架构是强相关的,切勿生搬硬套。
01
第一类:接口超时问题。
不论是通过F12分析页面请求,还是查看Skywalking做链路分析,经常会发现接口超时的问题。简单地调用流程图如下:
针对这类问题,需要区分不同的业务诉求来做处理,主要分成两类。
源系统对结果实时性要求高的,可以做以下优化手段:
- 目标系统要做分页请求拦截,每页在10~200条之间;
- 目标系统尽可能避免多层循环嵌套,在循环中避免对数据库批量请求操作;
- 目标系统尽可能采用一些缓存机制来确保业务逻辑加速处理;
源系统对结果实时性要求低的,可以做以下优化手段:
- 通过MQ消息队列进行解耦处理;
- 采用异步机制来提升接口的性能和MQ的吞吐量
02
第二类:数据库死锁问题。
在多并发的情况下,由于锁的使用不当,或者事务过大,都会造成数据库锁的问题,进而引发性能问题,常见的大事务引发的问题如:
如何定位数据库是否有死锁,如果是Mysql数据库,可通过“show engine innodb status" SQL来查看(需要较大的数据库权限),如果出现如下信息,则说明有锁存在,具体的分析过程请自行查阅相关资料。
解决方案通常有两种:利用好Spring的事务传播机制,共7种,了解它们的使用场景及用法,全局自动提交/回滚事务。
另一种是利用java finally块代码执行机制,在代码异常块中手动回滚事务,要注意必须在finally中作处理,如下图;
03
第三类:数据丢失问题。
数据丢失或者变异通常发生在异步处理的场景中,同步场景中几乎不会发生,简单的调用关系如下:
主要有三类情况会发生数据丢失的问题。
源系统调用接口或发送消息时数据丢失,造成这类问题的原因,包含但不限于以下情况:
(1)MQ服务器磁盘空间不足、宕机等;
(2)断网、网络波动等;
常用的解决方案(适用于断网、网络波动、目标系统服务异常时的场景):
(1)源系统调用接口或发送消息时,记录日志到ELK--以后排查问题的时候用
(2)源系统接口调用/发送失败时消息时:如果首次执行失败,每隔10s,再次调用/发送,直到调用/发送成功;连续3次调用/发送失败,将接口调用/发送消息存入本地消息表,通过定时任务补偿机制,在业务空闲时重试;重试执行成功后,维护更新本地消息表中执行状态或清除本地消息表中的数据;
数据传输过程中数据丢失造成这类问题的原因,包含但不限于以下情况:
(1)单次调用接口请求/发送消息 数据量过大;
(2)MQ服务器磁盘空间不足、宕机等;
(3)断网、网络波动等;
(4)黑客、软件劫持网络;
上述 2、3、4 为小概率事件,一般情况,主要精力还是投放在程序代码上面。
常用的解决方案:
(1)请求数据分页,每页不超过200条(网络、服务器较差的环境,分页需要拆的更小);
(2)对MQ服务器进行监控;
(3)通过架设高可用的网络,来提高网络质量;
(4)防火墙、WAF等安全设备;
目标系统接收到数据,处理过程中丢失数据(重点关注)造成这类问题的原因,包含但不限于以下情况:
(1)目标系统接收数据后急于直接进行业务逻辑处理;
(2)目标系统大事务;
(3)目标系统数据库死锁;
(4)目标系统接口性能问题;
……
常用的解决方案
(1)目标系统收到数据后,记录日志到ELK--以后排查问题的时用
(2)目标系统收到数据后:第一步:将数据落入本地消息表;第二步:然后直接返回源系统已收到数据的请求;第三步:异步处理收到的数据;第四步:调用源系统补偿机制接口告诉数据处理结果;--需要源系统配合提供补偿机制接口,第五步:异步维护本地消息表中的数据处理状态
04
第四类:数据重复问题。
在高并发或者用户快速点击页面的情况下,有时候会造成数据的重复提交,特别是在新增事务的场景中,比如基础数据重复提交、订单重复提交、扫描枪快速多次扫描上报数据等。
解决这类问题,可参考秒杀系统设计原理,作如下处理:
1、按钮置灰,禁止用户重复提交请求;
2、TF技术:通过JS在一定时间内只能提交一次请求;
3、Redis标志位策略:首次请求时,在Redis中创建一个标志位,然后执行业务代码;
再次请求时,到Redis上查看这个标志位是否存在,如果存在,拒绝请求;如果业务代码执行完毕,删除Redis中的标志位;
4、 关注接口的幂等性验证测试;
05
相对于功能测试,技术类的缺陷需要测试人员关注业务的技术实现,因为这些问题比较难直观地反馈到页面上,但是出了问题,影响范围又相对会比较广。所以需要测试人员具备一定的技术视野,去了解研发实现,从技术层面提出相对应的测试策略,提升自己的价值。
你,平时会注意到这些问题吗?
PS:因为涉及保密问题,所以本文所提到的场景均没有给出案例,但思路和解决方案都是可落地的,仅供参考。
共勉。