JavaScript 的服务网格:驯服微服务混乱(2024版)

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

当微服务变成一场噩梦

\n

想象一下:你成功地将单体应用拆解成了十几个基于 Node.js 的微服务。每个服务负责自己的任务——身份验证、商品目录、购物车、支付。一切都很美好,直到真正的“乐趣”开始:服务宕机、请求丢失、超时增加、日志分散在五个不同的仪表板上。熟悉吗?

\n

你从通过 axios 进行简单的 HTTP 请求开始,但现在每个服务都需要知道所有其他服务的地址,处理重试、熔断器和负载均衡。代码变成了基础设施逻辑的意大利面条。正是在这里,Service Mesh 登场了——这是一种架构模式,它将所有网络魔法从你的 JavaScript 代码中抽离出来。

\n

在本文中,我们将探讨 Service Mesh 在 JavaScript 和 Node.js 上下文中的工作原理,编写与流行解决方案(Envoy、Istio、Linkerd)集成的真实代码,并理解这种复杂性何时是合理的。开始吧!

\n\n

什么是 Service Mesh,为什么 JavaScript 开发者需要它

\n

Service Mesh 是一个专门用于微服务间通信的基础设施层。与其将服务发现、负载均衡、加密和监控逻辑嵌入到每个 JavaScript 服务中,不如将其提取到一个“sidecar”代理中,该代理与你的应用程序的每个实例一起运行。

\n

对于 Node.js 开发者来说,这意味着:

\n
    \n
  • 干净的业务逻辑代码——你只需编写 Express/Koa/Fastify 处理器,所有网络魔法都被隐藏了。
  • \n
  • 自动负载均衡——请求在实例之间分配,无需额外的库。
  • \n
  • 开箱即用的可靠性——重试、超时、熔断器都可以声明式配置。
  • \n
  • 可观测性——追踪、指标和日志自动收集。
  • \n
\n

最酷的是:你不受语言限制。Service Mesh 在网络层工作,因此你的 JavaScript 服务可以与 Go 服务、Python 服务或遗留的 Java 单体应用通信——代理会让一切透明化。

\n\n

Service Mesh 架构:Sidecar 容器和控制平面

\n

经典的 Service Mesh 由两部分组成:

\n

数据平面

\n

你的每个微服务(例如,运行在 3000 端口的 Node.js 应用程序)都与一个 sidecar 代理(通常是 Envoy 或 Linkerd-proxy)一起运行。所有入站和出站请求都通过这个代理:

\n
// 通过 sidecar 进行路由的示例\n// 你的服务监听 localhost:3000\n// Sidecar 监听 localhost:8080 并转发流量\n\n// 在生产环境中,你永远不会直接访问另一个服务\n// 相反,你向 localhost:8080/service-name 发送请求\n\nconst axios = require('axios');\n\n// 没有 Service Mesh(不好)\n// const userService = 'http://user-service:4000';\n\n// 使用 Service Mesh(好)—— 向 sidecar 发起请求\nconst userService = 'http://localhost:8080'; \n\nasync function getUser(id) {\n    const response = await axios.get(`${userService}/users/${id}`);\n    return response.data;\n}
\n

代理会自动找到正确的 user-service 实例,平衡负载并应用安全策略。

\n\n

控制平面

\n

这是系统的“大脑”。例如,Istio 使用 Pilot、Mixer 和 Citadel 组件来管理配置、收集遥测数据和颁发证书。你用 YAML 描述路由规则,控制平面将这些规则分发到所有 sidecar 代理。

\n\n

实践示例:Node.js + Envoy + Istio

\n

让我们创建一个真实的配置。我们将有两个基于 Express 的微服务:order-service 和 payment-service。我们不会硬编码彼此的 URL,而是使用 Service Mesh。

\n\n

步骤 1:编写

博客

书籍推荐