本文来自网易云社区

作者:刘静媛

前言  

从事金融业务领域的测试工作过程已经有半年时间了,在此期间遇到了各种类型的问题,个人认为在日常测试工作中,特别是涉及资金的业务领域内,测试人员需要格外关注的方面有:系统的并发问题、幂等问题、性能问题及资损风险等。下面就是这段时间以来,在并发问题和幂等问题上站在测试角色上的一些积累和总结。

一、并发问题  

1、什么是并发?

并发(Concurrency)是指系统在同一时间段内,同时执行多个计算程序。为了更好的解释并发的概念,引入并行(Parallelism)概念来进行对比分析。

下图较为形象的给出两者的工作机制:

在多个线程同时工作时,单个CPU硬件环境下不可能真正同时的有多个线程在工作,此时并发机制实际上是将CPU的运行时间划分成若干时间段,不同的时间段交由不同的线程使用,而其他线程此时属于挂起状态。在多个CPU的硬件环境下才有可能实现多个线程真正的同时工作。

2、并发与并行特点

并发 并行
宏观层面同时执行 严格的同时执行
解决多个不相关的任务 一般解决同一个任务
资源和数据共享 资源和数据隔离
单、多处理器均可 必须多处理器
彼此需要交互通信 不需要交互通信
重点是组合协调 重点是执行

3、并发的优缺点

优点:

(1)提升资源利用:这个优点是最容易理解的,多线程并发可以提升cpu的利用率,比如在一个线程等待磁盘IO资源时,CPU可以去执行另外的任务。在任务量大的情况下,并发机制能够明显减少系统耗时。

(2)模型边界清晰:能够并发的任务,应该是尽量没有依赖关系的,是相互独立的,能够同时执行而不相互影响的。例如设计一个文件处理器,就可以使用多个线程,每个线程负责一个文件的读取和操作,在多个线程同时工作时,对每个文件的操作是相互独立的。

(3)异步事件响应:在处理异步任务时,并发编程的优点更是显而易见的,它能够避免单线程情况下资源闲置和过度等待。建立单独的监听器,在得到异步响应时随时处理响应,高效合理的利用系统资源。

缺点:

(1)安全风险:由于同一进程下的多个线程会共享地址空间和数据,而多个线程访问资源的顺序具有不确定性,因此在多线程并发时容易出现脏读、幻读等问题。(线程安全)

(2)活跃度风险(饥饿、死锁、活锁)

(3)性能风险:线程频繁调度切换同样会带来资源浪费。

(4)分析、编程和测试复杂

4  、并发编程常见的应用场景

定时任务、分布式任务、WS服务、Servlet、异步消息

多见于:多进程并发、集群中机器之间并发

5  、并发安全措施

数据库行级锁:悲观锁,乐观锁

全局分布式锁

应用同步和锁机制:——Synchronized\CAS;——java.util.concurrent.locks;——java.util.concurrent.atomic

使用线程安全的容器:java.util.concurrent

6  、测试角度看并发问题:

6  .1 难分析、难测试:

有些并发问题,是很难在平时测试过程中发现的,特别是系统底层存在的并发问题,例如:

缓存更新设计不合理导致的脏数据问题——如果缓存更新的设计模式是先清除旧的缓存再更新数据库,首先这个设计是不合理的,排除设计的正确性不谈,如果在测试人员不了解缓存更新策略的情况下,执行上层业务层面的并发测试,有很大的概率是在测试过程中并没有出现问题,但是仔细分析一下,在一个外部条件触发了缓存更新的同时,有可能出现另外两个并发操作:一个更新,一个查询。在删除缓存后,有一个查询操作访问缓存没有命中,会去查数据库,并把数据库中老的数据放进缓存中,同时更新操作会更新数据库。这样导致缓存中的数据一直是老的数据,是脏数据并且会一直脏下去。而在现实测试过程中,缓存的更新以及查询操作都发生的非常之快,很难人为造出类似或者更为复杂的并发场景。

6  .2 难定位、难复现:

大家在开发测试过程当中可能都会遇到的一个场景就是在多次执行同一个操作时,不定期的会有一个操作是执行失败了,很难找到失败的规律,测试同学提bug时也会很难再复现出bug并保留现场给开发人员排查。甚至此类情况直接出现在了生产环境,用户反馈说操作失败,但是更难说清楚在什么情况下会失败。这种问题发生的原因可能是多种多样的,可能是多线程设计的漏洞,也可能是系统交互的异常情况欠考虑引起的。当遇到这种情况时,靠碰运气和多次尝试是很笨拙的方法,关键还是分析出可能存在的并发问题,再有针对的尝试验证,确定是某种原因并分析解决后,再进行并发尝试,看是否还存在问题。

