当前位置: 首页 > 后端技术 > Node.js

千亿流水背后,前端工程师如何做好“资金流失防控”?

时间:2023-04-03 19:38:08 Node.js

前言资金损失——顾名思义,是平台与用户或客户的心理预期不符,直接或间接造成经济损失的场景。长期以来,我们的生产环境存在资金流失问题,而且随着企业规模和版图的不断扩大,经济损失规模也不断扩大,直接对企业造成了非常恶劣的影响。平台、客户和用户。影响。尤其是在一定时期内,资金流失风险高的问题连续出现,严重程度上升到集团化程度,对平台的生产经营产生了较大的负面影响。因此,大家非常重视资金流失风险的防控。本文希望通过我们的思考和淘喜双十一的实践,为大家提供一些资产流失防控的经验参考,也欢迎大家提出宝贵意见。(更多干货内容请关注【淘系技术】公众号,每日更新阿里工程师技术干货)探索之路在资金流失防控方面,服务端起步早于前端,而且也很专业,比如各种离线或者实时的容灾幂等检查,链路协调告警,关键配置检查,关键标准检查等等。但是,就前端而言,技术部门阿里巴巴淘系的负责人是从2019年双11前夕才开始关注前端资产保护的,所以一年前还没有产品化的计划。问题总结、问题界定、程度分级、红线划定,通过一些规章制度、学习和考核手段,通过一些人工盘点、盘点等人工演练方式,强化资产损失防控的文化意识。casebycase规避资产流失风险,确保业务稳定。比如下面就介绍一下手工排练这种非常直接的原生方法。由于人工排练缺乏产品化手段,去年双11、双12等大促,前端采用人肉盘点和人工排练的方式进行保障。我们分析了前端所有可能出现的资金损失风险点,制定了一套专属于前端资金损失的规章制度和风险代码,并围绕这些资金损失风险点,盘点了所有的资金损失风险点。参与双11的业务前端代码,对损坏问题的识别、预防、止血、恢复进行详细的人工演练。印象中,2019年双11,前端C端资产流失防控一共进行了6天,每天2场(下午和晚上),平均每场3.5小时会议,约有4名评委。共进行73次预演,每次预演约15分钟,最少参与2次彩排,平均总人力成本为200小时(换算为25人日)。这个数字和双11整体的人力投入水平相比,也是非常恐怖的。通过上述方法,我们实际上在过程中提前发现了一些资金损失风险问题。虽然最后每次大促线上都没有出现资金流失的问题,但是这种土办法在过程中消耗了大量的人力和时间。控制效果完全取决于评委当时在现场的审阅效果。可见,人工排练方式不仅耗费时间和人力,而且防护效果有??限,不宜作为长效防控方式。因此,我们正在探索和准备用一些产品化的手段来解决防控效果和成本的问题,我们做了以下尝试。如前所述,前后端对账受限于人工排练方式的成本和防控效果。去年双十二之后,我们开始尝试资金流失防控的产品化设计。从以往股权营销活动中的资金流失案例来看,当消费者看到的股权信息与账户实际收到的股权信息不一致时,很容易引发大量客户投诉。例如:一短视频商家在发放福利时,消费者收到成功单品的优惠券时,误发红包;某发红包商家误将红包列表界面作为中奖结果表达方式,发现时长长达10.5小时。对于上述权益信息前端展示与后端分布不一致的情况,及时监测报警对于止血控制资产损失规模至关重要。为此,针对类似问题,我们针对业务产品的生产阶段,设计了一套前后端对账的产品化解决方案。前后端对账整体思路如下:对账解决方案涉及采集层统一接入、实时数据处理对账、告警订阅。页面侧采集权益关键信息;数据层:基于Blink,实时处理数据,存储在SLS日志和METAQ消息中,通过后端平台订阅日志消息,实时对账;应用层:订阅权益对账消息,通过实时告警流程,通过SLS日志查看权益实时行情和模块治理。但是在项目上线一段时间后,我们发现效果并没有达到预期:一方面,由于前端SDK对业务代码有些侵入,各方业务仍然存在较多或者在接入前后端对账时会产生一定的成本。尤其是一些稳定的老线上业务,在转型过程中很容易引入新的问题;另一方面,前端SDK采集的权益信息无法从UI展现层直接识别出来(可能会被截断),发现的问题都是各方业务开发同学前后端权限不一致导致的误报。从实际表现来看,我们原本希望通过前后端对账的方式,及时发现业务产品前端权益表达与业务交付过程中的不一致。生产阶段。但是这个方案没有UI的好处,前端的Point字段、问题发现率低、一定的访问成本等都不能满足我们的需求。只能继续探索其他的资产流失防控手段。因此,我们将目光聚焦在业务产品的研发阶段,看看能否从产品的研发阶段探索出一些防止资金流失的商业手段,于是做了如下尝试。静态代码扫描在尝试了前后端对账方案后,我们开始重新思考:人工排练的方式可以帮助我们发现潜在的资产损失风险,但主要问题是需要大量的人力和时间成本,那么为什么不如何降低这个成本呢?为此,我们从代码的CcdeReview过程中探索出一种基于AST(AbstractSyntaxTree,抽象语法树)的前端代码静态扫描方案,可以避免金额计算、数字欺诈、数字歧义、文案过期等问题在某种程度上。等问题。本机替代人工CodeReview,不仅节省了人工成本,也为CR的质量提供了标杆保证。静态扫码的整体方案如下,其背后的具体原理介绍如下。AST在计算机科学中,抽象语法树(AbstractSyntaxTree,AST)或简称句法树(Syntaxtree)是对源代码语法结构的一种抽象表示。它以树的形式表示编程语言的语法结构,树上的每个节点代表源代码中的一个结构。这是维基百科对AST的解释。我们来看一个简单的代码例子?AST转换:如上图,代码片段varstr="helloworld"被拆解成多个部分,最后最终以树的形式表示出来(如果想查看更多源码对应的AST,可以使用神器astexplorer在线试用)。扫码的基础是基于对仓库代码的AST解析遍历。为此,我们需要使用Babel来完成这部分工作。BabelBabel实际上是一个JavaScript编译器,主要用于旧浏览器或环境将ECMAScript2015+代码转换为向后兼容版本的JavaScript代码。简单来说,为了将ES2015+代码转换为向后兼容的版本代码(如ES5),Babel每次都需要将源代码解析成AST,然后修改AST使其符合ES5语法,最后重新生成代码。总结起来,有3个阶段:parse->transform->generate。从上面可以看出,Babel不仅完成了AST的解析工作,而且由于其编译js代码的使命,还提供了一套完整的访客插件机制进行扩展。关于“HowtocustomizeBabelplugins”,你可以查看这个Babel插件手册。根据手册,我们可以使用如下代码添加自定义规则来完成扫码任务:自定义规则介绍完AST和Babel,我们再回到资产丢失防控的问题上。根据以往经验,前端容易造成资金流失/舆论的代码往往包括:金额赋默认值、金额数字化计算、固定金额/点数到期、限时文案。..因此,我们可以根据以上案例自定义规则来编写Babel插件。以“amount被赋予默认值”为例,我们可以在日常代码中列出一些badcase,然后使用astexplorer分析其AST,最后有针对性地编写匹配规则。case1:直接赋默认值根据上面代码vsAST关系图,我们可以看到,我们只需要找到VariableDeclarator节点,并且满足id是amount变量,init是大于0的value节点这两个条件代码如下:case2:ES6解构语法赋默认值观察上面的关系图,我们可以得出一个结论:找到AssignmentPattern节点,同时满足两个条件,剩下的是一个amount变量而right是一个大于0的值节点,代码如下:case3:"||"运算符赋默认值上面的规则也并不复杂,但需要注意一点:在实际代码中,=右边的赋值表达式可能要复杂得多,甚至包含一些逻辑运算。因此,我们需要改变策略:遍历右边的赋值表达式是否包含“||正数”模式。代码如下:通过上面的三个例子,我们已经可以扫描出大部分“赋值金额默认值”的代码了。其他一些场景也是如此,只要根据代码生成的AST找到规则,然后编写相应的Babel插件即可。小结然而,静态代码扫描工具虽然可以帮助我们发现一些代码层面的共性问题,但是它们对不同的业务逻辑仍然不敏感,所以很难挖掘出代码中的深层次问题。因此,在面对UI、多态、复杂交互逻辑等场景时,单纯的静态代码扫描并不足以彻底解决问题。因此,在第一个保护流程之后,我们设计了第二个保护流程,下面详细介绍。根据UI测试扫描,基于之前的资金流失失败,问题多出现在改代码的时候。开发同学的新变化影响了业务原有的功能,测试同学只是没有回到这一点。对于考生来说,每次全业务返还的工作量巨大且重复。以收红包为例。不同账户(人群)、成功收款、网络超时、重复收款、不合格、服务失败等都是通常需要考虑资金损失的测试用例。这时候如果有一个UI自动化回归测试工具,不仅可以为业务提供保障,也可以解放测试同学。而传统的UI自动化测试需要开发者编写相应的自动化测试代码,不仅有上手成本,还会产生额外的工作量。为此,我们提出了一种基于录制/回放的UI测试扫描方案:开发/测试同学只需要提供一个可以正常访问的页面地址,正常的功能测试会被录制成测试用例,项目发布时执行。回放一次页面,最后通过对比UI测试用例的快照来判断功能回归是否通过。UI测试扫描的整体思路如下:其背后的原理介绍如下。页面代理代理页面本质上是一个web服务,通??过url参数接收原始页面链接和注入脚本地址,服务器请求原始页面返回相应的html文档,并注入接口拦截脚本、调试工具脚本和从url参数中获取的自定义注入脚本。代理页面和原页面有相同的html,同时也会加入原页面的query参数。直接访问代理页面时,除了js的location变量外,其他环境和原始页面几乎一样。至于location变量,我试了很多方案,发现都改写不了。一旦页面被重写,它就会跳转。在多次尝试无果后,我们发现我们可以用不同的方式解决这个问题。由于我们无法重写它,所以我们替换了它。我们把页面中所有的script脚本都包裹了一层with,如下图,我们重写了页面中所有js脚本的上下文,让读取的位置被我们重写,从而实现渲染并且代理页面的运行结果与原页面效果一致。录制脚本通过上面提到的页面代理,我们可以在访问原始页面时注入我们的录制脚本。为了支持页面的播放,记录时必须提供两条数据:记录过程中产生的所有网络访问数据用户操作数据(包括点击、滚动等)记录网络访问数据并不难,这这里就不展开多说了,可以借用AOP的思想,在网络请求的回调中添加一个拦截器,同时保存本次请求的url、param、response,让它们可以在播放过程中进行匹配和使用。下面看看如何劫持用户的操作数据。其实在h5页面中,用户的任何触摸操作都会依次触发onTouchStart、onTouchMove、onTouchEnd事件,所以我们只需要拦截这三个事件对应的targetEvent参数即可。以onTouchStart的拦截为例:如上所示,我们记录了触发事件的事件类型、节点选择器、时间戳、页面距顶部的高度、坐标位置等信息,所有这些都是播放的必要数据。再来看页面的滚动拦截,劫持onScroll事件即可。不过,这里要注意一点,页面滚动有两种:一种是手指接触屏幕时的拖动,一种是手指离开屏幕后的惯性滚动。前者会同时触发onTouchMove和onScroll,后者只会触发onScroll。回放脚本回放脚本同样依赖于代理页面的注入能力,但它的作用与录制脚本恰恰相反:拦截请求,使用录制时录制的网络数据mock依次派发touchEvent事件。同样,拦截请求和记录的原理也大致相同。一致,根据本次请求的请求参数,从记录时截获的数据中找到对应的匹配即可。让我们看看如何根据时间调度touchEvent事件来模拟播放。核心代码如下:派发事件是基于dom的dispatchEvent方法。可以参考MDN文档。代码如下:快照对比及难度分析。以及播放的最后一帧快照,所以接下来我们希望设计一套算法来自动判断这两张快照的内容是否一致。从不同的输入案例来看,我们主要面临以下难点:相同的文字在不同型号的手机上会以不同的字号显示,像素级比较会误判相同的文字不一致。对于红包等弹窗图片,只需要关注红包弹窗中的信息是否一致即可,不相关的背景会导致模型误判。由于回放/录制不能保证时间戳的严格一致性,所以两张快照在位置上往往存在位移偏差。算法设计的整体算法流程如下图所示。下面一步步讲解算法思路。首先计算两个快照的SIFT相似度进行初步筛选。匹配的核心问题是对同一目标在不同时间、不同分辨率、不同光照、不同方向的图像进行匹配。图像的局部特征对于旋转、缩放和亮度变化保持不变,对于视角变化、仿射变换和噪声也保持一定程度的稳定性。两个相似度低于阈值的快照被判定为失败,通过的快照将被进一步细化比较。对于弹窗图片,需要提前去掉背景等无关信息,只保留弹窗信息。这里,首先将图像从RGB空间转换为LUV空间。L分量会保留图片的亮度信息,方便根据亮度值对图片进行二值化处理,去除无效背景。效果如下。将预处理后的干净图片送入OCR(光学字符识别)模型,提取文字内容和对应的坐标信息。删除像素太小的文本信息往往是噪声产生的错误信息。根据返回的坐标信息还原文本的位置,方便下一步进行内容比对。比较上一步产生的结果内容,在图上将两个快照不一致的地方标记为输出,算法结束。效果演示失败:.jpg")通过:.jpg").jpg")总结确实,我们改变了传统的通过UI扫描工具编写UI测试代码的方式,测试同学只需要记录一个功能测试时copy测试用例就够了,既减少了测试同学自动化的学习成本和回归的时间成本,又为每一次业务发布提供了自动化回归保障。不过,在这个双11战线——端防御工作实际落地但是,我们还是遇到了一些问题:UI测试扫描目前只支持h5,与淘系中其他一些前端技术栈(如weex、直播、小程序等)不兼容。),导致这些业务只能人工审核虽然我们对快照比对算法进行了优化,但在实际应用中还是会遇到一些由于算法判断不准确导致的误判,因此我们会继续优化快照比对算法,进一步提高准确率的判断准确性。目前的snapshot比对只验证了录制和回放的最后一帧(也就是最终状态),没有使用大量的中间状态信息,从而失去了过程的验证。因此,我们未来会考虑引入视频比对算法,实现真实录制/回放全比对。基于目前的页面代理机制,录制功能只支持当前页面的操作录制,无法覆盖页面跳转的测试用例。因此,我们将继续升级页面代理和录制/播放脚本,以支持链接级别的测试用例覆盖。上面遇到的这些问题,都是我们未来要持续关注的挑战。总结与展望如上所述,淘系的前端防御工作在一年内悄然发生了变化,从最初的人工排练到现在的三种渐进式产品化防控方式:水平静态扫描分析的资金流失风险问题做出了第一个产品化的防控手段——资金流失/舆情风险扫码工具;【产品化】针对UI、多态、复杂交互逻辑等针对层级分析识别出的资产流失风险问题,我们与测试团队合作实施了第二种产品化防控方式——资产流失/舆情风险UI测试扫描,对比UI测试用例快照,防范资产丢失风险;【背景方案】对于上述产品化方式无法覆盖的特殊场景,暂时依赖人工预演作为自下而上的保障方案。与去年的双11答辩工作相比,今年我们依靠上述方案,甚至取消了人工排练。排练也从去年需要准备相关文件(比如止血方案、预案等)变成了今年录制UI测试用例。准备时间成本几乎持平,却大大节省了参与排练的时间;此外,今年的预防效果也好于去年,重点更突出,保障组合更全面。当然,目前的这些方案只是预防措施,不能100%保证线上不会出现资金亏本的故障。大家对京城防卫的态度,不能掉以轻心。在接下来的工作中,考虑到目前的防御方案只能预防代码缺陷,在产品设计、运行配置等方面还没有实质性的防控手段,所以我们会在链路层面跟进,防控措施在生产环境和运行环境,以及一些告警和自动止血机制的建设,为平台保驾护航。(更多干货内容请关注【淘科技】公众号,每日更新阿里工程师技术干货)