行业报告 AI展会 数据标注 标注供求
数据标注数据集
主页 > 技术社区 > 运维 > 正文

Kubernetes-使用 Quarkus 进行原生内循环开发

今天的微服务通常部署在Kubernetes等平台上,该平台协调容器化应用程序的部署和管理。然而,微服务并不存在于真空中。它们通常与其他服务通信,例如数据库、消息代理或其他微服务。因此,一个应用通常由多个服务组成一个完整的解决方案。

但是,作为开发人员,您如何开发和测试作为更大系统一部分的单个微服务?本文研究了一些常见的内循环开发周期挑战,并展示了 Quarkus 和其他技术如何帮助解决其中的一些挑战。

什么是内循环?

几乎所有的软件开发都是迭代的。内部循环包含在将代码提交到版本控制之前在开发人员的机器上发生的所有事情。内部循环是开发人员编写代码、构建和测试代码,并可能在本地运行代码的地方。在当今世界,内部循环还可以包括对Git 拉取请求的多次提交,其中开发人员可以针对特定功能多次提交,直到该功能被视为完成。

注意: 随着越来越多的远程开发环境(例如Red Hat OpenShift Dev SpacesGitpodGitHub Codespaces可用),本地一词在当今业界也引起了争论。本文不区分开发人员机器和任何这些类型的环境。在本文中,它们都被视为本地。

当代码到达源代码控制中需要构建、测试、扫描并最终通过自动持续集成和部署 (CI/CD) 流程部署的点时,内循环转移到外循环。图 1 说明了一个简单的内循环和外循环。

内循环与外循环

图 1:内部循环发生在开发人员的本地计算机上,而外部循环发生在 CI/CD 进程中。

内环开发的挑战

在不担心额外的下游服务的情况下,单独开发单个微服务已经足够具有挑战性了。如果微服务依赖于其他服务才能正常运行,您如何在本地计算机上单独运行微服务?

使用各种模拟技术,您可以在某种程度上避免在编写和运行测试时缺少所需的服务。模拟技术通常非常适合测试。您还可以使用内存中替换所需的服务,例如H2 数据库而不是单独的数据库实例。除此之外,如果您想要或需要在本地运行应用程序,则需要更好的解决方案。

当然,您可以尝试在开发机器上重现应用程序的整个环境。但即使可以,你真的愿意吗?您认为 Twitter 或 Netflix 的开发人员可以在他们的开发机器上重现他们的环境吗?图 2 显示了他们架构的复杂性。Lyft 也尝试过这种方法,但发现它不可行或不可扩展。

来自流行公司的微服务架构

