使用 AWS Copilot、Amazon ECS、Docker 和 AWS Fargate 将单体应用程序分解为多个微服务

模块 3:拆分单体应用程序

概述

最终的应用程序架构使用 Amazon ECS 和应用程序负载均衡器 (ALB)。

a. 客户端 – 客户端通过端口 80 发送流量请求。

b. 负载均衡器 – ALB 将外部流量路由到正确的服务。ALB 检查客户端请求,并使用路由规则将请求定向到与规则匹配的目标组的实例和端口。

c. 目标组 – 每个服务都有一个目标组,用于跟踪为该服务运行的每个容器的实例和端口。

d. 微服务 – Amazon ECS 将每个服务部署到 EC2 集群中的容器内。每个容器只处理单个功能。

为什么要使用微服务?

崩溃隔离

即使是最优秀的工程组织,在生产环境中也难免会发生严重崩溃。除了遵循所有标准最佳实践来优雅地处理崩溃之外,构建微服务是一种可以限制此类崩溃影响的方法。良好的微服务架构意味着,如果服务的一个微小部分发生崩溃,只有该部分服务会停止运行。服务的其余部分可以继续正常运行。

安全隔离

在单体应用程序中,如果应用程序的一个功能存在安全漏洞,例如允许远程代码执行的漏洞,那么必须假设攻击者也可以访问系统的每个其他功能。例如,如果头像上传功能存在安全问题,最终可能会危及存储用户密码的数据库,这可能很危险。使用 Amazon ECS 将功能拆分为微服务,可以通过为每个服务分配自己的 AWS Identity and Access Management (IAM) 角色来保护对 AWS 资源的访问。在遵循微服务最佳实践的情况下,即使攻击者入侵了一个服务,他们也只能访问该服务的资源,而无法在不入侵其他服务的情况下横向访问其他服务的资源。

独立扩展

将功能拆分为一些微服务后,每个微服务类使用的基础设施数量和实例数量可以独立地进行扩展。这样可以更容易衡量特定功能的成本,并确定可能需要首先优化的功能。如果某个特定功能在资源需求方面出现问题,其他功能不会受到影响,并且可以保持可靠的性能。

开发速度

微服务可降低开发风险,使团队能够加快构建速度。在单体应用程序中,添加新功能可能会影响单体应用中的所有其他功能。开发人员必须仔细考虑他们添加的任何代码的影响,并确保不会破坏任何其他功能。而正确的微服务架构会将新功能的新代码放入新服务中。开发人员可以放心地编写任何代码,而无需担心其影响现有代码,除非他们明确地在两个微服务之间建立连接。

学习目标

在本模块中,您将把 Node.js 应用程序拆分为几个相互连接的服务,并为每个微服务创建一个 AWS Copilot 服务。

 时长

20 分钟

 使用的服务

AWS Copilot

操作步骤

请按照以下分步指南拆分单体应用程序。 

步骤 1:创建服务

在上一个模块中,您创建并部署了 api 应用程序和 api 环境。您可以复用这些来部署微服务。在本模块中,应用程序的代码已被划分为三个微服务:posts、threads 和 users。每个微服务都将部署为一个服务。monolith 服务是使用 CLI 菜单部署的。在本模块中,您可以通过为 copilot svc init 命令指定 flag 来部署服务。首先创建 post 微服务。

$ copilot svc init --app api --dockerfile ./3-microservices/services/posts/Dockerfile --name posts --svc-type "Load Balanced Web Service"

✔ Wrote the manifest for service posts at copilot/posts/manifest.yml
Your manifest contains configurations like your container size and port (:3000).

- Update regional resources with stack set "microservices-infrastructure"  [succeeded]  [0.0s]
Recommended follow-up actions:
  - Update your manifest copilot/posts/manifest.yml to change the defaults.
  - Run `copilot svc deploy --name posts --env test` to deploy your service to a test environment.

对 threads 和 users 微服务重复相同步骤。

$ copilot svc init --app api --dockerfile ./3-microservices/services/threads/Dockerfile --name threads --svc-type "Load Balanced Web Service"

$ copilot svc init --app api --dockerfile ./3-microservices/services/users/Dockerfile --name users --svc-type "Load Balanced Web Service"

步骤 2:在 manifest.yml 中编辑每个微服务的路径。

AWS Copilot 根据服务名称设置服务的路径。但是,server.js 中微服务的路径是 api/<服务名>。在每个微服务清单中编辑路径,并在路径中添加 api/。
# Distribute traffic to your service.
http:
  # Requests to this path will be forwarded to your service.
  # To match all requests you can use the "/" path.
  path: 'api/posts'

下一项:部署微服务