此方案说明了如何构建一个解决方案,该解决方案可在 Web 视图中处理基础数据更改,而无需使用实时服务进行页刷新。 使用此方案的示例包括对产品和货物的实时跟踪,以及社交媒体解决方案。
体系结构
下载此体系结构的 Visio 文件。
组件
- Azure 服务总线是应用程序和服务之间的一个非常可靠的云消息服务(即使一个或多个应用程序和服务处于脱机状态)。
- Azure SignalR 服务,用于为 Web 应用程序轻松添加实时通信功能。
- Azure Functions 是事件驱动的无服务器计算平台,也可以解决复杂的业务流程问题。
备选方法
这种方案的现有替代方法包括 Pusher。 它是供应用开发人员构建可缩放实时通信功能的可靠 API 方面的领导者。
此外还有 PubNub。 借助 PubNub,可以轻松地将实时功能添加到应用,而无需担心基础结构。 构建使用户能够在移动设备、浏览器、桌面和服务器之间实时参与的应用。
Ably 是另一种替代方案。 它提供无服务器发布/订阅 (pub/sub) 消息传递,可根据需求可靠缩放。 使用 WebSocket 在边缘处传递消息。 Ably 平台通过 API 调用提供高度可用、可弹性缩放且全局分布的实时基础结构。
尽管 Pusher、PubNub 和 Ably 是最广泛采用的实时消息传递平台,但对于此方案,你将在 Azure 中执行所有操作。 建议使用 SignalR 作为首选平台,因为它允许服务器和客户端之间的双向通信。 它也是一种开源工具,具有 7.9 K 个 GitHub 星和 2.2 K 个 GitHub 分支。
有关详细信息,请参阅 GitHub 上的 SignalR 开源存储库。
方案详细信息
在此方案中,你将了解如何设置实时消息服务,以便共享外卖服务交易的实时位置。 对于尝试为 Web 或移动应用程序构建实时位置共享平台的用户,此示例也非常有用。
你将使用 SignalR 服务,该服务在无服务器模式下配置,以便与服务总线触发的 Azure Functions 应用进行集成;所有这些都通过使用 .NET Core 实现。
可能的用例
以下其他用例都采用类似的设计模式:
- 与客户端设备共享实时位置
- 向用户推送通知
- 更新时间线
- 创建聊天室
注意事项
这些注意事项实施 Azure 架构良好的框架的支柱原则,即一套可用于改进工作负载质量的指导原则。 有关详细信息,请参阅 Microsoft Azure 架构良好的框架。
下面是开发此方案时要考虑的一些注意事项,包括如何在 ServiceBusTrigger 中配置 Azure 服务总线连接字符串中的参数:
- 中心:中心与视频流式处理服务类似。 你可以订阅该中心,以便从/向中心发送/接收消息。
- 目标:目标与收音机频道类似。 他们包括正在收听目标频道的每个人,在该频道上有新消息时,他们都会得到通知。
如果可以记住 SignalR 平台的上述两个功能,就可以轻松地快速启动和运行。
可用性、可伸缩性和安全性
通过遵循下面两部分所描述的方法,可以使用该解决方案实现高可用性。
区域配对
每个 Azure 区域都与同一地域内的另一个区域配对。 通常,请选择同一区域对中的区域(例如“美国东部 2”和“美国中部”)。 这样做的好处包括:
- 如果发生大范围的故障,会优先恢复每个区域对中的至少一个区域。
- 计划内 Azure 系统更新会按顺序提供给配对的区域,以尽可能减少停机时间。
- 在多数情况下,区域对位于同一地域内以满足数据驻留要求。
- 但请确保两个区域都支持你的应用程序所需的全部 Azure 服务。 请参阅服务(按区域)。 有关区域对的详细信息,请参阅业务连续性和灾难恢复 (BCDR):Azure 配对区域。
Azure Front Door
下载此体系结构的 Visio 文件。
Azure Front Door 是一个可缩放的安全入口点,用于快速交付全局应用程序。 当使用“优先级路由”时,如果主区域不可用,它会自动进行故障转移。 与部署到单个区域相比,多区域体系结构可以提供更高的可用性。 如果区域性故障影响主要区域,可以使用 Front Door 来故障转移到次要区域。
当解决方案的单个子系统出现故障时,此体系结构可能也很有用。 使用 Web 应用程序防火墙和 DDoS 防护在边缘停止网络和应用程序层攻击。 使用 Microsoft 托管规则集强化服务,并创建自己的规则以便对应用进行自定义保护。
Front Door 是系统中的一个潜在故障点。 如果服务出现故障,则客户端在停机期间无法访问应用程序。 查看 Front Door 服务级别协议 (SLA),然后确定仅使用 Front Door 是否能满足企业对高可用性的需求。 如果不能,请考虑添加另一个流量管理解决方案作为故障回复机制。 如果 Front Door 服务出现故障,请将 DNS 中的规范名称 (CNAME) 记录更改为指向另一个流量管理服务。 此步骤必须手动执行,并且在传播 DNS 更改之前,应用程序将不可用。
成本优化
成本优化是关于寻找减少不必要的费用和提高运营效率的方法。 有关详细信息,请参阅成本优化支柱概述。
假设企业每天有 1000 个订单,并且需要同时与所有订单共享位置数据。 根据发布日期的定价,估计用于部署此方案的 Azure 使用量将接近每月 192 美元。
服务类型 | 预估每月成本 |
---|---|
Azure Functions | 119.40 美元 |
Azure SignalR 服务 | 48.97 美元 |
Azure 服务总线 | 23.71 美元 |
总计 | 192.08 美元 |
部署此方案
Azure Functions 开发
使用 Azure Functions 和 Azure SignalR 服务构建的无服务器实时应用程序通常需要两个 Azure Functions:
- 一个
negotiate
函数,客户端调用该函数来获取有效的 SignalR 服务访问令牌和服务终结点 URL。 - 一个或多个用于发送消息或管理组成员身份的函数。
SignalRFunctionApp
SignalRFunctionApp 是一个函数应用,该应用创建带有服务总线触发器并使用 SignalR 的 Azure Functions 实例。
Negotiate.cs
此函数由 HTTP 请求触发。 客户端应用程序使用此函数来从 SignalR 服务获取令牌,客户端可使用该令牌来订阅中心。 此函数应命名为 negotiate
。 有关详细信息,请参阅通过 Azure SignalR 服务进行的 Azure Functions 开发和配置。
Message.cs
此函数由服务总线触发器触发。 它与 SignalR 服务绑定。 它从队列中提取消息,并将其传递给 SignalR 中心。
Instructions
开始之前:
- 请确保在 Azure 上预配了服务总线队列。
- 请确保在 Azure 上以无服务器模式预配了 SignalR 服务。
- 在 local.settings.json 文件中输入连接字符串(服务总线和 SignalR)。
- 在 CORS 中输入客户端应用程序(SignalR 客户端)的 URL。 有关最新的语法,请参阅通过 Azure SignalR 服务进行的 Azure Functions 开发和配置。
- 在 Message.cs 文件内的服务总线触发器中输入服务总线队列名称。
现在,让我们配置客户端应用程序来测试它。 首先,从解决方案体系结构 GitHub 页面获取示例源。
SignalR 客户端
这是一个简单的 .NET Core Web 应用程序,用于订阅由 SignalRFunctionApp 创建的中心。 它实时显示在服务总线队列中接收的消息。 可以通过 SignalRFunctionApp 来使用移动客户端,但在此存储库中,我们将坚持使用 Web 客户端。
说明
确保 SignalRFunctionApp 正在运行。
复制 Negotiate 函数生成的 URL。 如下所示:
http://localhost:7071/api/
。将 URL 粘贴到 chat.js 文件中,放置到
signalR.HubConnectionBuilder().withUrl("YOUR_URL_HERE").build();
内部。运行应用程序。
Web 客户端成功订阅 SignalR 中心时,状态为“已连接”。
SendToQueue.js
此 node.js 脚本可将消息推送到服务总线,以便你可以测试刚刚完成的部署。
Instructions
安装节点 Azure 服务总线模块 (@azure/service-bus)。
在脚本中输入连接字符串和队列名称。
运行该脚本。
后续步骤
你可以将此方案应用于生产环境。 但是,请确保 Azure 服务设置为可缩放。 例如,Azure 服务总线应设置为标准或高级计划。
可以直接从 Visual Studio 向 Azure Functions 部署代码。 若要了解如何将代码从 Visual Studio 发布到 Azure Functions,请遵循软件开发方法指南。
请参阅如何在 Azure Functions 中使用 Azure 服务总线绑定。 Azure Functions 支持对服务总线队列和主题的触发器和输出绑定。
请参阅如何在 Azure Functions 中使用 SignalR 服务绑定进行身份验证,并向连接到 Azure SignalR 服务的客户端发送实时消息。 Azure Functions 支持 SignalR 服务的输入和输出绑定。