软件架构场景之—— 接口 Mock:第三方服务还没好,功能设计如何继续?

业务场景

场景一:公司外部之间的调用

我们都知道,联调外部接口,往往需要先申请测试环境,而申请测试环境的时间一般都很长,会耗费很多精力

比如有一次,我们需要对接一个第三方支付的接口,自己系统的功能需求做出来后,对接三方支付接口的功能还迟迟没有动工。我们不断催商务,商务不断催第三方支付的联系人,第三方支付的联系人一直说在走流程,最终光一个第三方支付接口的测试环境就等了 3 周。以至于每次在例会上过项目进度时,这个标红旗的延期项目都会抢镜头

场景二:公司内部之间的接口调用

曾经有一个项目需要配合另一个部门一起做。需求宣讲完后就是定排期,然后就问合作部门:“这几个接口什么时候可以联调?”

因为合作部门还在赶另外一个项目,便回复道:“我们先一起对接口,等忙完手头这个项目,再给出排期可以吗?”

然后我们催促道:“那也得给出一个具体的上线计划啊?”

在我们的催促下,合作部门终于给出了一个日期。

过了几天,合作部门手头的项目出现了延期,又跑过来跟我们说:“我们可能晚几天才能提供那些接口。”

因为需要与对方交互的接口的功能迟迟未动,我们也不敢释放人手,担心人手释放后,项目又立马启动,开发人员好不容易熟悉了新项目又要回来做这个

 

解决思路

我们希望有一个 Mock 接口服务,它能提供与正式服务的 URI、出入参一样的接口,区别是主机名或者 URL 的前缀不一样

在开发和测试过程中,我们都连接上 Mock 服务。等到接口或环境搭建好后,我们无须修改代码,通过一个简单的配置切换即可让服务连接到真实接口服务,然后通过一些简单的回归测试即可实现上线,大大提升了开发效率,此时整体的系统架构如下图所示

看了这个图,内心不禁感慨:“这个架构简直太简单了,都不太好意思画了。”

不过,如果我们想实现这个思路,可就一点不简单了,因为它包含了Mock 服务端和Mock 服务客户端调用设计

 

Mock 服务端设计

1. Mock 接口支持返回动态字段数据

比如有一个接口输入的参数为 UserID、OrderID 和 Redirect URL,如下图所示

输出的参数为 success 和 startTime,如下图所示

我们希望每次调用这个 Mock 接口时,startTime 都返回当前时间,如下图所示

2. Mock 接口支持一些简单的逻辑

在测试过程中,我们会通过不同的测试用例走完不同的流程,比如我们希望调用 Mock 接口传入的 UserID 是 10001,那么 Mock 接口返回的 success 值为 True,否则为 False,而后系统会根据不同的 success 值进入不同的流程

3. Mock 接口支持回调

在实际开发工作中,有很多联调接口需要异步回调,比如上面的例子中,如果返回的 success 值是 True,我们希望过一段时间回调 Redirect URL

4. Mock 接口支持规则校验

我们希望通过添加一些规则让这个 Mock 服务对传入的参数进行校验,比如校验 UserID 是否为数字、OrderID 是否为 15 位数字、Redirect URL 是否为 URL……

5. Mock 服务支持接口文档导入

这一点比较特别,比如某些团队在设计接口文档时,直接将接口定义放在 Wiki 上;而某些团队直接写在 Java 代码中,再通过 Swagger 生成在线接口文档

对于前者,我们要求定义接口时,直接将接口文档放在新的 Mock 服务上。而对于后者,因为不想改变他们的习惯,所以最终 Mock 服务需要支持 Swagger 文档导入

根据以上五点需求,我们开始在市面上找一些合适的开源框架,并发现市面上收费的接口文档管理工具有 Apizza、Eolinker,免费的有 YAPI 和 RAP2,出于各种原因的考虑,最终我们决定在 YAPI 和 RAP2 中进行选择

这里可以参考如下的 YAPI 和 RAP2 对比表

通过表中内容对比,发现 YAPI 更贴合我们的需求,此时开发人员只需改动一个小功能即可满足所有诉求。因此,在 Mock 服务端设计过程中,最终我们基于 YAPI 进行二次开发

 

Mock 服务客户端调用设计

1. Mock 服务如何支持基于二进制流的接口调用?

因为历史原因,有些服务间调用使用 Spring Cloud Feign ,而有些服务间调用使用基于二进制流序列化的 RPC(当然是基于 TCP 协议)

如果服务间的通讯是基于二进制流而不是 JSON,就没办法在 YAPI 上通过简单的界面定义输入输出参数了,且 YAPI 也不支持二进制流的调用,此时我们的解决方案如下图所示

在上面框架中,我们添加了一个拦截器,它会拦截所有服务间调用的请求,并增加一个判断。如果访问的地址是 Mock 服务,我们就使用 HTTP 协议,并且通过 JSON 进行序列化和反序列,这样问题就解决了

2. Mock 服务客户端如何简单切换 Mock 与真实服务?

这里,需要考虑以下 2 种情况

  • 对于第三方接口,只需在配置中将第三方接口的 host 改为 Mock 服务的 host 即可
  • 对于微服务间的调用,我们知道 Spring Cloud 中的微服务定义都是服务级别,但是在实际开发的场景中,我们需要使用接口级别的 Mock,比如我们开发的 operationService,它依赖 productService 的几个接口。因此,在新项目中,我们还需要在 productService 中新增几个接口,且它们必须调用 Mock 服务的接口,而原先的接口继续调用真实的 productService 中原来已经做好的接口。此时,我们需要在配置中心增加 2 个配置项:mock.apis 和 mock.host,每次服务间调用时,先判断调用的 URI 是否在 mock.apis 字符串列表中,如果在,则让它调用 mock.host 这台机器。

3. 如何预防线上环境使用 Mock 服务?

在服务启动时,先判断当前的环境名称,如果是 prod(线上环境),先判断 mock.apis 中是否有值,有值的话提示异常。然后扫描所有的 properties 配置,如果配置中包含 Mock 服务地址,则说明有些地方配置了 Mock 服务的调用,也提示异常

到这里,整体的 Mock 调用方案就完成了

 

总结

Mock 服务上线使用后,如果第三方服务或者其他团队的接口还没有准备好,可以直接根据接口文档配置 Mock 接口,并且所有测试人员都可以基于这些 Mock 接口展开测试。测试差不多后,我们就可以释放团队成员,安排他们开展其他项目

等第三方服务或其他团队的接口好了后,我们再抽调部分成员回来进行简单联调、回归测试,从而实现了系统快速上线,最终整个团队对这个 Mock 服务的评价也不错

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值