如何使用Nylas在本地测试微服务(下)

2023-03-11   出处: Nylas  作/译者:Zhi Qu/王练

Minikube + Tilt

Minikube 为我们的开发环境提供了基础设施。
本地 Kubernetes 集群称为 Minikube。 它可以模拟生产环境中运行的 Kubernetes。 您可以在 Minikube 中创建 Kubernetes 部署和 Cron 作业。 这些可以通过 Kubernetes 命令行 kubectl 访问。 有关 Minikube 的更多信息,请参阅 https://minikube.sigs.k8s.io/docs/。
让我们看一下 Nylas Sync 域的开发环境,在本地Minikube 集群中运行 14 个服务和 2 个作业。

这里的每个 pod 都运行单一服务。各服务在同一集群内交互。
开发人员可以在“部署”选项卡中看到服务列表,例如“zoom-notification-server”、“graph-notification-subscriber”、“graph-metadata-listener”等:

所有这些都是 Nylas 后端服务,在同一个 Minikube 集群中本地运行。 但是为什么我们不使用 Docker Compose 呢?
首先,Nylas 后端服务与 Kubernetes API 交互。 一些微服务创建 Kubernetes 作业,一些提供 Kubernetes pod。 Docker Compose 无法模拟 Kubernetes 内部 API。
其次,Minikube 可以更好地模拟生产环境。 人们使用 Helm 而不是 Docker Compose 将服务部署到生产环境中。 我们可以为我们的开发环境和生产环境使用相同的 Helm 模板。 唯一的区别是 Helm 值。 这样,人们不仅可以测试他们的代码,还可以测试他们的部署流水线。

除 Minikube之外,我们还使用了一个神器: Tilt。 Tilt 是一种用于在本地运行 Kubernetes 集群的开发人员工具。 它提供智能重建和实时更新。
要设置开发人员环境,只需运行 tilt up。 所有服务都会自动部署到 Minikube。 它还提供了一个仪表板,您可以在其中查看进度:

在幕后,Tilt 为每项服务完成如下工作:

  1. 编译服务二进制文件
  2. 将二进制文件构建到 Docker 映像中
  3. 通过 Helm 在 Minikube 中部署服务

Tilt 提供的最令人兴奋的功能是实时更新。 每次开发人员在他们的 IDE 中更改代码时,Tilt 都会检测到更改并自动重启服务! 服务重启只需要几秒钟。 现在的编写和测试迭代比以往任何时候都短。

有关 Tilt 的更多信息,您可以阅读他们的文档:https://tilt.dev/。

第三方服务模拟器

大多数服务都依赖第三方。 一个服务可能依赖于 Redis、PostgreSQL、Kafka 等。 为了设置开发环境,我们必须在本地运行第三方依赖。
如果第三方服务有官方的 Helm 图表,我们可以简单地将它安装到我们的 Minikube 中。 但是有些第三方依赖是不能直接安装的。 Google PubSub 和 Amazon DynamoDB 等服务没有可用的 Helm 图表。

针对这些服务,我们提供了模拟器。
以下是 Nylas 在我们的开发环境中提供的一些模拟器:

  • gcloud 是一个谷歌命令行工具。 它可以模拟 Google PubSub 和 Spanner。
  • LocalStack 是一个单一的服务。 它可以模拟大多数 AWS 服务,包括 DynamoDB 和 SQS。
  • Temporalite 是一个命令行工具。 它可以模拟 Temporal 工作流引擎。

我们将这些模拟器构建到 Docker 镜像中,并编写了一个 Helm 图表模板。 然后我们可以将它们部署到 Minikube。
这是我们的 Google PubSub 模拟器的示例 Dockerfile:

FROM google/cloud-sdk:alpine AS builder
LABEL stage=builder
RUN gcloud components install pubsub-emulator

FROM openjdk:jre-alpine

COPY --from=builder /google-cloud-sdk/platform/pubsub-emulator /pubsub-emulator

