写点什么

Marcin Grzejszczak 访谈:Spring Cloud Contract

  • 2017-04-27
  • 本文字数:3435 字

    阅读完需:约 11 分钟

Marcin Grzejszczak 是 Pivotal 的一名软件工程师。目前,他在从事 Spring Cloud Contract 的开发,这是一个消费者驱动的、面向 Java 的契约框架。为了了解该框架的一些好处,特别是消费者驱动契约对微服务测试的帮助,InfoQ 对 Marcin 进行了采访。

要点:

  • 对于架构来说,消费者驱动契约和测试驱动开发类似;
  • Spring Cloud Contract 与 Spring 生态系统集成得很好;
  • 当使用消费者驱动契约时,端到端测试变得多余;
  • 在 Spring Cloud Contract 中,Spring Rest Docs 可以代替 Groovy DSL;
  • 将来,Spring Cloud Contract 将为非 Java 用户提供改进的工具。

InfoQ:您能简要介绍一下消费者驱动契约模式以及它解决的是微服务开发中的哪类问题吗?

Marcin Grzejszczak:消费者驱动契约是一个流程,旨在帮助客户测试他们的软件,创建更好的架构设计。在架构层面,我们可以称之为测试驱动开发。现如今,软件需要能够非常快速地响应客户需求、法律法规变化及业务需求,等等。另一方面,我们 IT 行业希望尽可能快地交付可靠的软件,经过测试,不含任何 Bug。这就是为什么我们创建了部署管道——自动化发布和测试过程。至于微服务,由于架构风格本身的性质,问题被放大了。我们不可能在不影响测试流程的情况下将单体应用拆分成微服务。

单体结构中包含的复杂性被推至架构层面。消费者驱动契约试图在团队之间定义一些明确的沟通界限。CDC 的总体流程是,消费者定义他们期望 API/ 消息是什么样子。这种期望就称为契约。从这些契约可以生成存根,稍后,消费者团队可以在构建过程中重复使用它们。在生产者一端也需要验证契约。那就导致,不管是测试生产者一端,还是测试消费者一端,都需要引入一种快速失败方法。对于快速失败,我们指的是软件构建失败以及通过产品调试发现问题(例如,我们在 REST/AMQP 消息中犯了一个错误)。

消费者驱动契约将 API 设计转移给了使用它的人。典型地,服务器端的团队只需要宣布 API 会是个什么样子。通常,消费者的数量导致那是唯一可能的方式。但情况并不总是如此。我见过,有的公司没有公开暴露他们的 API,团队也不希望在 API 应该是个什么样子这个问题上进行协作。CDC 就是设法将那种方法变成一种由消费者驱动 API 变化的方法。细想一下,这很有道理。不是服务器端消费 API,是消费者消费 API,那就是为什么创建的 API 应该尽可能地适应消费者。

InfoQ:你们创建 Spring Cloud Contract 的动机是什么?你们为什么用它代替其他可选的消费者驱动的契约框架?

Grzejszczak:和来自 Devskiller 公司的 Jakub Kubrynski 一起,我们对 CDC 框架进行了分析。我们得出的结论是,它们的学习曲线很高,而且非常啰嗦。这就是为什么在 2014 年 12 月诞生了 Spring Cloud Contract 的前身 Accurest。我们已经决定引入静态类型 Groovy DSL 来定义契约。这里要说到 Spring Cloud Contract 和其他 CDC 框架的主要区别了。Spring Cloud Contract 不仅可以从契约生成存根,还可以生成测试。那意味着开发人员只需要定义契约,而其他的东西都会为生产者自动生成。这曾是我们希望做出的一个非常重要的决策,因为 CDC 的本质就是,假定生成的存根是可信的。如果有人在契约中定义了一个可以通过GET方法访问的端点/foo,那么在生产者一端,我们就可以通过向/foo端点发送GET请求来生成一个测试。如果没有这样的端点,那么测试就会中断,存根也不会生成。

