博客 | NGINX

NGINX 教程: 如何部署和配置微服务

NGINX-F5-horiz-black-type-RGB 的一部分
Javier Evans 缩略图
哈维尔·埃文斯
2023 年 3 月 7 日发布

这篇文章是帮助您将2023 年 3 月微服务中的概念付诸实践的四个教程之一: 开始交付微服务

 

所有应用程序都需要配置,但配置微服务时的注意事项可能与单片应用程序不同。我们可以参考十二要素应用程序中的要素 3将配置存储在环境中)来获取适用于这两种类型应用程序的指导,但该指导可以适用于微服务应用程序。 具体来说,我们可以调整定义服务配置的方式,为服务提供配置,并使服务可作为可能依赖它的其他服务的配置值。

要从概念上理解如何使因素 3 适应微服务 - 特别是配置文件、数据库和服务发现的最佳实践 - 请阅读我们博客上的配置微服务应用程序的最佳实践。 这篇文章是将这些知识付诸实践的好方法。

笔记: 本教程的目的是说明一些核心概念,而不是展示在生产中部署微服务的正确方法。 虽然它使用了真正的“微服务”架构,但仍有一些重要的注意事项:

  • 本教程不使用 Kubernetes 或 Nomad 等容器编排框架。 这样,您就可以了解微服务概念,而不会陷入某个框架的细节中。 这里介绍的模式可以移植到运行这些框架之一的系统上。
  • 这些服务是为了易于理解而不是软件工程的严谨性而优化的。 重点是看服务在系统中的作用及其通信模式,而不是代码的细节。 有关更多信息,请参阅各个服务的README文件。

教程概述

本教程说明了因素 3 概念如何应用于微服务应用程序。 在四个挑战中,您将探索一些常见的微服务配置模式,并使用这些模式部署和配置服务:

  • 挑战 1挑战 2中,您将探索第一种模式,该模式涉及微服务应用程序的配置位置。有三个典型位置:

    • 应用程序代码
    • 应用的部署脚本
    • 部署脚本访问的外部源
  • 挑战 3中,您将设置另外两种模式:通过 NGINX 作为反向代理将应用程序公开给外界,并使用 Consul 启用服务发现。
  • 挑战 4中,您将实现最后的模式:使用微服务实例作为“作业运行器”,执行与其通常功能不同的一次性操作(在本例中模拟数据库迁移)。

本教程使用了四种技术:

  • messenger – 为本教程创建的具有消息存储功能的简单聊天 API
  • NGINX 开源信息服务和更广泛系统的入口点
  • Consul – 动态服务注册中心和键值存储
  • RabbitMQ – 一个流行的开源消息代理,支持服务异步通信

拓扑图显示 NGINX 开源和 Consul 模板在容器中一起运行。 咨询模板与咨询客户端进行沟通。 NGINX Open Source 是 messenger 服务的反向代理,它将数据存储在 messenger_db 中并与 Rabbit MQ 通信。

观看此视频以了解本教程的概述。 这些步骤与这篇文章并不完全匹配,但有助于理解概念。

先决条件和设置

先决条件

要在您自己的环境中完成本教程,您需要:

  • Linux/Unix 兼容环境
  • 对 Linux 命令行、JavaScript 和bash有基本的了解(但提供并解释了所有代码和命令,因此即使知识有限,您仍然可以成功)
  • DockerDocker Compose
  • Node.js 19.x 或更高版本

    • 我们测试了 19.x 版本,但预计 Node.js 的较新版本也能运行。
    • 有关安装 Node.js 的详细信息,请参阅Messenger服务存储库中的README 。 您还可以安装asdf以获取与容器中使用的完全相同的 Node.js 版本。
  • curl (大多数系统上已安装)
  • 教程概述中列出的四种技术: messenger (您将在下一节中下载它)、 NGINX 开源ConsulRabbitMQ

设置

  1. 启动终端会话(后续说明将其称为应用程序终端)。
  2. 在您的主目录中,创建microservices-march目录并将本教程的 GitHub 存储库克隆到其中。 (您也可以使用不同的目录名称并相应地调整说明。)

    笔记: 在整个教程中,省略了 Linux 命令行上的提示,以便更容易地将命令复制并粘贴到终端中。 波浪号 ( ~ ) 代表您的主目录。

    mkdir ~/microservices-marchcd ~/microservices-march
    git clone https://github.com/microservices-march/platform.git --branch mm23-twelve-factor-start
    git clone https://github.com/microservices-march/messenger.git --branch mm23-twelve-factor-start
    
  3. 切换到平台存储库并启动 Docker Compose:

    cd 平台docker compose up -d --build
    

    这将启动 RabbitMQ 和 Consul,它们将在后续的挑战中使用。

    • -d标志指示 Docker Compose 在容器启动时与容器分离(否则容器将保持连接到您的终端)。
    • --build标志指示 Docker Compose 在启动时重建所有映像。 这可以确保您运行的图像在文件发生任何潜在变化时保持更新。
  4. 切换到messenger存储库并启动 Docker Compose:

    cd../messengerdocker compose up -d --build
    

    这将启动信使服务的 PostgreSQL 数据库,在本教程的剩余部分我们将其称为信使数据库

挑战1: 定义应用程序级微服务配置

在这个挑战中,您将在我们将在本教程中看到的三个位置中的第一个位置设置配置:应用级别。 (挑战 2说明了第二和第三个位置、部署脚本和外部源。)

十二因素应用程序特别排除了应用级配置,因为这种配置不需要在不同的部署环境(十二因素应用程序称之为部署)之间进行更改。 尽管如此,为了完整性,我们还是涵盖了所有三种类型——在开发、构建和部署服务时处理每种类别的方式是不同的。

信使服务是用 Node.js 编写的,其入口点位于信使存储库中的app/index.mjs中。 该文件的这一行:

应用程序.使用(express.json());

是应用级配置的一个示例。 它配置Express 框架应用/json类型的请求体反序列化为 JavaScript 对象。

此逻辑与您的应用程序代码紧密耦合,并不是十二因素应用程序所认为的“配置”。 然而,在软件中一切都取决于您的情况,不是吗?

在接下来的两节中,您将修改此行以实现应用级配置的两个示例。

示例 1