RUN apk --update --no-cache add tini bash
ENTRYPOINT ["/sbin/tini", "--"]
CMD /pubsub-emulator/bin/cloud-pubsub-emulator --host=0.0.0.0 --port=8085
EXPOSE 8085

从官方 Helm 图表到模拟器,我们拥有在本地运行第三方依赖项所需的一切。

Mock服务

让我们再次看看示例开发环境:

服务通常会与域外的其他服务交互。 电子邮件服务需要向身份验证服务发送 API 请求,但是这两个服务不在同一个域中。 如果其他域的服务没有在Minikube中运行,我们如何在本地测试它们?

答案是:Mock服务。
如果电子邮件服务调用身份验证服务,我们将构建一个 fake-auth-service 仅用于测试。 Mock服务维护与真实服务相同的 API 定义,但不进行实际身份验证。 Mock服务的响应可以是硬编码的。

答案不是:在本地部署多个域。

我们认为服务应该在他们自己的域内进行本地测试,而不需要另一个服务也在本地运行。 在 Minikube 集群中同时部署多个域导致的问题多于解决的问题。
最大的原因是CPU和内存消耗。 我们尝试在 2019 款 Apple MacBook Pro 上部署两个服务域。 我们的 IDE 卡死了,笔记本电脑开始发热,风扇也不停歇。 这是一个非常糟糕的开发者体验。

开发环境与持续集成

通过本地运行的开发环境,我们可以编写功能测试。 以下是我们可以实施的一些示例功能测试:

以下是 GitHub 操作配置示例:

name: Function test
on: pull_request
jobs:
  Function-Test:
    name: Function-Test
  runs-on: ubuntu-latest
  steps:
    - name: Install Go
      uses: actions/setup-go@v2
      with:
        go-version: '>=1.17.0'
    - name: Checkout
      uses: actions/checkout@v2
    - name: Setup Kubernetes Tools
      uses: yokawasa/action-setup-kube-tools@v0.8.0
      with:
        tilt: '0.26.3'
    - name: Start Minikube
      id: minikube
      uses: medyagh/setup-minikube@master
      with:
        minikube-version: 1.25.2
    - name: Validate tilt
      run: tilt ci
    - name: Run Function Test
      run: go test -v function-test/...

如果功能测试失败,开发人员PULL请求中看到失败。 如果不小心破坏了开发环境,CI 检查也会在代码部署之前拦截错误。

总结

通过划分域的微服务,在Nylas 中的开发环境如下所示:

总结如下:

  • 将 Minikube 作为本地基础设施运行
  • 使用 Tilt 部署所有服务
  • 支持模拟第三方服务
  • 如果不在同一个域中,支持会构建虚假服务
  • 实现在 Minikube 中对服务进行功能测试
  • 使用 GitHub Actions 将所有内容与 CI 集成

现在,所有 Nylas 核心服务都可以在本地运行和测试,极大地提高了 Nylas 的开发速度。

特别感谢所有帮助这项工作的相关人员:

  • Andrew Jung
  • Anirban Das
  • Mudit Seth
  • Pouya Sanooei
  • Albert Korionov
  • Bahram Kouhestani
  • Chitresh Deshpande
  • Joe Chen
  • Danton Pimentel
  • Wei Xiang Li
  • Ali Hussain
  • Elliot Yaghoobia

声明:本文为本站编辑转载,文章版权归原作者所有。文章内容为作者个人观点,本站只提供转载参考(依行业惯例严格标明出处和作译者),目的在于传递更多专业信息,普惠测试相关从业者,开源分享,推动行业交流和进步。 如涉及作品内容、版权和其它问题,请原作者及时与本站联系(QQ:1017718740),我们将第一时间进行处理。本站拥有对此声明的最终解释权!欢迎大家通过新浪微博(@测试窝)或微信公众号(测试窝)关注我们,与我们的编辑和其他窝友交流。
195° /1950 人阅读/0 条评论 发表评论

登录 后发表评论