当前位置:首页 > 公众号精选 > 架构师社区
[导读]最近,因为增加了一些风控措施,导致新人拼团订单接口的QPS、TPS下降了约5%~10%,这还了得!

作者:浪漫先生

来源:uejin.im/post/6854573218322513933



# 前言


最近,因为增加了一些风控措施,导致新人拼团订单接口的QPS、TPS下降了约5%~10%,这还了得!


首先,快速解释一下【新人拼团】活动:


业务简介:顾名思义,新人拼团是由新用户发起的拼团,如果拼团成功,系统会自动奖励新用户一张满15.1元减15的平台优惠券。这相当于是无门槛优惠了。每个用户仅有一次机会。新人拼团活动的最大目的主要是为了拉新。


新用户判断标准:是否有支付成功的订单 ? 不是新用户 : 是新用户。


当前问题:由于像这种优惠力度较大的活动很容易被羊毛党、黑产盯上。因此,我们完善了订单风控系统,让黑产无处遁形!然而由于需要同步调用风控系统,导致整个下单接口的的QPS、TPS的指标皆有下降,从性能的角度来看,【新人拼团下单接口】无法满足性能指标要求。因此CTO指名点姓让我带头冲锋……冲啊!


# 问题分析


风控系统的判断一般分为两种:在线同步分析和离线异步分析。在实际业务中,这两者都是必要的。在线同步分析可以在下单入口处就拦截掉风险,而离线异步分析可以提供更加全面的风险判断基础数据和风险监控能力。


最近我们对在线同步这块的风控规则进行了加强和优化,导致整个新人拼团下单接口的执行链路更长,从而导致TPS和QPS这两个关键指标下降。


# 解决思路


要提升性能,最简单粗暴的方法是加服务器!然而,无脑加服务器无法展示出一个出色的程序员的能力。CTO说了,要加服务器可以,买服务器的钱从我工资里面扣……


在测试环境中,我们简单的通过使用StopWatch来简单分析,伪代码如下:

