前端客户端通信

小窍门

此内容摘自电子书《为 Azure 架构云原生 .NET 应用程序》,可在 .NET 文档 查阅或下载免费的 PDF 离线阅读。

Azure 平台的云原生 .NET 应用电子书封面缩略图。

在云原生系统中,前端客户端(移动、Web 和桌面应用程序)需要信道才能与独立的后端微服务进行交互。

有哪些选项?

为简单起见,前端客户端可以直接与后端微服务 通信 ,如图 4-2 所示。

将客户端定向到服务通信

图 4-2. 客户端与服务的直接通信

使用此方法,每个微服务都有一个可供前端客户端访问的公共终结点。 在生产环境中,将负载均衡器放置在微服务前面,并按比例路由流量。

虽然易于实现,但直接客户端通信仅适用于简单的微服务应用程序。 此模式紧密耦合前端客户端到核心后端服务,为许多问题打开大门,包括:

  • 客户端容易受到后端服务重构的影响。
  • 核心后端服务由于直接暴露,攻击面更加广泛。
  • 各项微服务中的横切关注点重复。
  • 过于复杂的客户端代码 - 客户端必须跟踪多个终结点,并以弹性方式处理故障。

相反,广为接受的云设计模式是在前端应用程序和后端服务之间实现 API 网关服务 。 图 4-3 中显示了模式。

API 网关模式

图 4-3. API 网关模式

在上图中,请注意 API 网关服务如何抽象后端核心微服务。 它作为 Web API 实现,充当 反向代理,将传入流量路由到内部微服务。

网关使客户端免受内部服务分区和重构的隔离。 如果更改后端服务,可以在网关中容纳它,而不会中断客户端。 这也是横切关注点(例如标识、缓存、复原能力、计量和限制)的第一道防线。 其中许多交叉问题可以从后端核心服务卸载到网关,从而简化后端服务。

必须小心,使 API 网关保持简单快捷。 通常,业务逻辑保留在网关外。 复杂的网关面临着变成瓶颈并最终成为单体应用本身的风险。 较大的系统通常公开多个按客户端类型(移动、Web、桌面)或后端功能分段的 API 网关。 Backend for Frontends模式为实现多个网关提供了指导。 图 4-4 中显示了模式。

服务于前端的后端模式

图 4-4. 服务于前端的后端模式

请注意,上图中如何根据客户端类型(Web、移动或桌面应用)将传入流量发送到特定 API 网关。 此方法很有意义,因为每个设备的功能在外形规格、性能和显示限制方面存在显著差异。 通常,移动应用程序公开的功能少于浏览器或桌面应用程序。 可以优化每个网关,以匹配相应设备的能力和功能。

简单网关

首先,可以生成自己的 API 网关服务。 快速搜索 GitHub 将提供许多示例。

对于简单的 .NET 云原生应用程序,可以考虑 Ocelot 网关。 开源和为 .NET 微服务创建,它是轻量级、快速、可缩放的。 与任何 API 网关一样,其主要功能是将传入的 HTTP 请求转发到下游服务。 此外,它还支持在 .NET 中间件管道中可配置的各种功能。

YARP (另一个反向代理)是由一组Microsoft产品团队领导的另一个开源反向代理。 YARP 可以作为 NuGet 包下载,并以中间件的形式插入到 ASP.NET 框架中,且具有高度自定义功能。 你会发现 YARP 记录详尽并附有各种用法示例。

对于企业云原生应用程序,有几个托管的 Azure 服务可帮助快速启动工作。

Azure 应用程序网关

对于简单的网关要求,可以考虑 Azure 应用程序网关。 它作为 Azure PaaS 服务提供,包括基本的网关功能,例如 URL 路由、SSL 终止和 Web 应用程序防火墙。 该服务支持 第 7 层负载均衡 功能。 使用第 7 层,可以根据 HTTP 消息的实际内容(而不仅仅是低级别 TCP 网络数据包)路由请求。

在本书中,我们倡导在 Kubernetes 上托管云原生系统。 容器编排器 Kubernetes 自动化管理容器化工作负载的部署、缩放和运维问题。 可将 Azure 应用程序网关配置为 Azure Kubernetes 服务 群集的 API 网关。

应用程序网关入口控制器使 Azure 应用程序网关能够直接使用 Azure Kubernetes 服务。 图 4.5 显示了体系结构。

应用程序网关入口控制器

图 4-5. 应用程序网关入口控制器

Kubernetes 包含支持 HTTP(级别 7)负载均衡的内置功能,称为 入口。 Ingress 定义了一组规则,用于说明如何对外暴露 AKS 中的微服务实例。 在上一个映像中,入口控制器解释为群集配置的入口规则,并自动配置 Azure 应用程序网关。 根据这些规则,应用程序网关将流量路由到 AKS 中运行的微服务。 入口控制器侦听对入口规则的更改,并相应地更改 Azure 应用程序网关。

Azure API 管理

对于中等到大规模的云原生系统,可以考虑 使用 Azure API 管理。 它是一种基于云的服务,不仅解决了 API 网关的需求,而且还提供功能齐全的开发人员和管理体验。 API 管理如图 4-6 所示。

Azure API 管理

图 4-6. Azure API 管理

