OpenTelemetry演示应用的前端重构(转向Next.js)

博客文章在发布后不会更新。这篇文章已经发布一年多了,其内容可能已过时,部分链接可能无效。在依赖任何信息之前,请务必核实。

OpenTelemetry 项目的众多特别兴趣小组(SIG)之一是OpenTelemetry 社区演示 SIG。该 SIG 支持一套已仪器化的微服务和一个前端 Web 应用,用于展示如何使用 OpenTelemetry 仪器化分布式系统。

Web 应用的主要重点是演示如何仪器化应用程序,无论其使用何种编程语言、平台或操作系统。Web 应用还展示了不同的仪器化技术:自动和手动、指标和 Baggage。所有这些都遵循官方 OTel 文档中规定的标准和约定。有关具体要求的更多信息可在此处找到。

我公司致力于成为 OpenTelemetry 社区的一部分并拥抱它。我们今年夏天的目标之一是更深入地参与一个核心 OpenTelemetry 项目,以便我们能够做出有意义的贡献。OTel 演示是实现我们目标的最匹配项目,因为贡献不仅能帮助社区,还能为我们测试和展示我们的产品提供绝佳的示例。

我们做的第一件事是与 OTel Demo SIG 的组织者 Carter Socha 联系。Carter 非常热情,并帮助我们确定了我们的贡献可能最有影响力的领域。我们开始查看 Austin Parker 创建的 issue,该 issue 引用了一项全面的前端重构,涉及将应用程序从 Go 服务器端渲染(SSR)迁移到一个包含浏览器端客户端(客户端渲染或 CSR)的架构,并改进整体样式、主题和用户体验。

这项工作的一个有趣之处在于,要求将商店从“普通”商店迁移到一个天文商店,以匹配 OpenTelemetry 项目的整体品牌形象。

一旦我们得到了 OTel Demo SIG 其他成员的许可,我们就开始着手进行前端架构重构中的各项更改。

OpenTelemetry 演示应用描述和技术栈

演示应用是一个天文商店,具有基本的电子商务功能,如购物车、货币选择器、支付和结账。它还能够根据用户的上下文显示促销(广告)和相关产品。

该演示的应用栈包括多种语言的多个微服务,涵盖了 OTel 支持的每种语言。

每个微服务都有一个特定的目标,并可以通过使用全局 gRPC 定义进行通信。持久化信息保存在 PostgreSQL 数据库中,并且有外部服务连接到第三方服务以触发事件(例如确认电子邮件)。所有微服务(包括前端)都连接到同一个 OpenTelemetry Collector 实例,该实例使用 Jaeger 作为跟踪数据的数据存储之一。

OpenTelemetry Demo System Diagram OpenTelemetry Demo Technology List

在重新架构之前,前端是一个 Golang SSR 应用,它将完整的 HTML 发送到浏览器进行显示。每次请求和调用都会重定向到服务器,以便显示新信息。

Web 应用样式改进、主题更新和用户体验重新设计

在开发过程开始之前,前端应用在颜色、产品和整体用户体验方面与 OpenTelemetry 使用的主题不匹配。此外,该演示缺乏真正的 Web 前端(浏览器端)应用程序,因为当前的实现是一个 Go 应用程序。

OpenTelemetry Demo Old Front-end

首要任务是通过更新设计、配色方案和用户体验,将演示应用带入现代化。Olly Babiak 加入进来,通过创建应用程序的现代化版本来帮助我们实现这一点。它包括改进的产品列表页面显示方式、更新的产品详情页面、迷你购物车以及完全兼容的移动版本应用程序。

OpenTelemetry Demo New Front-end

现在,我们拥有了一个与 OpenTelemetry 其他主题和颜色相匹配的设计,看起来更像 OpenTelemetry.io 网站。

前端应用架构重构

我们进行了一项初步提案,其中包括以下内容:

  • 框架和工具(脚手架、I/O、样式、UI 库)
  • 代码架构和结构(目录、编码模式)
  • 仪表化
  • 部署与分发
  • 测试(E2E、单元测试)

该提案在每周一的会议上向 OpenTelemetry Demo SIG 进行了演示,并获得了继续推进的许可。作为更改的一部分,我们决定使用 Next.js,它不仅作为主要的前端应用程序,还作为前端和 gRPC 后端服务之间的聚合层。

New Front-end Data Flow

正如您在图表中看到的,该应用程序有两个主要的连接点:一个来自浏览器端(REST)连接到 Next.js 聚合层,另一个从聚合层连接到后端服务(gRPC)。

OpenTelemetry 仪器化

我们接下来进行的大项目是仪器化 Next.js 应用的双方。为此,我们必须将应用程序连接到所有微服务使用的同一个 Collector 两次。

使用 官方 gRPC exporter 结合 Node.js SDK 设计了一个简单的后端解决方案。

您可以在此处找到完整的实现。基本仪器化包括对大多数常用的 Node.js 库和工具的自动仪器化。作为提供更好用户示例的一部分,添加了路由中间件形式的手动仪器化。这将捕获传入的 HTTP 请求并基于它创建一个 Span,包括上下文传播。您可以在此处找到实现。

前端稍微复杂一些,因为 初始渲染是服务器端的。我们必须确保在 JavaScript 代码执行时从浏览器端加载 Tracer。

在添加了检查浏览器端的验证后,我们加载了自定义的前端跟踪模块,其中包括创建 Web Tracer Provider 和自动 Web 仪器化

自动前端仪器化捕获最常见的用户操作,如点击、Fetch 请求和页面加载。为了让浏览器端能够与 Collector 交互,需要进行配置更改:启用 Web 应用的传入 CORS 请求。

设置完成后,通过从 Docker 加载应用程序并与不同功能进行交互,我们可以开始查看从前端用户事件到后端 gRPC 服务的完整跟踪。

Front-end Trace Jaeger Visualization

为 OpenTelemetry 做贡献是很有价值的

作为一个专注于在可观测性领域构建开源工具的团队,为 OpenTelemetry 社区整体做出贡献的机会对我们来说非常重要。此外,拥有一个使用多种不同语言和技术的复杂微服务应用程序对我们的团队直接有用。我们非常享受为 OpenTelemetry 项目做出贡献的过程,并积极寻求更多贡献的机会!

Oscar ReyesOlly Babiak 也在开发 Tracetest,这是一个开源工具,允许您使用 OpenTelemetry 开发和测试分布式系统。它适用于任何兼容 OTel 的系统,并支持创建基于跟踪的测试。请在 https://github.com/kubeshop/tracetest 查看。