在此示例中,您设置了信使服务接受的请求主体的最大大小。 此大小限制由express.json函数的limit参数设置,如Express API 文档中所述。 这里您将限制参数添加到上面讨论的 Express 框架的 JSON 中间件的配置中。

  1. 在您喜欢的文本编辑器中,打开app/index.mjs并替换:

    应用程序.使用(express.json())
    

    和:

    app.use(express.json({限制: “20b” }));
    
  2. 在应用程序终端(您在“设置”中使用的终端)中,更改为应用程序目录并启动信使服务:

    cd app npm install node index.mjs messenger_service 监听端口 4000
    
  3. 启动第二个单独的终端会话(后续指令调用客户端终端)并向通讯服务发送POST请求。 错误消息表明请求已成功处理,因为请求主体在步骤 1 中设置的20 字节限制以下,但 JSON 负载的内容不正确:

    curl -d '{“text”:“hello”}'-H“Content-Type: 应用/json”-X POST http://localhost:4000/conversations ...{“error”: “对话必须有 2 个唯一用户”}
    
  4. 发送稍长的消息正文(再次在客户端)。 与步骤 3 相比,输出内容更多,包括一条错误消息,表明这次请求正文超过了 20 个字节:

    curl -d '{“text”:“hello, world”}'-H“Content-Type: 应用/json”-X POST http://localhost:4000/conversations ... \”PayloadTooLargeError:请求实体太大”
    

示例 2

此示例使用convict ,这是一个允许您在单个文件中定义整个配置“模式”的库。 它还说明了十二因素应用程序中因素 3 中的两个指导原则:

  • 将配置存储在环境变量中——您可以修改应用程序,以便使用环境变量( JSON_BODY_LIMIT )设置最大正文大小,而不是在应用程序代码中进行硬编码。
  • 明确定义您的服务配置– 这是对微服务第 3 因素的改编。 如果您不熟悉这个概念,我们建议您花点时间阅读我们博客上的“配置微服务应用程序的最佳实践”