6  .3 预防和发现手段:

a.业务场景分析:实际应用场景下某功能是否会出现并发情况,对于会出现并发情况,重点关心代码设计,并准备做并发测试。

b.静态代码分析:可以借助工具   Contemplate's   ThreadSafe Solo,参考  http://www.contemplateltd.com/threadsafe

c.并发测试的注意事项:

(1)不放过偶发的错误和失败

(2)做好测试分析,完成非并发的功能测试后,针对测试分析时分析到的容易出并发问题的部分做独立的并发测试

(3)并发测试时,注意并发测试设置的并发线程数需要做到可调节,通常要大于CPU数量


二、幂等问题

1、幂等的概念

幂等来源于数学概念:单目运算中,x为某集合中的任意数,f为运算子,如果满足f(x)=f(f(x)),那么f运算就是幂等的。

幂等性是系统接口的一种承诺,承诺只要调用接口成功,多次相同的输入会有相同的结果反馈和等同一次处理的影响力。声明为幂等的接口会认为外部调用失败是常态,并且失败后必然会有重试。

2、引发幂等问题的常见原因

用户重复提交——非常容易发生,前端、后端均需要控制

网络重发——容易遗漏,但有可能发生

消息重发——容易遗漏,但有可能发生

系统间重试——需要根据业务情况来判断是否需要重试,哪些情况哪些系统需要重试

3、幂等问题的控制关键

在设计资金的系统中,幂等问题有着十分重要的地位,比如我们定义一个接口withdraw

bool withdraw(accountId, amount)

withdraw的语义是从accountId对应的账户中扣除amount数额的钱;如果扣除成功则返回true,账户余额减少amount;如果扣除失败则返回false,账户余额不变。

一种典型的情况是withdraw请求已经被服务器端正确处理,但服务器端的返回结果由于网络等原因被丢掉了,导致客户端无法得知处理结果。如果是在交互设计或者前端展示上处理的不够好,用户会以为这次操作执行失败,然后刷新页面或者重复提交请求,这就导致了withdraw被调用两次,账户也被多扣了一次钱。整个过程如下图所示:

为解决此问题,需要对接口进行幂等性改造,增加一个唯一ID参数,如:

bool idempotent_withdraw(uniqId,accountId,amount)

这个ID需要全局唯一的标识一次请求,客户端的同一个业务请求只有一个uniqId,服务端在收到请求后去检查一下是否已存在这个   uniqId并且执行成功了,如果执行成功就不会再处理第二次的调用请求,如此就避免了重复扣款的问题。

总体而言,在技术实现上,控制幂等问题的关键在于唯一键+状态机。

首先,调用者在请求中携带一个唯一ID,这个ID唯一的标识一个工作单元,这个工作单元只允许被成功执行一次。

其次,接受者在收到请求,获得唯一ID时,要先去查询这个ID所标识的工作单元是否被执行过。   检查是否执行的逻辑通常是根据唯一请求ID ,在服务端查询请求是否有记录,是否有对应的响应信息,如果有,直接把响应信息查询后返回;如果没有,那么就当做新请求去处理。

4、测试角度看幂等

(1)需要更多的关注业务性质和产品设计上,是否需要做到幂等,是时间维度的幂等还是空间维度的幂等。

(2)接口的幂等测试一定不能遗漏,由于幂等场景相对容易制造出来,幂等测试的难度远远小于并发测试,因此在做接口测试时不妨对每个接口都思考一下是否需要幂等,需要的话就测试一下其幂等性

(3)业务场景,特别是涉及到资金流动的业务场景,对失败重试机制一定要慎重。

网易云大礼包:https://www.163yun.com/gift

本文来自网易云社区,经作者刘静媛授权发布

相关文章:
【推荐】 SpringBoot入门(五)——自定义配置