@Transactional(rollbackFor = Exception.class)public CollageOrderResponseVO colleageOrder(CollageOrderRequestVO request) { StopWatch stopWatch = new StopWatch();  stopWatch.start("调用风控系统接口"); // 调用风控系统接口, http调用方式 stopWatch.stop();  stopWatch.start("获取拼团活动信息"); //  // 获取拼团活动基本信息. 查询缓存 stopWatch.stop();  stopWatch.start("获取用户基本信息"); // 获取用户基本信息。http调用用户服务 stopWatch.stop();  stopWatch.start("判断是否是新用户"); // 判断是否是新用户。查询订单数据库 stopWatch.stop();  stopWatch.start("生成订单并入库"); // 生成订单并入库 stopWatch.stop();  // 打印task报告 stopWatch.prettyPrint();  // 发布订单创建成功事件并构建响应数据 return new CollageOrderResponseVO();}


执行结果如下:

StopWatch '新人拼团订单StopWatch': running time = 1195896800 ns---------------------------------------------ns % Task name---------------------------------------------014385000 021% 调用风控系统接口010481800 010% 获取拼团活动信息013989200 015% 获取用户基本信息028314600 030% 判断是否是新用户028726200 024% 生成订单并入库


在测试环境整个接口的执行时间在1.2s左右。其中最耗时的步骤是【判断是否是新用户】逻辑。这是我们重点优化的地方(实际上,也只能针对这点进行优化,因为其他步骤逻辑基本上无优化空间了)。


# 确定方案


在这个接口中,【判断是否是新用户】的标准是是用户是否有支付成功的订单。因此开发人员想当然的根据用户ID去订单数据库中查询。我们的订单主库的配置如下:


这配置还算豪华吧。然而随着业务的积累,订单主库的数据早就突破了千万级别了,虽然会定时迁移数据,然而订单量突破千万大关的周期越来越短……(分库分表方案是时候提上议程了,此次场景暂不讨论分库分表的内容)而用户ID虽然是索引,但毕竟不是唯一索引。因此查询效率相比于其他逻辑要更耗时。


通过简单分析可以知道,其实只需要知道这个用户是否有支付成功的订单,至于支付成功了几单我们并不关心。因此此场景显然适合使用redis的bitmap数据结构来解决。在支付成功方法的逻辑中,我们简单加一行代码来设置bitmap:

// 说明:key表示用户是否存在支付成功的订单标记// userId是long类型String key = "order:f:paysucc"; redisTemplate.opsForValue().setBit(key, userId, true);

通过这一番改造,在下单时【判断是否是新用户】的核心代码就不需要查库了,而是改为:

Boolean paySuccFlag = redisTemplate.opsForValue().getBit(key, userId);if (paySuccFlag != null && paySuccFlag) { // 不是新用户,业务异常}


修改之后,在测试环境的测试结果如下:

StopWatch '新人拼团订单StopWatch': running time = 82207200 ns---------------------------------------------ns % Task name---------------------------------------------014113100 017% 调用风控系统接口010193800 012% 获取拼团活动信息013965900 017% 获取用户基本信息014532800 018% 判断是否是新用户029401600  036%  生成订单并入库


测试环境下单时间变成了0.82s,主要性能损耗在生成订单入库步骤,这里涉及到事务和数据库插入数据,因此是合理的。接口响应时长缩短了31%!相比生产环境的性能效果更明显……接着舞!


# 晴天霹雳


这次的优化效果十分明显,想着CTO该给我加点绩效了吧,不然我工资要被扣完了呀~


一边这样想着,一边准备生产环境灰度发布。发完版之后,准备来个葛优躺好好休息一下,等着测试妹子验证完就下班走人。然而在我躺下不到1分钟的时间,测试妹子过来紧张的跟我说:“接口报错了,你快看看!”What?


当我打开日志一看,立马傻眼了。报错日志如下:

io.lettuce.core.RedisCommandExecutionException: ERR bit offset is not an integer or out of rangeat io.lettuce.core.ExceptionFactory.createExecutionException(ExceptionFactory.java:135) ~[lettuce-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]at io.lettuce.core.ExceptionFactory.createExecutionException(ExceptionFactory.java:108) ~[lettuce-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]at io.lettuce.core.protocol.AsyncCommand.completeResult(AsyncCommand.java:120) ~[lettuce-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]at io.lettuce.core.protocol.AsyncCommand.complete(AsyncCommand.java:111) ~[lettuce-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]at io.lettuce.core.protocol.CommandHandler.complete(CommandHandler.java:654) ~[lettuce-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]at io.lettuce.core.protocol.CommandHandler.decode(CommandHandler.java:614) ~[lettuce-core-5.2.1.RELEASE.jar:5.2.1.RELEASE]…………


bit offset is not an integer or out of range。这个错误提示已经很明显:我们的offset参数out of range。为什么会这样呢?我不禁开始思索起来:redis bitmap的底层数据结构实际上是string类型,redis对于string类型有最大值限制不得超过512M,即2^32次方byte…………我靠!!!


# 恍然大悟


由于测试环境历史原因,userId的长度都是8位的,最大值99999999,假设offset就取这个最大值。那么在bitmap中,bitarray=999999999=2^29byte。因此setbit没有报错。


而生产环境的userId,经过排查发现用户中心生成ID的规则变了,导致以前很老的用户的id长度是8位的,新注册的用户id都是18位的。以测试妹子的账号id为例:652024209997893632 = 2^59byte,这显然超出了redis的最大值要求。不报错才怪!


紧急回退版本,灰度发布失败~还好,CTO念我不知道以前的这些业务规则,放了我一马~该死,还想着加绩效,没有扣绩效就是万幸的了!


本次事件暴露出几个非常值得注意的问题,值得反思:


  • 懂技术体系,还要懂业务体系


    对于bitmap的使用,我们是非常熟悉的,对于多数高级开发人员而言,他们的技术水平也不差,但是因为不同业务体系的变迁而无法评估出精准的影响范围,导致无形的安全隐患。本次事件就是因为没有了解到用户中心的ID规则变化以及为什么要变化从而导致问题发生。

  • 预生产环境的必要性和重要性


    导致本次问题的另一个原因,就是因为没有预生产环境,导致无法真正模拟生产环境的真实场景,如果能有预生产环境,那么至少可以拥有生产环境的基础数据:用户数据、活动数据等。很大程度上能够提前暴露问题并解决。从而提升正式环境发版的效率和质量。

  • 敬畏心


    要知道,对于一个大型的项目而言,任何一行代码其背后都有其存在的价值:正所谓存在即合理。别人不会无缘无故这样写。如果你觉得不合理,那么需要通过充分的调研和了解,确定每一个参数背后的意义和设计变更等。以尽可能降低犯错的几率。


# 后记


通过此次事件,本来想着优化能够提升接口效率,从而不需要加服务器。这下好了,不仅生产环境要加1台服务器以临时解决性能指标不达标的问题,还要另外加7台服务器用于预生产环境的搭建!因为bitmap,搭进去了8台服务器。痛并值得。接着奏乐,接着舞~~~


免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

为了满足日益增长的数据处理需求,铁威马NAS推出了全新的性能巅峰2024年旗舰之作F4-424 Pro,并搭载了最新的操作系统--TOS 6。这款高效办公神器的问世,无疑将为企业和专业人士带来前所未有的便捷与效率。

关键字: 存储 Linux 服务器

Apr. 23, 2024 ---- 随着节能成为AI推理服务器(AI Inference Server)优先考量,北美客户扩大存储产品订单,带动QLC Enterprise SSD需求开始攀升。然而,目前仅Solidi...

关键字: SSD AI 服务器

在AI需求暴增、5G升级周期和汽车智能电动化等因素的推动下,全球电子市场进入新一轮的增长期,尤其是在通信电子、消费电子和汽车电子等领域。需求增长促使上游产能升级的同时,也带来了制造和设计上更严格的标准,各种电子零部件可以...

关键字: AI 服务器 5G

北京——2024年4月9日 越来越多的企业将关键性的工作负载放到云上,如何确保云上业务的连续性即云的韧性对企业来说就越来越重要。在亚马逊云科技,我们从一开始就在基础设施、服务设计与部署、运营模式和机制中将韧性考虑其中。例...

关键字: 服务器 存储 数据中心

目标应用包括电信设备、服务器和智能表计的电源,以及LED车灯或汽车低压DC/DC转换器

关键字: 二极管 服务器 智能表计

结合ST第三代碳化硅金属氧化物半导体场效晶体管、STGAP隔离驱动器和STM32微控制器技术,此图腾柱无桥式功率因数修正器(PFC)解决方案为一个即插即用的解决方案,满足数据中心之高阶服务器和电信通讯电源设计的需求...

关键字: 数据中心 服务器 碳化硅

康佳特扩展边缘服务器生态系统, 推出 µATX 服务器载板和基于最新英特尔至强处理器的 COMHPC Server模块

关键字: 处理器 服务器 AI

美国加利福尼亚州圣何塞 —— GTC —— 太平洋时间 2024 年 3 月 18 日 —— NVIDIA 于今日推出数十项企业级生成式 AI 微服务,企业可以利用这些微服务在自己的平台上创建和部署定制应用,同时保留对知...

关键字: AI 模型 生成式 AI 服务器

Mar. 7, 2024 ---- 2023年第三季供应商大幅减少产出,使得Enterprise SSD价格有撑,第四季合约价的反弹吸引买家积极购货,加上服务器品牌商需求也随着2024年企业资本支出展望优于去年,进而扩大...

关键字: NAND Flash 服务器 SSD

随着通用人工智能的发展,数据中心的计算需求逐步提高。针对多模态数据、大模型的推理和训练需要更高的算力支持,而随着算力提升与之而来的还需更关注在功耗方面的优化。对于头部云计算和服务厂商而言,针对专门用例提高每瓦性能变得至关...

关键字: ARM 服务器 AI Neoverse CSS
关闭
关闭