该示例还设置了一些您将在挑战 2中利用的“管道”:您将在该挑战中创建的Messenger部署脚本设置了JSON_BODY_LIMIT环境变量,您可以在此处将该变量插入到应用程序代码中,作为部署脚本中指定的配置的说明。

  1. 打开罪犯配置文件app/config/config.mjs ,并在amqpport键后添加以下内容作为新键:

    jsonBodyLimit: { doc: `JSON 中间件将解析的最大大小(包含单位)。 单元解析由
    https://www.npmjs.com/package/bytes 库完成。
    例如: “100kb”,
    格式: 字符串,
    默认值:null,
    环境: "JSON_BODY_LIMIT",
    },
    

    当您在下面的第 3 步中在命令行上使用 convict 库来设置最大主体大小时, convict库会负责解析JSON_BODY_LIMIT环境变量:

    • 从正确的环境变量中提取值
    • 检查变量的类型( String
    • 在应用中通过jsonBodyLimit键启用对它的访问
  2. app/index.mjs中替换:

    app.use(express.json({限制: “20b” }));
    

    应用程序.使用(express.json({ 限制:config.get(“jsonBodyLimit”) }));
    
  3. 在应用程序终端(在示例 1的第 2 步中启动了信使服务的地方)中,按Ctrl+c停止该服务。 然后再次启动它,使用JSON_BODY_LIMIT环境变量将最大主体大小设置为 27 字节:

    ^cJSON_BODY_LIMIT=27b 节点索引.mjs
    

    这是对您的用例有意义时修改配置方法的一个示例 - 您已从在应用程序代码中硬编码一个值(在本例中为大小限制)切换到使用环境变量来设置它,正如十二因素应用程序所建议的那样。

    如上所述,在挑战 2中,当您使用信使服务的部署脚本来设置环境变量而不是在命令行上设置它时, JSON_BODY_LIMIT环境变量的使用将成为第二个配置位置的示例。

  4. 在客户端终端中,重复示例 1步骤 4中的curl命令(使用更大的请求主体)。 因为您现在已将大小限制增加到 27 个字节,所以请求正文不再超出限制,并且您会收到错误消息,表明请求已被处理,但 JSON 有效负载的内容不正确:

    curl -d '{“text”:“hello, world”}'-H“Content-Type: 应用/json”-X POST http://localhost:4000/conversations {“error”: “对话必须有 2 个唯一用户”}
    

    如果您愿意,您可以关闭客户端终端。 您将在应用程序终端中发出本教程其余部分的所有命令。

  5. 在应用程序终端中,按Ctrl+c停止信使服务(您已在上面的步骤 3 中在此终端中停止并重新启动了该服务)。

    ^c
    
  6. 停止messenger-database 。 您可以放心地忽略显示的错误消息,因为网络仍在由平台存储库中定义的基础架构元素使用。 在messenger repo 的根目录下运行此命令。

    docker compose down ...无法删除网络mm_2023....
    

挑战2: 为服务创建部署脚本

配置应该与代码严格分开(否则部署时怎么会有所不同?)
– 来自十二因素应用程序中的因素 3

乍一看,您可能会将其解释为“不要将配置签入源代码管理”。 在这个挑战中,您将为微服务环境实现一个常见的模式,该模式似乎违反了这条规则,但实际上它尊重这条规则,同时提供了对微服务环境至关重要的宝贵流程改进。

在这个挑战中,您将创建部署脚本来模拟基础设施即代码和部署清单的功能,这些清单为微服务提供配置,修改脚本以使用外部配置源,设置机密,然后运行脚本来部署服务及其基础设施。

您可以在messenger repo 中新创建的基础设施目录中创建部署脚本。 名为基础设施(或该名称的一些变体)的目录是现代微服务架构中的常见模式,用于存储以下内容:

这种模式的好处包括:

  • 它将服务部署的所有权和特定于服务的基础架构(例如数据库)的部署分配给拥有该服务的团队。
  • 团队可以确保对这些元素的任何更改都经过其开发过程(代码审查、CI 等)。
  • 该团队可以轻松更改服务及其支持基础设施的部署方式,而无需依赖外部团队为他们工作。

如前所述,本教程的目的不是展示如何建立真实系统,并且您在本次挑战中部署的脚本与真实生产系统并不相似。 相反,它们说明了在处理微服务相关的基础设施部署时通过特定工具的配置解决的一些核心概念和问题,同时将脚本抽象为尽可能最少的特定工具。

创建初始部署脚本

  1. 在应用程序终端中,在messenger repo 的根目录下创建一个基础设施目录,并创建文件来包含messenger服务和messenger-database 的部署脚本。 根据您的环境,您可能需要在chmod命令前加上sudo

    mkdir 基础设施cd 基础设施
    touch messenger-deploy.sh
    chmod +x messenger-deploy.sh
    touch messenger-db-deploy.sh
    chmod +x messenger-db-deploy.sh
    
  2. 在您喜欢的文本编辑器中,打开messenger-deploy.sh并添加以下内容,为messenger服务创建初始部署脚本:

    /bin/bashset -e JSON_BODY_LIMIT=20b docker run \ --rm \ -e JSON_BODY_LIMIT="${JSON_BODY_LIMIT} “信使
    

此脚本目前尚未完成,但它说明了几个概念:

  • 它通过将该配置直接包含在部署脚本中来为环境变量分配一个值。
  • 它使用docker run命令上的-e标志在运行时将环境变量注入容器中。

以这种方式设置环境变量的值似乎有些多余,但这意味着 - 无论这个部署脚本变得多么复杂 - 您都可以快速查看脚本的最顶部并了解配置数据是如何提供给部署的。

此外,虽然实际的部署脚本可能不会明确调用docker run命令,但此示例脚本旨在传达 Kubernetes 清单之类的程序所解决的核心问题。 当使用 Kubernetes 之类的容器编排系统时,部署会启动一个容器,并且从 Kubernetes 配置文件派生的应用程序配置将提供给该容器。 因此,我们可以将此示例部署文件视为部署脚本的最小版本,其作用与 Kubernetes 清单等框架特定的部署文件相同。

在实际的开发环境中,您可能会将此文件放入源代码控制中并进行代码审查。 这使您的团队的其他成员有机会对您的设置进行评论,从而有助于避免因配置错误的值导致意外行为的事件。 例如,在此屏幕截图中,团队成员正确地指出传入的 JSON 请求主体的 20 字节限制(使用JSON_BODY_LIMIT设置)太低。

代码审查的屏幕截图显示,消息正文的限制为 20 个字节太小

修改部署脚本以从外部源查询配置值

在挑战的这一部分,您将为微服务的配置设置第三个位置:在部署时查询的外部源。 在部署时动态注册值并从外部源获取它们比硬编码值要好得多,因为硬编码值必须不断更新并且可能会导致失败。 如需讨论,请参阅我们博客上的配置微服务应用程序的最佳实践

此时有两个基础设施组件在后台运行,为信使服务提供所需的辅助服务:

  1. RabbitMQ,在实际部署中由平台团队拥有(从设置的第 3 步开始)
  2. messenger-database ,由您的团队在实际部署中拥有(从设置的第 4 步开始)

app/config/config.mjs中的信使服务的罪犯模式定义了与这些外部配置相对应的所需环境变量。 在本节中,您将设置这两个组件,通过在可共同访问的位置设置变量的值来提供配置,以便信使服务在部署时可以查询它们。

RabbitMQ 和messenger-database所需的连接信息在Consul 键/值 (KV) 存储中注册,这是部署所有服务时可访问的公共位置。 Consul KV 存储不是存储此类数据的标准位置,但本教程为了简单起见使用它。

  1. infrastructure/messenger-deploy.sh的内容(在上一节第2步中创建)替换为以下内容:

    #!/bin/bashset -e #此配置需要新的提交才能更改NODE_ENV=production PORT=4000 JSON_BODY_LIMIT=100kb # 通过从系统中提取信息来配置 Postgres 数据库POSTGRES_USER=$(curl -X GET http://localhost:8500/v1/kv/messenger-db-application-user?raw=true) PGPORT=$(curl -X GET http://localhost:8500/v1/kv/messenger-db-port?raw=true) PGHOST=$(curl -X GET http://localhost:8500/v1/kv/messenger-db-host?raw=true) #通过从系统中提取信息来配置 RabbitMQ AMQPHOST=$(curl -X GET http://localhost:8500/v1/kv/amqp-host?raw=true) AMQPPORT=$(curl -X GET http://localhost:8500/v1/kv/amqp-port?raw=true) docker run \ --rm \ -e NODE_ENV="${NODE_ENV} “ \ -e 端口=”${PORT} “ \ -e JSON_BODY_LIMIT="${JSON_BODY_LIMIT} “ \ -e PGUSER="${POSTGRES_USER} “ \ -e PGPORT=”${PGPORT} “ \ -e PGHOST="${PGHOST} “ \ -e AMQPPORT =”${AMQPPORT} “ \ -e AMQPHOST="${AMQPHOST} “信使
    

    此脚本示例了两种类型的配置:

    • 直接在部署脚本中指定的配置——它设置部署环境( NODE_ENV )和端口( PORT ),并将JSON_BODY_LIMIT更改为 100 KB,这是一个比 20 字节更现实的值。
    • 从外部源查询的配置- 它从 Consul KV 存储中获取POSTGRES_USERPGPORTPGHOSTAMQPHOSTAMQPPORT环境变量的值。 您可以通过以下两个步骤设置 Consul KV 存储中的环境变量的值。
  2. 打开messenger-db-deploy.sh并添加以下内容,为messenger-database创建初始部署脚本:

    /bin/bashset -e PORT=5432 POSTGRES_USER=postgres docker run \ -d \ --rm \ --name messenger-db \ -v db-data:/var/lib/postgresql/data/pgdata \ -e POSTGRES_USER="${POSTGRES_USER} " \ -e POSTGRES_PASSWORD="${POSTGRES_PASSWORD} “ \ -e PGPORT=”${PORT} " \ -e PGDATA=/var/lib/postgresql/data/pgdata \ --network mm_2023 \ postgres:15.1 #使用 Consul 注册有关数据库的详细信息curl -X PUT http://localhost:8500/v1/kv/messenger-db-port \ -H "Content-Type: application/json" \ -d "${PORT} " curl -X PUT http://localhost:8500/v1/kv/messenger-db-host \ -H "Content-Type: application/json" \ -d 'messenger-db' #这与上面的 "--name" 标志匹配# (主机名) curl -X PUT http://localhost:8500/v1/kv/messenger-db-application-user \ -H "Content-Type: application/json" \ -d "${POSTGRES_USER} “
    

    除了定义部署时信使服务可以查询的配置之外,该脚本还说明了与创建初始部署脚本中的信使服务初始脚本相同的两个概念:

    • 它直接在部署脚本中指定某些配置,在这种情况下,告诉 PostgreSQL 数据库运行的端口和默认用户的用户名。
    • 它使用-e标志运行 Docker,以便在运行时将环境变量注入容器中。 它还将正在运行的容器的名称设置为messenger-db ,它将成为您在设置的第 2 步中启动平台服务时创建的 Docker 网络中数据库的主机名。
  3. 在实际部署中,通常是平台团队(或类似团队)负责平台存储库中 RabbitMQ 等服务的部署和维护,就像您对messenger存储库中的messenger-database所做的那样。 然后,平台团队确保依赖于该基础设施的服务能够发现该基础设施的位置。 出于本教程的目的,请自行设置 RabbitMQ 值:

    curl -X PUT --silent --output /dev/null --show-error --fail \ -H "内容类型:应用/json" \
    -d“rabbitmq” \
    <a href="http://localhost:8500/v1/kv/amqp-host">http://localhost:8500/v1/kv/amqp-host</a>
    
    curl -X PUT --silent --output /dev/null --show-error --fail \
    -H“内容类型:应用/json”\
    -d“5672” \
    <a href="http://localhost:8500/v1/kv/amqp-port">http://localhost:8500/v1/kv/amqp-port</a>
    

    (您可能想知道为什么使用amqp来定义 RabbitMQ 变量——这是因为AMQP是 RabbitMQ 使用的协议。)

在部署脚本中设置机密

信使服务的部署脚本中仅缺少一个(关键的)数据 -信使数据库的密码!

笔记: 秘密管理不是本教程的重点,因此为了简单起见,秘密在部署文件中定义。 切勿在实际环境中(开发、测试或生产)这样做,这会带来巨大的安全风险

要了解正确的机密管理,请查看 2023 年 3 月微服务的第 2 单元“微服务机密管理 101” 。 (剧透:秘密管理工具是存储秘密的唯一真正安全的方法)。

  1. infrastructure/messenger-db-deploy.sh的内容替换为以下内容,以将messenger-database的密码密钥存储在Consul KV存储中:

    #!/bin/bashset -e PORT=5432 POSTGRES_USER=postgres #注意: 在实际部署中切勿这样做。 存储密码
    # 仅在加密的秘密存储中。
    POSTGRES_PASSWORD = postgres docker run \ --rm \ --name messenger-db-primary \ -d \ -v db-data:/var/lib/postgresql/data/pgdata \ -e POSTGRES_USER="${POSTGRES_USER} " \ -e POSTGRES_PASSWORD="${POSTGRES_PASSWORD} “ \ -e PGPORT=”${PORT} " \ -e PGDATA=/var/lib/postgresql/data/pgdata \ --network mm_2023 \ postgres:15.1 echo "注册密钥 messenger-db-port\n" curl -X PUT --silent --output /dev/null --show-error --fail http://localhost:8500/v1/kv/messenger-db-port \ -H "Content-Type: application/json" \ -d "${PORT} " echo "注册密钥 messenger-db-host\n" curl -X PUT --silent --output /dev/null --show-error --fail http://localhost:8500/v1/kv/messenger-db-host \ -H "Content-Type: application/json" \ -d 'messenger-db-primary' #这与上面的 "--name" 标志匹配#对于我们的设置,它表示主机名echo "注册密钥 messenger-db-application-user\n" curl -X PUT --silent --output /dev/null --show-error --fail http://localhost:8500/v1/kv/messenger-db-application-user \ -H "Content-Type: application/json" \ -d "${POSTGRES_USER} “ echo “注册密钥 messenger-db-password-never-do-this\n” curl -X PUT --silent --output /dev/null --show-error --fail http://localhost:8500/v1/kv/messenger-db-password-never-do-this \ -H “Content-Type: application/json” \ -d “${POSTGRES_PASSWORD} “ printf “\​​n 已完成使用 Consul 注册 postgres 详细信息\n”
    
  2. Infrastructure/messenger-deploy.sh的内容替换为以下内容,以从 Consul KV 存储中获取messenger-database密码机密:

    #!/bin/bashset -e #此配置需要新的提交才能更改NODE_ENV=production PORT=4000 JSON_BODY_LIMIT=100kb # 通过从 #系统中提取信息来配置 Postgres 数据库POSTGRES_USER=$(curl -X GET http://localhost:8500/v1/kv/messenger-db-application-user?raw=true) PGPORT=$(curl -X GET http://localhost:8500/v1/kv/messenger-db-port?raw=true) PGHOST=$(curl -X GET http://localhost:8500/v1/kv/messenger-db-host?raw=true) #注意: 在实际部署中切勿这样做。 存储密码
    # 仅在加密的秘密存储中。
    PGPASSWORD=$(curl -X GET http://localhost:8500/v1/kv/messenger-db-password-never-do-this?raw=true) #通过从系统拉取的方式获取 RabbitMQ 配置AMQPHOST=$(curl -X GET http://localhost:8500/v1/kv/amqp-host?raw=true) AMQPPORT=$(curl -X GET http://localhost:8500/v1/kv/amqp-port?raw=true) docker run \ --rm \ -d \ -e NODE_ENV="${NODE_ENV} “ \ -e 端口=”${PORT} “ \ -e JSON_BODY_LIMIT="${JSON_BODY_LIMIT} “ \ -e PGUSER="${POSTGRES_USER} “ \ -e PGPORT=”${PGPORT} “ \ -e PGHOST="${PGHOST} “ \ -e PGPASSWORD="${PGPASSWORD} “ \ -e AMQPPORT =”${AMQPPORT} “ \ -e AMQPHOST="${AMQPHOST} “\ --network mm_2023 \ messenger
    

运行部署脚本

  1. 切换到messenger repo 中的应用程序目录并为messenger服务构建 Docker 镜像:

    cd../appdocker build-t messenger.
    
  2. 验证只有属于平台服务的容器正在运行:

    docker ps --format '{{.Names}}' consul-server consul-client rabbitmq
    
  3. 切换到messenger存储库的根目录并部署messenger 数据库messenger服务:

    cd .../基础设施/messenger-db-deploy.sh
    ./基础设施/messenger-deploy.sh
    

    messenger-db-deploy.sh脚本启动messenger-database并向系统注册适当的信息(在本例中是 Consul KV 存储)。

    然后, messenger-deploy.sh脚本启动应用并从系统(再次是 Consul KV 存储)中提取messenger-db-deploy.sh注册的配置。

    暗示: 如果容器启动失败,请删除部署脚本中docker run命令的第二个参数( -d \行),然后再次运行该脚本。 然后,容器在前台启动,这意味着它的日志出现在终端中并可能识别问题。 当您解决问题时,恢复-d \行,以便实际容器在后台运行。

  4. 向应用发送一个简单的健康检查请求来验证部署是否成功:

    curl 本地主机:4000/健康curl: (7)11毫秒后无法连接到本地主机端口4000: 连接被拒绝
    

    哎呀,失败了! 事实证明,您仍然缺少一个关键的配置,并且信使服务尚未暴露给更广泛的系统。 它在mm_2023网络中顺利运行,但该网络只能从 Docker 内部访问。

  5. 停止正在运行的容器,为下一个挑战中创建新的镜像做准备:

    docker rm $(docker stop $(docker ps -a -q --filter ancestor=messenger --format="{{.ID}}"))
    

挑战3: 向外界公开服务

在生产环境中,您通常不会直接公开服务。 相反,您遵循常见的微服务模式并在主服务前面放置反向代理服务。

在这个挑战中,您可以通过设置服务发现将消息服务公开给外界:注册新的服务信息并在其他服务访问时动态更新该信息。 为此,您可以使用以下技术:

  • Consul是一个动态服务注册中心, Consul 模板是一个基于 Consul 数据动态更新文件的工具
  • NGINX 开源,作为反向代理和负载平衡器,为您的消息服务公开一个入口点,该入口点由在容器中运行的应用的多个单独实例组成

要了解有关服务发现的更多信息,请参阅我们博客上的“配置微服务应用程序的最佳实践”中的“将服务用作配置”

设置 Consul

messenger repo 中的app/consul/index.mjs文件包含在启动时向 Consul 注册messenger服务以及在正常关闭时注销该服务所需的所有代码。 它公开一个函数register ,该函数使用 Consul 的服务注册表注册任何新部署的服务。

  1. 在您喜欢的文本编辑器中,打开app/index.mjs并在其他import语句后添加以下代码片段,以从app/consul/index.mjs导入register函数:

    从“。/consul/index.mjs”导入{注册为registerConsul};
    

    然后修改脚本末尾的SERVER START部分,如下所示,在应用启动后调用registerConsul()

    /* ================== 服务器启动 =================== */ app.listen(port, async () => { console.log(`messenger_service 正在监听端口${port}`); registerConsul(); }); 导出默认应用程序;
    
  2. app/config/config.mjs中打开罪犯模式,并在示例 2的步骤 1 中添加的jsonBodyLimit键后添加以下配置值。

      consulServiceName:{ doc: “该服务在 Consul 中注册的名称。 如果未指定,则服务未注册",
    格式:“*”,
    默认值:null,
    env: “CONSUL_SERVICE_NAME”,
    },
    consulHost: {
    doc: “Consul 客户端运行的主机”,
    格式: 字符串,
    默认值:“consul-client”,
    环境: “CONSUL_HOST”,
    },
    consulPort: {
    doc: “Consul 客户端的端口”,
    格式:“port”,
    默认值: 8500,
    环境: "CONSUL_PORT",
    },
    

    这将配置新服务注册的名称并定义 Consul 客户端的主机名和端口。 下一步,您将修改信使服务的部署脚本以包含这个新的 Consul 连接和服务注册信息。

  3. 打开infrastructure/messenger-deploy.sh并将其内容替换为以下内容,以将您在上一步中设置的Consul连接和服务注册信息包含在信使服务配置中:

    #!/bin/bashset -e #此配置需要新的提交才能更改NODE_ENV=production PORT=4000 JSON_BODY_LIMIT=100kb CONSUL_SERVICE_NAME="messenger" # Consul 主机和端口包含在每个主机中,因为我们在了解它们之前无法查询 Consul CONSUL_HOST="${CONSUL_HOST} “ CONSUL_PORT=”${CONSUL_PORT} " # 通过从系统中提取信息来配置 Postgres 数据库POSTGRES_USER=$(curl -X GET "http://localhost:8500/v1/kv/messenger-db-application-user?raw=true") PGPORT=$(curl -X GET "http://localhost:8500/v1/kv/messenger-db-port?raw=true") PGHOST=$(curl -X GET "http://localhost:8500/v1/kv/messenger-db-host?raw=true") #注意: 在实际部署中切勿这样做。 存储密码
    # 仅在加密的秘密存储中。
    PGPASSWORD=$(curl -X GET "http://localhost:8500/v1/kv/messenger-db-password-never-do-this?raw=true") #通过从系统拉取的方式获取 RabbitMQ 配置AMQPHOST=$(curl -X GET "http://localhost:8500/v1/kv/amqp-host?raw=true") AMQPPORT=$(curl -X GET "http://localhost:8500/v1/kv/amqp-port?raw=true") docker run \ --rm \ -d \ -e NODE_ENV="${NODE_ENV} “ \ -e 端口=”${PORT} “ \ -e JSON_BODY_LIMIT="${JSON_BODY_LIMIT} “ \ -e PGUSER="${POSTGRES_USER} “ \ -e PGPORT=”${PGPORT} “ \ -e PGHOST="${PGHOST} “ \ -e PGPASSWORD="${PGPASSWORD} “ \ -e AMQPPORT =”${AMQPPORT} “ \ -e AMQPHOST="${AMQPHOST} " \ -e CONSUL_HOST="${CONSUL_HOST} “ \ -e CONSUL_PORT="${CONSUL_PORT} “ \ -e CONSUL_SERVICE_NAME="${CONSUL_SERVICE_NAME} “\ --network mm_2023 \ messenger
    

    主要需要注意的是:

    • CONSUL_SERVICE_NAME环境变量告诉消息服务实例在向 Consul 注册时使用什么名称。
    • CONSUL_HOSTCONSUL_PORT环境变量用于在部署脚本运行位置运行的 Consul 客户端。

    笔记: 在实际部署中,这是一个必须由团队之间达成一致的配置示例 - 负责 Consul 的团队必须在所有环境中提供CONSUL_HOSTCONSUL_PORT环境变量,因为如果没有此连接信息,服务就无法查询 Consul。

  4. 在应用程序终端中,切换到应用程序目录,停止所有正在运行的Messenger服务实例,然后重建 Docker 映像以嵌入新的服务注册代码:

    cd appdocker rm $(docker stop $(docker ps -a -q --filter ancestor=messenger --format="{{.ID}}"))
    docker build -t messenger .
    
  5. 在浏览器中导航到http://localhost:8500来查看 Consul UI 的实际运行(尽管目前还没有任何有趣的事情发生)。

  6. messenger存储库的根目录中,运行部署脚本来启动messenger服务的实例:

    CONSUL_HOST=consul-client CONSUL_PORT=8500./infrastructure/messenger-deploy.sh
    
  7. 在浏览器的 Consul UI 中,单击标题栏中的“服务”以验证单个消息服务是否正在运行。

    Consul UI Services 选项卡,其中分别包含一个 Consul 和 Messenger 服务实例

  8. 再运行几次部署脚本来启动更多信使服务实例。 在 Consul UI 中验证它们是否正在运行。

    CONSUL_HOST=consul-client CONSUL_PORT=8500./infrastructure/messenger-deploy.sh
    

    Consul UI 的“messenger”选项卡包含该服务的五个实例

设置NGINX

下一步是添加 NGINX Open Source 作为反向代理和负载均衡器,以将传入流量路由到所有正在运行的消息传递实例。

  1. 在应用程序终端中,将目录更改为messenger repo 的根目录并创建一个名为load-balancer的目录和三个文件:

    mkdir load-balancercd load-balancer
    touch nginx.ctmpl
    touch consul-template-config.hcl
    touch Dockerfile
    

    Dockerfile定义了 NGINX 和 Consul 模板运行的容器。 当消息服务在其服务注册表中发生变化(服务实例启动或关闭)时,Consul 模板使用另外两个文件来动态更新 NGINX 上游。

  2. 打开步骤1中创建的nginx.ctmpl文件,添加以下NGINX配置片段,Consul模板使用该片段动态更新NGINX上游组:

    上游 messenger_service { {{- 范围服务“messenger”}}
    服务器 {{ .Address }}:{{ .Port }};
    {{- end }}
    }
    
    服务器 {
    listen 8085;
    server_name localhost;
    
    location / {
    proxy_pass http://messenger_service;
    add_header 上游主机 $upstream_addr;
    }
    }
    

    此代码片段将在 Consul 中注册的每个消息服务实例的 IP 地址和端口号添加到 NGINX messenger_service上游组。 NGINX 将传入的请求代理到动态定义的上游服务实例集。

  3. 打开第1步中创建的consul-template-config.hcl文件,添加以下配置:

    consul { 地址 = "consul-client:8500"
    
    重试 {
    enabled = true
    尝试次数 = 12
    退避 = "250ms"
    }
    }
    模板 {
    源 = "/usr/templates/nginx.ctmpl"
    目标 = "/etc/nginx/conf.d/default.conf"
    权限 = 0600
    命令 = "如果 [ -e /var/run/nginx.pid ]; 那么 nginx -s reload; 否则 nginx; fi"
    }
    

    这个 Consul 模板配置告诉它重新渲染模板(上一步中创建的 NGINX 配置片段),将其放置在指定的目的地,最后运行指定的命令(告诉 NGINX 重新加载其配置)。

    实际上,这意味着每次在 Consul 中注册、更新或取消注册服务实例时都会创建一个新的default.conf文件。 然后,NGINX 会在没有停机的情况下重新加载其配置,确保 NGINX 拥有一组最新的、健康的服务器(消息服务实例),可以向其发送流量。

  4. 打开步骤1中创建的Dockerfile文件,添加以下内容,构建NGINX服务。 (出于本教程的目的,您不需要了解Dockerfile ,但为了方便起见,代码已在线记录。)

    FROM nginx:1.23.1 ARG CONSUL_TEMPLATE_VERSION=0.30.0 #为 Consul # 集群的位置设置环境变量。 默认情况下,它会尝试解析为 consul-client:8500
    # 如果 Consul 作为容器运行,则会出现以下行为: 
    # 同一主机并链接到此 NGINX 容器(使用别名 
    # 当然是领事了。 但是这个环境变量也可以
    # 如果我们想解析为
    # 另一个地址。
    
    ENV CONSUL_URL consul-client:8500 #下载指定版本的Consul模板ADD https://releases.hashicorp.com/consul-template/${CONSUL_TEMPLATE_VERSION} /consul-template_${CONSUL_TEMPLATE_VERSION} _linux_amd64.zip /tmp 运行 apt-get update \ && apt-get install -y --no-install-recommends dumb-init unzip \ && unzip /tmp/consul-template_${CONSUL_TEMPLATE_VERSION} _linux_amd64.zip -d /usr/local/bin \ && rm -rf /tmp/consul-template_${CONSUL_TEMPLATE_VERSION} _linux_amd64.zip 复制 consul-template-config.hcl ./consul-template-config.hcl 复制 nginx.ctmpl /usr/templates/nginx.ctmpl 暴露 8085 STOPSIGNAL SIGQUIT CMD ["dumb-init", "consul-template", "-config=consul-template-config.hcl"]
    
  5. 构建 Docker 映像:

    docker build-t messenger-lb 。
    
  6. 更改为messenger目录的根目录,创建一个名为messenger-load-balancer-deploy.sh的文件作为 NGINX 服务的部署文件(就像您在整个教程中部署的其余服务一样)。 根据您的环境,您可能需要在chmod命令前加上sudo

    cd ..
    touch 基础设施/messenger-load-balancer-deploy.sh
    chmod +x 基础设施/messenger-load-balancer-deploy.sh
    
  7. 打开messenger-load-balancer-deploy.sh ,添加以下内容:

    #!/bin/bashset -e # Consul 主机和端口包含在每个主机中,因为我们#在了解它们之前无法查询 Consul CONSUL_HOST="${CONSUL_HOST} “ CONSUL_PORT=”${CONSUL_PORT} “docker run \ --rm \ -d \ --name messenger-lb \ -e CONSUL_URL="${CONSUL_HOST} :${CONSUL_PORT} “ \ -p 8085:8085 \ --network mm_2023 \ messenger-lb
    
  8. 现在一切就绪,请部署 NGINX 服务:

    CONSUL_HOST=consul-客户端 CONSUL_PORT=8500./infrastructure/messenger-load-balancer-deploy.sh
    
  9. 查看您是否可以从外部访问信使服务:

    curl -X GET http://localhost:8085/health确定
    

    有用! NGINX 现在正在所有已创建的通讯服务实例之间进行负载均衡。 您可以判断,因为X-Forwarded-For标头显示的通讯服务 IP 地址与上一节步骤 8中的 Consul UI 中的 IP 地址相同。

挑战4: 使用服务作为作业运行器来迁移数据库

大型应用通常使用带有小型工作进程的“作业运行器”,可用于执行修改数据等一次性任务(例如SidekiqCelery )。 这些工具通常需要额外的支持基础设施,例如RedisRabbitMQ 。 在这种情况下,您可以使用信使服务本身作为“作业运行器”来运行一次性任务。 这是有道理的,因为它已经很小了,完全能够与数据库和它所依赖的其他基础设施进行交互,并且与服务流量的应用完全分开运行。

这样做有三个好处:

  1. 作业运行器(包括它运行的脚本)经过与生产服务完全相同的检查和审查过程。
  2. 可以轻松更改数据库用户等配置值,以使生产部署更加安全。 例如,您可以使用只能从现有表中写入和查询的“低权限”用户运行生产服务。 您可以配置不同的服务实例,以能够创建和删除表的更高权限用户的身份更改数据库结构。
  3. 一些团队从处理服务生产流量的实例中运行作业。 这很危险,因为作业问题可能会影响容器中的应用正在执行的其他功能。 我们首先实施微服务就是为了避免这样的事情,不是吗?

在这个挑战中,您将探索如何通过更改某些数据库配置值并迁移Messenger数据库以使用新值并测试其性能来修改工件以填充新角色。

迁移 Messenger 数据库

对于实际的生产部署,您可能会创建两个具有不同权限的不同用户:“应用用户”和“迁移者用户”。 为简单起见,在此示例中,您使用默认用户作为应用用户,并创建具有超级用户权限的迁移器用户。 在实际情况下,值得花费更多时间根据用户的角色来决定每个用户需要哪些特定的最低权限。

  1. 在应用程序终端中,创建一个具有超级用户权限的新 PostgreSQL 用户:

    echo “使用超级用户密码‘migrator_password’创建用户 messenger_migrator;” | docker exec -i messenger-db-primary psql -U postgres
    
  2. 打开数据库部署脚本( infrastructure/messenger-db-deploy.sh )并替换其内容以添加新用户的凭据。

    笔记: 让我们花点时间重申一下——对于实际部署,切勿将数据库凭据等机密信息放在部署脚本中或机密信息管理工具以外的任何地方。 详情请参见第二单元: 微服务秘密管理 101微服务 2023 年 3 月。

    #!/bin/bash set -e PORT=5432 POSTGRES_USER=postgres #注意: 在实际部署中切勿这样做。 存储密码
    # 仅在加密的秘密存储中。
    # 因为本教程中我们重点介绍其他概念,所以我们
    # 为了方便起见,请在此处以此方式设置密码。
    POSTGRES_PASSWORD=postgres #迁移用户POSTGRES_MIGRATOR_USER=messenger_migrator #注意: 如上所述,在实际部署中切勿这样做。
    POSTGRES_MIGRATOR_PASSWORD =migrator_password docker run \ --rm \ --name messenger-db-primary \ -d \ -v db-data:/var/lib/postgresql/data/pgdata \ -e POSTGRES_USER="${POSTGRES_USER} " \ -e POSTGRES_PASSWORD="${POSTGRES_PASSWORD} “ \ -e PGPORT=”${PORT} " \ -e PGDATA=/var/lib/postgresql/data/pgdata \ --network mm_2023 \ postgres:15.1 echo "注册密钥 messenger-db-port\n" curl -X PUT --silent --output /dev/null --show-error --fail http://localhost:8500/v1/kv/messenger-db-port \ -H "Content-Type: application/json" \ -d "${PORT} " echo "注册密钥 messenger-db-host\n" curl -X PUT --silent --output /dev/null --show-error --fail http://localhost:8500/v1/kv/messenger-db-host \ -H "Content-Type: application/json" \ -d 'messenger-db-primary' #这与上面的 "--name" 标志匹配#对于我们的设置,它表示主机名echo "注册密钥 messenger-db-application-user\n" curl -X PUT --silent --output /dev/null --show-error --fail http://localhost:8500/v1/kv/messenger-db-application-user \ -H "Content-Type: application/json" \ -d "${POSTGRES_USER} “ curl -X PUT --silent --output /dev/null --show-error --fail http://localhost:8500/v1/kv/messenger-db-password-never-do-this \ -H “内容类型:application/json” \ -d “${POSTGRES_PASSWORD} “ echo “注册密钥 messenger-db-application-user\n” curl -X PUT --silent --output /dev/null --show-error --fail http://localhost:8500/v1/kv/messenger-db-migrator-user \ -H “Content-Type: application/json” \ -d “${POSTGRES_MIGRATOR_USER} “ curl -X PUT --silent --output /dev/null --show-error --fail http://localhost:8500/v1/kv/messenger-db-migrator-password-never-do-this \ -H “内容类型:application/json” \ -d “${POSTGRES_MIGRATOR_PASSWORD} “ printf “\​​n 已完成使用 Consul 注册 postgres 详细信息\n”
    

    此更改只是将迁移者用户添加到数据库部署后在 Consul 中设置的用户集中。

  3. 基础架构目录中创建一个名为messenger-db-migrator-deploy.sh的新文件(同样,您可能需要在chmod命令前加上sudo ):

    触摸基础设施/messenger-db-migrator-deploy.shchmod +x基础设施/messenger-db-migrator-deploy.sh
    
  4. 打开messenger-db-migrator-deploy.sh并添加以下内容:

    #!/bin/bashset -e #此配置需要新的提交才能更改NODE_ENV=production PORT=4000 JSON_BODY_LIMIT=100kb CONSUL_SERVICE_NAME="messenger-migrator" # Consul 主机和端口包含在每个主机中,因为我们在了解它们之前无法查询 Consul CONSUL_HOST="${CONSUL_HOST} “ CONSUL_PORT=”${CONSUL_PORT} " #获取迁移器用户名和密码POSTGRES_USER=$(curl -X GET "http://localhost:8500/v1/kv/messenger-db-migrator-user?raw=true") PGPORT=$(curl -X GET "http://localhost:8500/v1/kv/messenger-db-port?raw=true") PGHOST=$(curl -X GET http://localhost:8500/v1/kv/messenger-db-host?raw=true) #注意: 在实际部署中切勿这样做。 存储密码
    # 仅在加密的秘密存储中。
    PGPASSWORD=$(curl -X GET "http://localhost:8500/v1/kv/messenger-db-migrator-password-never-do-this?raw=true") #通过从系统拉取的方式获取 RabbitMQ 配置AMQPHOST=$(curl -X GET "http://localhost:8500/v1/kv/amqp-host?raw=true") AMQPPORT=$(curl -X GET "http://localhost:8500/v1/kv/amqp-port?raw=true") docker run \--rm \-d \--name messenger-migrator \-e NODE_ENV="${NODE_ENV} “ \ -e 端口=”${PORT} “ \ -e JSON_BODY_LIMIT="${JSON_BODY_LIMIT} “ \ -e PGUSER="${POSTGRES_USER} “ \ -e PGPORT=”${PGPORT} “ \ -e PGHOST="${PGHOST} “ \ -e PGPASSWORD="${PGPASSWORD} “ \ -e AMQPPORT =”${AMQPPORT} “ \ -e AMQPHOST="${AMQPHOST} " \ -e CONSUL_HOST="${CONSUL_HOST} “ \ -e CONSUL_PORT="${CONSUL_PORT} “ \ -e CONSUL_SERVICE_NAME="${CONSUL_SERVICE_NAME} “\ --network mm_2023 \ messenger
    

    该脚本与您在“设置 Consul”第 3 步中创建的最终形式的Infrastructure/messenger-deploy.sh脚本非常相似。 主要区别在于CONSUL_SERVICE_NAMEmessenger-migrator而不是messenger ,并且PGUSER对应于您在上面的步骤 1 中创建的“migrator”超级用户。

    重要的是CONSUL_SERVICE_NAMEmessenger-migrator 。 如果将其设置为messenger ,NGINX 将自动轮流使用此服务来接收 API 调用,并且它不会处理任何流量。

    该脚本以迁移器的角色部署了一个短暂的实例。 这可以防止迁移问题影响主消息服务实例的流量服务。

  5. 重新部署 PostgreSQL 数据库。 由于您在本教程中使用bash脚本,因此您需要停止并重新启动数据库服务。 在生产应用中,您通常只运行基础架构即代码脚本,仅添加已更改的元素。

    docker stop messenger-db-primaryCONSUL_HOST=consul-client CONSUL_PORT=8500./infrastructure/messenger-db-deploy.sh
    
  6. 部署 PostgreSQL 数据库迁移器服务:

    CONSUL_HOST=consul-客户端 CONSUL_PORT=8500 ./infrastructure/messenger-db-migrator-deploy.sh
    
  7. 验证实例是否按预期运行:

    docker ps --format "{{.Names}}" ... messenger-migrator
    

    您还可以在 Consul UI 中验证数据库迁移器服务是否已在 Consul 中正确注册为messenger-migrator (再次强调,它没有以messenger名称注册,因为它不处理流量):

    Consul UI Services 选项卡,其中各有一个 consul 和 messenger-migrator 服务实例,以及四个 messenger 服务实例

  8. 现在进行最后一步——运行数据库迁移脚本! 这些脚本与任何真正的数据库迁移脚本都不一样,但是它们确实使用messenger-migrator服务来运行特定于数据库的脚本。 数据库迁移完成后,停止messenger-migrator服务:

    docker exec -i -e PGDATABASE=postgres -e CREATE_DB_NAME=messenger messenger-migrator node scripts/create-db.mjsdocker exec -i messenger-migrator node scripts/create-schema.mjs
    docker exec -i messenger-migrator node scripts/create-seed-data.mjs
    docker stop messenger-migrator
    

测试 Messenger 服务的实际效果

现在您已将信使数据库迁移到其最终格式,信使服务终于可以供您查看了! 为此,您需要针对 NGINX 服务运行一些基本的curl查询(您在设置 NGINX中将 NGINX 配置为系统的入口点)。

以下一些命令使用jq来格式化 JSON 输出。 您可以根据需要安装它,或者如果愿意的话从命令行中省略它。

  1. 创建对话:

    curl -d '{"participant_ids": [1, 2]}' -H "Content-Type: 应用/json" -X POST 'http://localhost:8085/conversations' { "conversation": { "id": “1”,“插入位置”: “ YYYY - MM - DD T06:41:59.000Z” } }
    
  2. 向 ID 为 1 的用户发送一条消息到对话中:

    curl -d '{"内容": “这是第一条消息”}'-H“User-Id: 1” -H“Content-Type: 应用/ json” -X POST'http://localhost:8085 / conversations / 1 / messages'| jq {“消息”:{“ id”: "1", "内容": “这是第一条消息”,“索引”: 1,“用户ID”: 1、“用户名”: “詹姆斯·布兰德电话”,“conversation_id”: 1,“插入位置”: “ YYYY - MM - DD T06:42:15.000Z” } }
    
  3. 使用其他用户(ID 2)的消息回复:

    curl -d '{"内容": “这是第二条消息”}'-H“User-Id: 2” -H“Content-Type: 应用/ json” -X POST'http://localhost:8085 / conversations / 1 / messages'| jq {“消息”:{“ id”: "2", "内容": “这是第二条消息”,“索引”: 2,“用户ID”: 2、“用户名”: “Normalavian Ropetoter”,“对话 ID”: 1,“插入位置”: “ YYYY - MM - DD T06:42:25.000Z” } }
    
  4. 获取消息:

    curl -X GET 'http://localhost:8085/conversations/1/messages' | jq { “消息”:[ { “id”: "1", "内容": “这是第一条消息”,“user_id”: “1”,“频道编号”: “1”,“索引”: “1”,“插入位置”: “ YYYY - MM - DD T06:42:15.000Z”,“用户名”: “詹姆斯·布兰德电话”},{“id”: "2", "内容": “这是第二条消息”,“user_id”: “2”,“频道 ID”: “1”,“索引”: “2”,“插入位置”: “ YYYY - MM - DD T06:42:25.000Z”,“用户名”: “Normalavian Ropetoter” } ] }
    

清理

在本教程中,您已经创建了大量容器和图像! 使用以下命令删除您不想保留的任何 Docker 容器和图像。

  • 要删除所有正在运行的 Docker 容器:

    docker rm $(docker stop $(docker ps -a -q --filter ancestor=messenger --format="{{.ID}}"))docker rm $(docker stop messenger-db-primary)
    docker rm $(docker stop messenger-lb)
    
  • 要删除平台服务:

    #从平台存储库docker compose down
    
  • 要删除本教程中使用的所有 Docker 镜像:

    docker rmi messengerdocker rmi messenger-lb
    docker rmi postgres:15.1
    docker rmi hashicorp/consul:1.14.4
    docker rmi rabbitmq:3.11.4-management-alpine
    

下一步

您可能会想“设置一些简单的东西似乎需要做很多工作”——您是对的! 转向以微服务为中心的架构需要对如何构建和配置服务进行细致的考量。 尽管存在诸多复杂性,您仍然取得了一些扎实的进展:

  • 您设置了一个以微服务为中心的配置,其他团队可以轻松理解。
  • 您设置的微服务系统在所涉及的各种服务的扩展和使用方面都具有一定的灵活性。

要继续您的微服务教育,请查看 2023 年 3 月的微服务。 第 2 单元“微服务机密管理 101”提供了微服务环境中机密管理的深入且用户友好的概述。


“这篇博文可能引用了不再可用和/或不再支持的产品。 有关 F5 NGINX 产品和解决方案的最新信息,请探索我们的NGINX 产品系列。 NGINX 现在是 F5 的一部分。 所有之前的 NGINX.com 链接都将重定向至 F5.com 上的类似 NGINX 内容。”