测试角度的并发和幂等问题总结相关推荐

  1. WEB网站压力测试方案 压力测试如何换算并发用户数

    http://wenku.baidu.com/view/bedf1a93daef5ef7ba0d3c29.html 压力测试通过确定一个系统的瓶颈或者不能接收的性能点,来获得系统能提供的最大的服务级别 ...

  2. 从测试角度对测试驱动开发的思考【转】

    测试驱动开发(TDD)是极限编程的重要特点,它以不断的测试推动代码的开发,既简化了代码,又保证了软件质量.本文主要从测试角度出发,从需求分解等四个阶段阐述了测试人员在测试驱动开发中所发挥的促进作用 大 ...

  3. 通过压力测试提升服务器并发性能实例

    前言 前一段时间应领导要求,对公司服务端代码进行简单的压力测试.测试发现,并发数只能维持在很小的值以内,比如模拟并发数超过100,失败率就会大大提高. 在咨询完后端搭建过程后发现,基本上所有的配置参数 ...

  4. 测试角度:如何看待三星大量手机系统崩溃并数据丢失事件?

    5.23日早上凌晨的时候,大量网友反馈:三星手机出现震动并屏幕闪烁现象,无限重启,然后造成手机系统崩溃.死机并乱码,大量数据被丢失! 在事故发生的当天中午,三星公司已发表声明,承认该问题事件的发生,并 ...

  5. 测试角度学安全测试之burpsuite--intruder之暴力破解

    命运对勇士低语,你无法抵御风暴:勇士低语回应,我就是风暴! 主要是基于测试角度去理解,需要的功能,本文通过intruder模块的暴力破解,实现验证码攻克.入侵模块的原理是根据访问链接中存在的参数/变量 ...

  6. jmeter压力测试动态修改并发参数

    Apache JMeter 是 Apache 旗下的开源压测工具,创建于 1999 年初,迄今已有超过 20 年历史.JMeter 功能丰富,社区(用户群体)庞大,是主流开源压测工具之一. 性能测试通 ...

  7. 【高并发】——幂等的实现方案

    一.背景 我们实际系统中有很多操作,是不管做多少次,都应该产生一样的效果或返回一样的结果. 例如: 1. 前端重复提交选中的数据,应该后台只产生对应这个数据的一个反应结果. 2. 我们发起一笔付款请求 ...

  8. 从单核CPU系统角度看并发问题

    1,问题引入: 在单核cpu系统中:进程有个全局量 int g_i = 0,在进程中开10个线程,每个线程都不对 g_i 加锁的情况下做1亿次自增操作 (g_i++) :主线程等待所有的线程结束后,再 ...

  9. 如何测试系统的并发量

    前因 博主上周刚面试了一家恒生系的公司,貌似是恒生全资子公司,叫啥**云融.反正总结就是一个字,菜.为什么博主要攻击他呢,这其实是有缘由的. 因为博主在做他家的笔试的时候,系统崩溃了,(笔试可能才几百 ...

最新文章

  1. 近世代数--整环的商域--整环D扩充为域Q
  2. Hibernate逍遥游记-第2章-使用hibernate.properties
  3. shutil模块、json和pickle模块
  4. k均值例子 数据挖掘_人工智能、数据挖掘、机器学习和深度学习的关系
  5. dataset__getitem___【小白学PyTorch】3.浅谈Dataset和Dataloader
  6. RHEL7.0时间同步设置
  7. 为什么mvc里面的ModelState.IsValid一只都是true
  8. 固定字符结尾的正则_新手上路:图文解读助你理解和使用正则表达式
  9. EOS主网上线,如何在Imtoken里导入EOS钱包?
  10. 计算机操作系统第六章测试题及答案
  11. javascript的apply理解
  12. SylixOS中的中断服务对象
  13. esp32 s3 外部flash和外部psram配置
  14. postgres 导入纯文本数据txt
  15. 51单片机简单计时器
  16. Intel 82576网卡
  17. 提高农业品牌互联网曝光度的“四个一工程”
  18. 苏州企业申报2019年高新技术企业财务工作如何开展
  19. android qq版本6.6.1,手机QQ6.6.1有哪些更新内容 手机QQ最新版本详细介绍
  20. 易开发易投产的51单片机时钟计时器:番茄时钟——TFT彩屏显示方案

热门文章

  1. 开篇有益-解析微软微服务架构eShopOnContainers(一)
  2. js图表控件:highcharts的应用(二)
  3. Lighttpd 配置与性能优化
  4. 03-MySQL多表操作
  5. 银行启动开放战略,能否赢回金融科技下半场?
  6. 详细的多维度测评,看看哪个 Python 版本速度最快!
  7. ms sql 主键自动生成32位guid
  8. memcached 缓存服务器
  9. BIND 子域授权的实现和区域转发实现
  10. 在Visual Studio 2012中使用VMSDK开发领域特定语言(一)