首先,API 管理会公开一个网关服务器,该服务器允许基于可配置的规则和策略对后端服务的受控访问。 这些服务可以位于 Azure 云、本地数据中心或其他公有云中。 API 密钥和 JWT 令牌决定谁可以执行哪些操作。 所有流量都记录用于分析目的。

对于开发人员,API 管理提供开发人员门户,提供对服务、文档和示例代码的访问权限,以便调用它们。 开发人员可以使用 Swagger/Open API 来检查服务终结点并分析其使用情况。 该服务适用于主要开发平台:.NET、Java、Golang 等。

发布者门户公开管理仪表板,其中管理员公开 API 并管理其行为。 可以授予服务访问权限、监视服务运行状况以及收集的服务遥测数据。 管理员将 策略 应用于每个终结点以影响行为。 策略 是针对每个服务调用按顺序执行的预生成语句。 可为入站和出站调用配置策略,也可在出现错误时调用策略。 可以在不同的服务范围内应用策略,以便在合并策略时启用确定性排序。 该产品自带大量预制策略

下面是策略如何影响云原生服务行为的示例:

  • 限制服务访问。
  • 强制实施身份验证。
  • 如有必要,限制来自单个源的调用。
  • 启用缓存。
  • 阻止来自特定 IP 地址的调用。
  • 控制服务流程。
  • 将请求从 SOAP 转换为 REST,或在不同的数据格式(例如从 XML 转换为 JSON)之间。

Azure API 管理可以公开托管在云或数据中心的任何位置的后端服务。 对于可能在云原生系统中公开的旧服务,它支持 REST 和 SOAP API。 甚至可以通过 API 管理公开其他 Azure 服务。 可以将托管 API 放置在 Azure 支持服务(如 Azure 服务总线Azure 逻辑应用)之上。 Azure API 管理不包括内置的负载均衡支持,应与负载均衡服务结合使用。

Azure API 管理跨四个不同的层提供:

  • 开发 人员
  • 基本
  • 标准
  • 高级版

开发人员层适用于非生产工作负荷和评估。 其他层提供越来越强大的功能,以及更高的服务级别协议(SLA)。 高级层提供 Azure 虚拟网络多区域支持。 所有级别每小时都有固定价格。

Azure 云还提供 Azure API 管理的 无服务器层 。 服务称为 消耗定价层,是围绕无服务器计算模型设计的 API 管理变体。 与前面显示的“预分配”定价层不同,消耗层提供即时预配和按作付费定价。

它为以下用例启用 API 网关功能:

  • 使用无服务器技术(如 Azure FunctionsAzure 逻辑应用)实现的微服务。
  • Azure 后备服务资源(如服务总线队列和主题、Azure 存储等)。
  • 流量偶尔出现大峰值但大多数时间都很低的微服务。

消耗层使用相同的基础服务 API 管理组件,但基于动态分配的资源采用完全不同的体系结构。 它与无服务器计算模型完全一致:

  • 没有要管理的基础结构。
  • 无闲置容量。
  • 高可用性。
  • 自动缩放。
  • 成本基于实际使用情况。

对于将无服务器资源公开为 API 的云原生系统来说,新的消耗层是一个不错的选择。

实时通信

实时或推送通信是前端应用程序通过 HTTP 与后端云原生系统通信的另一个选项。 应用程序(如财务滴答程序、在线教育、游戏和工作进度更新)需要来自后端的即时实时响应。 使用正常的 HTTP 通信时,客户端无法知道何时提供新数据。 客户端必须持续 轮询 或向服务器发送请求。 通过 实时 通信,服务器可以随时将新数据推送到客户端。

实时系统通常以高频率数据流和大量并发客户端连接为特征。 手动实现实时连接可能会变得复杂,需要非普通基础结构来确保将可伸缩性和可靠的消息传送传送到连接的客户端。 你会发现自己正在管理 Azure Redis 缓存的实例和一组负载均衡器,这些负载均衡器配置了粘滞会话,用于进行客户端关联。

Azure SignalR 服务 是一项完全托管的 Azure 服务,可简化云原生应用程序的实时通信。 技术实现的详细信息,例如容量预配、扩展和持久连接,都会被简化和隐藏。 它们按 99.9% 的服务级别协议进行处理。 你专注于应用程序功能,而不是基础结构管道。

启用后,基于云的 HTTP 服务可以将内容更新直接推送到连接的客户端,包括浏览器、移动和桌面应用程序。 客户会自动更新,无需轮询服务器。 Azure SignalR 对创建实时连接的传输技术(包括 WebSockets、服务器端事件和长轮询)进行抽象化。 开发人员专注于将消息发送到已连接客户端的所有或特定子集。

图 4-7 显示了一组连接到已启用 Azure SignalR 的云原生应用程序的 HTTP 客户端。

Azure SignalR

图 4-7. Azure SignalR

Azure SignalR 服务的另一个优势是实现无服务器云原生服务。 也许代码是按需使用 Azure Functions 触发器执行的。 此方案可能很棘手,因为代码不会与客户端保持长时间的连接。 Azure SignalR 服务可以处理这种情况,因为该服务已经为你管理了连接。

Azure SignalR 服务与其他 Azure 服务(例如 Azure SQL 数据库、服务总线或 Redis 缓存)紧密集成,为云原生应用程序开辟了许多可能性。