前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >干货 | 携程酒店MOCK全链路实践

干货 | 携程酒店MOCK全链路实践

作者头像
携程技术
发布2019-08-15 17:57:00
9350
发布2019-08-15 17:57:00
举报
文章被收录于专栏:携程技术携程技术

作者简介

刘晓攀,携程酒店性能测试负责人,专注性能测试分析和辅助测试工具的开发。

一、前言

Mock在整个软件开发测试周期中已经非常普遍,我们也会经常有意无意地使用它。譬如开发了一段代码,这段代码强依赖了其他服务,在对方服务完成之前,肯定是期望代码能够同步开发。那么在开发的过程中一定会根据约定固定对方服务的返回,这种在代码中的模拟行为,是一种mock。

另外当前很多应用为了提高性能,普遍采用cache的方式。有些cache数据是需要很多database的数据经过一定的逻辑运算得到的,而在测试过程中,为了快速验证测试场景,直接取修改cache数据的方式,也是一种mock。

在当前五花八门的mock方式中,我们希望有一种方便快捷的mock方式,便于开发测试使用,特别是对于多依赖、多变化的场景,更需要mock的协助。否则将需要打通一系列的外部依赖来满足一个场景的需要。

于是,我们推出了mock全链路。mock全链路既是一种mock方式,又是mock在不同阶段的扩展使用。当然 mock全链路还面临着一些些问题,我们将在后面的章节中详细展开。

二、技术背景

技术的进步更多源于底层技术,比如正是由于蒸汽机的发明,才有了现在各式各样的机动车,挖土机,收割机等等,工业上各种技术也有了不同形式的发展。同理,酒店mock也是伴随着基础架构、日志系统的更新换代而不断发展。

mock全链路就是在框架能够完整跟踪应用调用链,指定header在链路上无限透传,ES日志系统大范围应用的背景下产生的 。当然不管mock怎么变化,最基础的原理还是建立在常规mock的基础上的(如图1)。

图1 常规mock示意图

首先在多依赖的应用中,特别是强依赖服务的业务逻辑比较复杂,依赖服务所在的组还有一堆任务的情况下,通过构造打通依赖服务的行为会变得非常耗时。严重的时候,会拖累整个项目的进度。

ES在公司的大规模应用,为我们解决此类问题提供了契机。ES的埋点数据为mock提供了很好的种子。框架的链路完整埋点为全链路提供最基础的管道,没有这个最基础的管道,所有的链路都将是模糊不清,无法识别的。同时 header在链路中的透传为整个mock实现铺平了道路,使得mock能够快速根据header中的规则来识别不同的链路调用。

测试的不同场景在这里也有了很好的区分。而这些数据又都可以在ES中通过埋点来解决。mock可以通过ES API把这些数据拉来使用,从而基础的API调用链路已经成形并且明晰。这就为后续的实现打下基础。

基础调用链路图如下:

Es链路埋点如图2所示:

图2 ES埋点链路示意图

当所有的链路设施都准备好之后,影响整个使用过程的就是怎么样把mock快速无缝的切入真实调用链路。

我们知道,无论是slb还是ip直连,最基本的原理还是所有的服务都需要注册,注册的最终目的就是所有的服务中心化。当调用依赖服务的时候,在中心里获取对方的服务,提供给调用方使用。

这样的情况下,应用切入mock最直接的想法就是把中心中依赖方地址修改成mock地址,当然这就需要框架提供支持。这是一种侵入式的mock应用方法。

另外一种方式是通过PROXY,类似于网络代理,所有经过代理的网络包在代理中进行收编和整理,该走mock的走mock,不走mock的放回原来的网络中。这种方式是当前相对比较理想的方式。把对应用的侵入,变成系统层面配置的更改,相对适应性更强一些。

综上两点解决后,整个mock链路的基本技术方案有了一个比较可行的落点。mock全链路的整体架构如图3。

图3 MOCK链路架构图

三、技术实现

Mock的技术实现要注意以下三点:

3.1 Mock的响应速度

响应速度要满足服务调用基本要求,不能timeout。正常情况下,mock不需要业务逻辑处理,只需要做规则的简单匹配,响应速度要快才对,这是建立在规则相对少的情况下。

如果在千万亿级的规则进来之后,规则的获取,场景的匹配速度会拖慢整个mock的响应,现在的mock系统同样要依赖缓存技术来提高规则场景的匹配速度。

另外是pb格式请求,我们要进行多次的序列化和反序列化,来保证配置的明文json或者xml能够正确的在请求中传递,而序列化和反序列化本身就是一个消耗cpu的动作,这会给响应造成极大的延迟。

当前情况下,我们尽量提前进行序列化和反序列化操作,操作结果存入缓存,这样能够在此等格式请求传递和返回传递的过程中,保持快速的字节流传递而不需要额外的序列化反序列化操作。

最后在转发的情况下,相对正常服务调用多了一次网络请求,时间消耗相对较长。在这方面我们尽量采用减少连接等待,保持连接状态等方式来减少多次socket连接造成的时间损耗。

3.2 契约依赖问题

对于依赖契约的请求格式,如pb等,需要契约的更新速度必须在ES埋点落库之前。

契约延迟更新是我们面临的很大问题,契约的不及时更新,会造成数据节点的丢失或者直接调用报错。发布订阅和编译包下载替换是我们目前解决这个问题的主要方式。

当前这需要维护一个所有应用契约文件的列表,以便我们在编译包中进行查找替换。而替换动作成功发生的前提是当前契约文件没有被进程占用。

3.3 系统操作的易用性

操作简单是用户使用的基础,也是系统的目标,当然操作习惯也会影响系统在不同人群中的使用。但最终的目标,是希望用户用尽量少的鼠标或者键盘动作,来完成整个mock的操作。链路使用操作相对简单是系统能够被使用的重要环节。

譬如ES数据拉取,我们采用了只让用户输入ES共享链接来代替繁琐复杂的ES过滤器配置。

最原始的设计UI如下图所示:需要有十几个配置项需要用户取配置:

改良后的交互如图4所示,只需要输入ES共享连接即可,其余的事情都由系统来协助用户完成,从而减少用户的使用费力度。

图4 ES数据拉取

四、面临的一些问题

在mock全链路的使用过程中,遇到一些新的问题,比如在真实调用链中重复调用的问题。由于重复调用的返回结果不一致,导致我们在mock全链路的时候无法知晓哪个是第一次要返回,哪个是第二次要返回,从而影响全链路的真实性。

缓存问题。之前提到过很多应用都会在本地或者其他缓存服务器做数据缓存,很多处理逻辑是缓存数据存在的情况下,拉取缓存数据,否则走依赖接口调用,在mock切入应用之后,发现很多缓存未过期导致mock无法被调用,从而影响全链路的正确性。

转发302问题。有些服务需要在服务API之间做302转发调用,而mock正常是要返回http code 200的状态的。

针对不同业务的问题,我们只能针对性的进行个性化或者通用兼容性修补,在通用系统的基础上,进行个性业务适应。

总之,mock全链路系统需要在实际业务中进行不断的锻造、更新,在使用中不断调整,从而保证mock全链路能够适应不同业务的需要。

五、后记

Mock的设计特别要考虑压测的需求,压测对mock系统的要求会更高,所以我们在设计之初,要把这种需求优先考虑,对系统扩展和快速资源扩容留下足够的空间。

另外匹配规则的设计要尽量简单,譬如正则和xpath, jpath此类的功能,从当前的统计数据来看,使用率不高;而简单的规则,譬如header匹配,包含等则被用户大面积使用。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 携程技术中心 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、前言
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档