写点什么

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:003170
用户头像

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

关注

评论

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

自动驾驶汽车:AI技术的未来之路

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

测试

华为3场重磅主题演讲先睹为快,顶级云原生&开源盛会即刻出发

华为云开源

华为 开源 云原生 KubeCON

日本站群服务器:提升网站流量的最佳选择

一只扑棱蛾子

站群服务器

写SAE评测,获 Airpods 2大奖【集结令】!

Serverless Devs

Serverless 云原生 AIGC

聚势共创 多元共生——中科美菱联动清华大学助力产研融合!

联营汇聚

华为云API对话机器人CBS的魅力—要是有AI,我要做“李白”- 5分钟开发作诗机器人

华为云PaaS服务小智

云计算 软件开发 华为云

全部自动化可行吗?

FunTester

AI革命:如何改变我们的工作和生活

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

测试

AI在医疗保健中的潜力与挑战

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

测试

DevOps|研发效能团队组织架构和能力建设

laofo

DevOps cicd 研发效能 持续交付 组织架构

关于 TDengine 3.0 数据订阅,你需要知道这些

TDengine

tdengine 时序数据库 国产时序数据库

人工智能塑造未来城市生活

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

测试

Git Stash:临时保存和切换工作状态的利器

凌览

git git stash

IPQ9574 IPQ9554 QCN9274 QCN6274 WIFI7 SolutionUnlocking the Potential of Wi-Fi 7

wallyslilly

ipq9554 qcn9274 qcn6274 ipq9574

开启 Kerberos 安全认证的大数据环境中如何正确指定 HS2 的 jdbc url 地址?

明哥的IT随笔

大数据 hive kerberos

预训练深度双向Transformer语言模型

百度开发者中心

自然语言处理 #人工智能 千帆大模型平台

为什么使用http代理要谨慎?动态ip地址和静态ip地址是什么意思?

巨量HTTP

http代理

机器学习:解码人工智能的核心技术

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

测试

自动驾驶汽车—AI技术的未来之路

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

测试

如何在低代码平台中应用可视化编程

力软低代码开发平台

人工智能伦理—面对技术的道德挑战

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

测试

软件测试/测试开发丨利用ChatGpt编写测试方案

测试人

人工智能 程序员 软件测试 测试方案 ChatGPT

百度智能云 AI 加速器第二期今日开营,42家AI原生应用企业入选

Geek_2d6073

如何访问TDH中Inceptor 底层的元数据库TxSQL

明哥的IT随笔

大数据 hive

深度理解自然语言处理的强大工具

百度开发者中心

自然语言处理 #人工智能 生成式AI

HarmonyOS 4.0 实况窗上线!支付宝实现医疗场景智能提醒

HarmonyOS SDK

huawei HarmonyOS

为什么你的自动化测试无法落地

老张

自动化测试

体验亚马逊的 CodeWhisperer 感觉

亚马逊云科技 (Amazon Web Services)

Java 人工智能

OpenHarmony自定义组件介绍

OpenHarmony开发者

OpenHarmony

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