显而易见,Spring Cloud Contract 与 Spring 环境集成得很好。我们已经支持使用 Spring Integration Spring Cloud Stream Spring AMQP Apache Camel 进行消息传递。但是,是一个叫做 Stub Runner 的组件让 Spring Cloud Contract 成为一个有吸引力的选项。我已经提到过,存根是从契约生成的。在默认情况下,我们希望用户以 JAR 文件的形式将生产者存根和契约发布到 Maven 库。假如存根的组 ID 为“org.springframework”,工件 ID 为“spring-boot-application”。为了运行存根,消费者需要像下面这样给测试加上注解:@AutoConfigureStubRunner (ids={'org.springframework:spring-boot-application:+'}

实际情况是,框架会自动下载包含存根的“org.springframework:spring-boot-application” JAR 文件的最新版本,然后启动一个内存内 HTTP 服务器,并在一个随机端口上提供存根。也就是说,只需一条注解,你就可以为构建生成整个环境的存根!此外,真正有趣的是,Spring Cloud Contract 可以完全消除服务发现工具。那意味着,存根注册在一个服务注册中心的内存版本中。那样,你可以像使用服务发现那样,向一个真正的 HTTP 服务器发送一个真正的 HTTP 请求。

如果你想要在测试环境中对打包好的应用程序执行一些冒烟测试,Spring Cloud Contract 的 Stub Runner 也非常方便。下载好的存根可以注册到真正的服务发现工具中(例如 Eureka ),在契约中定义的真正的消息可以发送给真正的队列(例如 RabbitMQ )。那样,你的应用程序甚至都不知道它在同存根交互。

InfoQ:消费者驱动契约模式,如果有的话,对端到端测试有什么影响吗?

Grzejszczak:这是一个很好的问题。就像我提到的那样,使用微服务增加了测试和部署应用程序的复杂度。尤其是,部署和端到端测试的组合很有趣。假如我们的系统由 50 个微服务组成,让我们提几个问题:

  1. 对于每个构建的微服务,每个团队都应该有它的部署环境吗?
  2. 谁来承担那 50 个环境的费用?
  3. 如果我们决定,不是每个微服务一个环境,那我们该如何处理部署队列?如果端到端测试需要运行很长时间,我们就不得不在轮到我们之前等待很长时间……
  4. 那些环境应该包含其他 49 个微服务的生产版本还是开发版本?
  5. 或者,生产版本和开发版本都应该测试?谁来配置那些环境,谁又负责维护那些环境?
  6. 有时候,企业无法在测试环境中使用生产数据——他们会对数据进行模糊处理,并满足完整性需求。

此外,还有一点需要考虑,就是端到端测试相当脆弱。有许多和代码 Bug 无关的原因可以导致它们失败。我不是说端到端测试没有带来任何价值——恰恰相反。当复杂度达到一定程度时,必须计算成本和收益。消费者驱动契约可以解决问题。如果消息违反了契约,那么执行契约测试可以提早终止构建。换句话说,如果你的消息中有错误,那么最好在构建的第一分钟就失败,而不是在 2 个小时的端到端测试的最后一分钟。

这可能会引起争议,但在我个人而言,我认为,只要设置恰当,端到端测试就是多余的,完全可以省略。这需要满足三个条件:(1)进行契约测试;(2)监控关键性能指标并报警;(3)可以进行回滚测试,并构建到部署管道中。作为这种部署管道的例子,你可以检出 Spring Cloud Pipelines 项目。

InfoQ:给我介绍下新的 Spring Rest Docs 集成吧,它是否可以改变传统的消费者驱动契约工作流?

Grzejszczak:那不新了,不过,它确实获得了更多的关注。有些用户不喜欢编写 Groovy DSL,不希望生成测试。他们希望完全属于自己的测试流程。还有一些其他的用户已经在使用 Spring Rest Docs 测试他们的代码。Dave Syer 就是其中的一位用户,向 Spring Rest Docs 添加 Spring Cloud Contract 集成就是他的主意。多亏了这个,你才能编写测试来测试你的 Web 应用程序以及自动生成存根。使用 Spring Cloud Contract 的最新版本,你还可以从 Spring Rest Docs 生成 Groovy DSL 契约。

至于工作流,我可以想象得到,消费者和开发者结对满足消费者需要的测试和存根。那样,流程得以保留。另一方面,有些事情告诉我,Spring Rest Docs 方法将更多地应用在“生产者契约”方法中。生产者定义契约是什么样子也是如此。在 Spring,我们喜欢用自己的产品来进行开发,Spring Initilizr(start.spring.io 背后的代码)已经使用了 Spring Cloud Contract,而且,Spring Initilizr 存根发布到了 Spring 的 Maven 库。

InfoQ:最后一个问题,在你们的路线图上,有什么有趣的东西可以介绍一下吗?

Grzejszczak:我们刚刚发布了 Spring Cloud Contract 的最新版本“1.1.0.RELEASE”,带来了一些有趣的特性,其中包括完全模块化(现在,你可以自定义 Spring Cloud Contract 的部件,比如,生成 PHP 测试),所以,在接下来的几个周里,我们最可能做的是修复 Bug,让 API 更稳定。就长远规划而言,我们在考虑简化非 Java 用户的工作。不过显然,对我们而言,最重要的是用户的反馈,我们会调整规划满足他们的需求。

如果你想进一步了解这个项目,可以查看项目主页。如果你有什么问题,可以通过 Gitter 或者 Twitter( @mgrzejszczak )联系我。

查看英文原文 Q&A with Marcin Grzejszczak on Spring Cloud Contract

2017-04-27 19:003409
用户头像

发布了 1008 篇内容, 共 419.4 次阅读, 收获喜欢 346 次。

关注

评论

发布
暂无评论
发现更多内容

【Netty】「优化进阶」(二)浅谈 LengthFieldBasedFrameDecoder:如何实现可靠的消息分割?

sidiot

Java 后端 Netty 6 月 优质更文活动

软件测试 | 性能测试实施流程

测吧(北京)科技有限公司

测试

Maya软件是做什么的?Maya软件优缺点分析!

Finovy Cloud

maya

【网络安全】浅谈数据库攻击复现及相关安全优化

sidiot

MySQL 网络安全

软件测试/测试开发丨用户端Web自动化测试学习笔记

测试人

Python 程序员 软件测试 学习笔记 web自动化

企业数智化转型数智员工到底能做什么?

用友BIP

数智底座 Pass平台

究竟是什么让山东航空人力资源数智化转型如虎添翼?

用友BIP

数智人力

一种很新的交互式智能标注技术

澳鹏Appen

人工智能 交互 数据标注 智能标注 交互式标注

自动驾驶优缺点都有什么

数据堂

Flyway:简化数据迁移以适应敏捷开发

inBuilder低代码平台

Hibernate5 动态模型

alexgaoyh

hibernate jpa 动态模型 运行时 sessionfactory

基于多尺度图神经网络的流场预测,实现精度与速度的平衡

飞桨PaddlePaddle

人工智能 百度飞桨 开发者说

低代码平台的实现原理

互联网工科生

软件开发 低代码 JNPF

从两个案例看Apache Flink如何提升企业实时数据处理效率

xfgg

Java flink 6 月 优质更文活动

软件测试 | 性能调整基础

测吧(北京)科技有限公司

测试

低代码开发将彻底颠覆编程行业!你还需要学习编程吗?

不在线第一只蜗牛

低代码 数字化 低代码开发

数字化转型与架构|开篇

数字随行

架构 数字化转型

NFTScan 与 Wagmi Labs 达成合作伙伴,双方在多链 NFT 数据方面展开合作!

NFT Research

NFT\

企业如何提高全面提升预算管理效率?

用友BIP

全面预算

【Netty】「源码解析」(二)HeapBuffer 创建过程详解:高效可靠的内存管理技巧

sidiot

Java 后端 Netty 6 月 优质更文活动

【Netty】「优化进阶」(一)粘包半包问题及解决方案

sidiot

Java 后端 Netty 6 月 优质更文活动

传统全面预算管理体系暴露的问题

用友BIP

全面预算

软件测试 | 性能测试管理障碍

测吧(北京)科技有限公司

测试

从规划、预算和预测中实现企业未来价值

智达方通

财务分析 预测模型 业财融合 全面预算管理

【Netty】「源码解析」(一)ByteBuf 的动态扩容策略与实现原理

sidiot

Java 后端 Netty 6 月 优质更文活动

不学血亏!手把手教会你推特视频如何下载到手机相册~

frank

提升网站速度的秘密武器:国外主机的优势解析!

一只扑棱蛾子

国外主机

中企出海之营销最佳实践——新加坡SK集团

用友BIP

中企出海

【Netty】「优化进阶」(三)Netty 通信协议设计:从 Redis、HTTP 和自定义协议看起

sidiot

Java 后端 Netty 6 月 优质更文活动

Marcin Grzejszczak访谈:Spring Cloud Contract_Java_Andrew Morgan_InfoQ精选文章