图 2(由https://future.com/the-case-for-developer-experience提供):Netflix 和 Twitter 等主要服务很容易拥有 500 多个微服务。

基于容器的内循环解决方案

使用容器可以帮助加快和改进内循环开发生命周期。容器可以帮助隔离和提供依赖服务的本地实例。我们将了解一些用于内循环的流行工具和技术。

Docker Compose 组成

一种常见的模式是在运行、调试和测试微服务时,使用Docker Compose在本地运行一些微服务的依赖服务(数据库、消息代理等)。使用 Docker Compose,您可以定义一组容器化服务,以提供微服务所需的功能。您可以轻松地启动、停止和查看这些容器化服务的日志。

但是,使用 Docker Compose 也有一些缺点。首先,您必须独立于应用程序代码维护 Docker Compose 配置。您必须记住随着应用程序的发展对 Docker Compose 配置进行更改,有时会在您的应用程序和 Docker Compose 配置之间复制配置。

其次,您被锁定在使用 Docker 二进制文件。对于 Windows 和 macOS 用户,Docker Desktop 不再对许多非个人用户免费您也无法使用其他容器运行时,例如PodmanPodman 确实支持 Docker Compose,但它并不支持您可以使用 Docker Compose 执行的所有操作,尤其是在非 Linux 机器上。

测试容器

Testcontainers是一个优秀的库,用于在应用程序运行测试时为各种服务创建和管理容器实例。它提供了通用数据库、消息代理或任何其他可以在容器中运行的东西的轻量级、一次性实例。

但 Testcontainers 只是一个库。这意味着应用程序必须合并它并对它一些事情才能实现它的好处。一般来说,使用 Testcontainer 的应用程序在执行单元或集成测试时会这样做,但不会在生产中使用。开发人员通常不会将库包含在应用程序的依赖项中,因为当应用程序部署到具有真实服务的真实环境中时,Testcontainers 不属于依赖项。

夸克

Quarkus是一个 Kubernetes 原生 Java 应用程序框架,它不仅仅关注功能集。与传统 Java 应用程序相比,除了实现快速启动时间和低内存占用之外,Quarkus 还确保每个功能都能以高度直观的方式运行良好,几乎不需要配置。该框架旨在使开发简单的东西变得微不足道,并使开发更复杂的东西变得容易。除了简单地运行良好之外,Quarkus 还旨在为开发人员带来欢乐,特别是针对内循环开发生命周期。

开发模式

Quarkus Developer Joy 故事的第一部分,通过Quarkus 开发模式进行实时编码,改进并加快了内循环开发过程。当 Quarkus 开发模式启动时,Quarkus 会自动反映正在运行的应用程序中的代码更改。因此,Quarkus 将图 1 内部循环的Write CodeBuildDeploy/Run步骤合并为一个步骤。只需编写代码,与您的应用程序交互,然后看到您的更改几乎没有延迟地运行。

开发服务

Quarkus Developer Joy 故事的第二部分Quarkus Dev Services自动提供和配置支持服务,例如数据库、消息代理等。当您在开发模式下运行 Quarkus 或执行测试时,Quarkus 会检查所有存在的扩展。Quarkus 随后会自动启动任何未配置的相关服务,并将应用程序配置为使用该服务。

Quarkus Dev Services 使用我们已经讨论过的 Testcontainer,但以对开发人员完全透明的方式。开发人员无需添加 Testcontainers 库,执行任何集成或配置,或编写任何代码。此外,当应用程序部署到具有真实服务的真实环境中时,开发服务不会影响应用程序。

此外,如果您的本地计算机上有多个 Quarkus 应用程序并以开发模式运行它们,默认情况下,开发服务会尝试在应用程序之间共享服务。如果您在使用同一服务的多个应用程序(如消息代理)上工作,则共享服务是有益的。

让我们以Quarkus Superheroes 示例应用程序为例。该应用程序由多个微服务组成,这些微服务共同构成了一个广泛的系统。一些微服务通过 REST 同步通信。其他的是事件驱动的,在Apache Kafka之间产生和消费事件一些微服务是反应式的,而另一些是传统的。所有微服务都会生成Prometheus使用的指标,并将跟踪信息导出到OpenTelemetry

该应用程序的源代码在 Apache 2.0 许可下位于GitHub 上。该系统的架构如图 3 所示。

Quarkus 超级英雄架构

图 3:Quarkus Superheroes 应用程序具有许多微服务和其他依赖服务。

 

在 Quarkus Superheroes 示例应用程序中,您可以在开发模式下本地启动rest-fights和服务。开发模式启动一个MongoDB容器实例、一个event-statisticsApicurio Registry容器实例和一个Apache Kafka容器实例。服务还需要一个 Apicurio Registry 实例和一个 Apache Kafka 实例,因此由dev 模式启动的实例将被.rest-fightsevent-statisticsrest-fightsevent-statistics service

持续测试

Quarkus Developer Joy 故事的第三部分,持续测试,通过立即在后台执行受影响的测试来提供代码更改的即时反馈。Quarkus 检测哪些测试覆盖了哪些代码,并在您更改代码时仅重新运行与该代码相关的测试。Quarkus 持续测试将测试与开发模式和开发服务结合到一个强大的内部循环生产力功能中,将图 1 的所有内部循环生命周期步骤压缩为一个步骤。

其他内环解决方案

到目前为止,我们概述的解决方案对本地内部循环开发非常有帮助,尤其是当您的微服务只需要一小组其他服务(例如数据库,或数据库和消息代理)时。但是当有很多依赖服务时,试图将它们全部复制到本地机器上可能不会很好地工作,如果有的话。

所以你会怎么做?当应用程序依赖于您不能不想在本地运行的其他服务时,您如何获得应用程序内循环开发的速度和敏捷性?

一种解决方案可能是管理共享服务的环境。然后每个开发人员将在他们的本地设置中配置这些服务,注意不要将配置提交到源代码管理中。

另一种解决方案可能是使用 Kubernetes,为每个开发人员提供一个命名空间,他们可以在其中部署所需的内容。然后,开发人员可以部署服务并配置其本地应用程序以使用它们。

这两种解决方案都可以工作,但实际上,它们通常会以一个问题告终:开发人员正在处理的微服务位于整个系统服务图中的某个位置开发人员如何触发他们关心的微服务作为更大请求或流程的一部分被调用?

难道不是更好的解决方案是在本地运行应用程序,但让更大的系统认为应用程序实际上部署在某个地方?

这种远程+本地开发模式被称为remocal这是一种非常强大的方法,可以在您的内部循环开发周期中获得即时反馈,同时确保您的应用程序在接近或匹配生产的环境中正常运行。

Quarkus 远程开发

Quarkus Developer Joy 故事的另一部分是远程开发,它使开发人员能够将应用程序部署到远程环境中,并在该环境中运行 Quarkus 开发模式,同时在本地进行实时编码。Quarkus 立即将代码更改同步到远程部署的实例。

Quarkus 远程开发允许开发人员在将运行的相同环境中开发应用程序,同时可以访问它可以访问的相同服务。此外,此功能大大减少了内部反馈循环,同时缓解了“在我的机器上工作”问题。远程开发还允许快速轻松地制作新特性和功能的原型。图 4 说明了远程开发模式的工作原理。

Quarkus 远程开发

图 4:Quarkus 远程开发模式以增量方式将本地代码更改与远程 Quarkus 应用程序同步。

 

首先,将应用程序部署到 Kubernetes、虚拟机、容器或某处的某个 Java 虚拟机 (JVM)。一旦运行,开发人员在他们的本地机器上运行远程开发模式,将他们的本地机器连接到远程实例。

从那里开始,开发就像在 Quarkus 开发模式下进行实时编码一样。当开发人员更改代码时,Quarkus 会自动编译并将更改推送到远程实例。

让我们继续之前的 Quarkus Superheroes 示例。假设整个系统部署到 Kubernetes 集群中。我们还假设您想要更改rest-fights微服务。

如图 5 所示,您rest-fights在本地计算机上以远程开发模式启动微服务。集群上运行的rest-fights应用程序连接到 Kubernetes 集群上的 MongoDB、Apicurio Registry 和 Apache Kafka 实例。

远程开发逻辑视图

图 5:远程开发模式下对本地应用程序的更改不断向远程实例发送更新。

 

然后,您可以通过其用户界面与系统交互。当您对微服务进行更改时,Quarkus 会逐步将更改与 Kubernetes 集群上的远程实例同步rest-fights如果需要,您甚至可以在本地计算机上的 IDE 中使用断点来协助调试。

Skupper

Skupper是第 7 层服务互连,可在没有 VPN 或特殊防火墙规则的情况下实现跨 Kubernetes 集群的安全通信。使用 Skupper,一个应用程序可以跨越多个云提供商、数据中心和区域。图 6 显示了 Skupper 的高级视图。

Skupper 逻辑架构

图 6:从逻辑上讲,Skupper 将不同站点上的服务连接在一起,作为一个站点存在。

 

使用 Skupper,您可以创建一个分布式应用程序,该应用程序由在不同 Kubernetes 集群中的不同命名空间中运行的微服务组成。暴露给 Skupper 的服务随后会暴露给每个命名空间,就好像它们存在于命名空间中一样。Skupper 创建代理端点以使服务在安装它的每个命名空间内可用。图 7 显示了此体系结构的逻辑视图。

Skupper 逻辑 Kubernetes

图 7:从逻辑上讲,Skupper 可以跨越多个 Kubernetes 集群并使远程服务显示为本地服务。

 

Kubernetes原生内循环开发的文章为什么要提到Skupper?因为除了桥接跨 Kubernetes 集群的应用程序之外,Skupper 代理还可以在任何机器上运行,从而实现机器与其他 Kubernetes 集群之间的双向通信。

从逻辑上讲,这就像插入到一组 Kubernetes 集群中间的本地机器。在集群上暴露给 Skupper 的服务可以发现在本地机器上暴露给 Skupper 代理的服务,反之亦然。

Skupper 可以使我们的 Quarkus Superheroes 示例更加有趣,使它远离我们之前描述的远程开发场景。

使用 Skupper,您无需将服务更改rest-fights从本地实例持续同步到远程实例,而是可以将远程rest-fights实例完全替换为运行 Quarkus 开发模式和持续测试的本地实例。

然后,Skupper 会将 Kubernetes 集群上的流量重定向rest-fights本地机器上运行的服务中。该服务发出的任何传出请求rest-fights,例如与 MongoDB、Apicurio 注册表和 Apache Kafka 实例的连接,甚至rest-heroes服务rest-villains,都将被重定向回 Kubernetes 集群。图 8 显示了此体系结构的逻辑视图。

Skupper 逻辑架构

图 8:从逻辑上讲,Skupper 可以使本地开发人员机器看起来像是在 Kubernetes 集群中。

 

您甚至可以使用 Quarkus 开发服务来允许rest-fights微服务提供自己的本地 MongoDB 实例,而不是使用集群上的实例,同时继续让流向 Kafka 的流量流向集群。此设置将使收听同一主题的其他 Kafka 消费者能够继续运行。

在这种情况下,Quarkus 持续运行微服务测试,rest-fights同时开发人员进行实时代码更改,同时流量持续流经 Kubernetes 集群上的整个系统。这些服务甚至可以分布到世界其他地区不同云提供商的其他 Kubernetes 集群,同时流量继续流经开发人员的本地机器。

更好的开发人员体验,无论是本地还是分布式

前面提到的 Lyft 文章系列的第二部分第三部分展示了 Lyft 解决这个问题的方法,尽管使用了不同的技术。随着越来越多的服务问世,Lyft 发现他们所做的并不能扩展,因此他们需要一种“远程”环境。

Quarkus 的设计考虑了许多 Developer Joy 特性。Quarkus 可帮助开发人员更快地进行迭代,并包含可缓解其中许多挑战并缩短开发生命周期的内置功能。开发人员可以专注于编写代码。

微信公众号

声明:本站部分作品是由网友自主投稿和发布、编辑整理上传,对此类作品本站仅提供交流平台,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,不为其版权负责。如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。

相关文章:

相关推荐:

网友评论:

发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
SEM推广服务

Copyright©2005-2026 Sykv.com 可思数据 版权所有    京ICP备14056871号

关于我们   免责声明   广告合作   版权声明   联系我们   原创投稿   网站地图  

可思数据 数据标注行业联盟

扫码入群
扫码关注

微信公众号

返回顶部