我们之前给大家分享过一些高并发的性能测试场景的案例以及解决方案,今天小编来带大家见识一下之前那份技术方案具体的实施过程,以及前端、后台服务器的交互情况。

如下图1是前端限制单台设备登录的示意图:

性能测试

 

客户抢购过程中,从多个层级模块对认购请求进行限流削峰处理,整体流程图如图2所示,如下图2是抢购流程图

PR

 

性能测试技术方案包括如下几个步骤:

1.前端控制用户点击抢购按钮的频率,每一次点击之后都出现一个蒙层或倒计时,对抢购按钮禁用一段时间,之后才允许C端用户再次点击按钮发起抢购请求;

2.服务器端对来自于客户端的请求做合法性校验,判断用户token是否有效,判断请求参数中的签名值是否正确(即图3中后端模块第二步),判断活动是否已经开始,从缓存获取客户信息,校验用户是否具有抢购资格,对不合法的请求全部拒绝并返回失败结果;

实施

 

3.获取用户频率锁,若成功获取,则进行后续判断,否则认为用户访问频率超限,使缓存中存储的用户token失效,给客户返回失败结果,并提醒用户重新登录;

4.获取对应房源的分布式锁,若获取失败,则认为该房源已售,返回失败结果;若获取商品锁成功,则认为本次抢购成功,返回成功结果;

5.客户抢购成功后,请求数据会推送给Kafka消息队列,并进行后续处理;

6.消费Kafka队列中的记录,发送抢购成功的通知短信给用户,将成交数据持久化到数据库,通过WebSocket实时传递成交记录给B端投屏页面。

在这个过程中,用户频率锁和商品锁都是通过Redis分布式非阻塞锁实现,只尝试一次,不阻塞等待。前端所使用的静态资源文件,通过CDN获取,避免对业务服务器的直接访问;服务器热点数据,如活动描述、活动须知等数据,存储在进程本地缓存中,以此提高程序响应速度。 抢购成功之后使用Kafka消息队列异步进行后续处理,包括写入订单到数据库、发送抢购成功的提醒短信、推送实时消息给B端前台投屏页等操作,既减少了客户的等待时间,也减轻了服务器和数据库的平均压力。

简单总结一下上述过程中涉及的防刷及防作弊策略。前端会对客户点击抢购按钮的频率作限制,正常情况下不会出现某客户请求频率过高的情况;客户的登录请求在nginx进行反向代理时会经过lua脚本的处理,对于请求过于频繁的可疑ip进行一段时间的封禁处理,拒绝其请求;抢购过程中,对于频率过高的用户请求,会被认为是作弊,返回失败结果,强制其下线。

同时,对于请求是否来源于真实客户端,进行前后端联合检验:校验逻辑包括前端模块和后端模块。其中,前端模块通过页面直出数据获取到用户的初始校验值,用户进行抢购操作时,对某些特征数据以及用户初始校验值进行加密运算,加密后的字符串作为签名传递给后端接口,之后前端按照某种方法对校验值作变换;后端模块收到请求后,首先对校验值按照与前端相同的方法进行变换,存入缓存,等待下一次的前端请求;

然后对请求特征数据以及原先的校验值进行与前端相同规则的加密运算,判断前端签名的值与后端计算的值是否匹配,匹配则继续进行后续处理,不匹配则返回失败结果。这种联合校验的方式减少了使用工具作弊的可能性,在增加作弊难度的同时保持了良好的用户体验。

分流角度来说,项目后端服务集群部署,客户端请求经过多层负载均衡,均匀地分散到各个应用服务器,各服务器共同分担计算力;IO层面,数据库进行读写分离,读请求和写请求分散到不同数据库,增加数据库承载能力。某些服务进行单独部署,如获取验证码、发送短信、发起支付等,这样一来,压力分摊在不同的微服务上,避免压力过于集中导致的服务器崩溃。

综上所述,通过多层级模块的防刷限流削峰处理,以及后端服务负载均衡,有效降低了性能测试过程中服务器和数据库的负载压力,使得项目能够在资源有限的情况下,在短时间内承受大量的并发请求,极大地增加了服务器的吞吐量。同时通过对用户访问次数的前后端校验,能够快速识别作弊请求,保证了活动稳定、公平地进行。