写点什么

无服务器 WebSocket:开启实时数据传递新时代

作者: Matthew O’Riordan

  • 2023-03-07
    北京
  • 本文字数:4848 字

    阅读完需:约 16 分钟

无服务器WebSocket:开启实时数据传递新时代

实时数据传递的兴起

 

我们的日常数字体验正在经历一场变革:实时数据。

 

现在,用户希望应用程序或浏览器中的页面无需刷新就能更新状态——例如,显示实时体育比分的应用程序或在地图上跟踪快递进度的网页。

 

我们都已经习惯了即时的数字体验,我们理所当然地认为应用程序和网页可以提供流畅的交互式服务,没有延迟。提供无缝实时更新体验来吸引用户的组织可以获得更高的用户参与度和更多的页面停留时间,还有潜在的再次访问和业务上的好处。如果没有无缝的实时更新,用户体验就会显得过时,并有失去市场份额的风险。

 

本文通过示例对一些最常见的实时用户体验进行了比较,讨论了支持实时更新的事件驱动架构,并介绍了常见的技术选项。

 

据估计,到 2025 年,全球30%的消费数据将来自实时信息交换,因为预计将有 1500 亿台设备连接并创建实时数据。随着企业寻求相对于竞争对手的运营优势,它们开始关注实时体验。在最近的一项调查中,一些 IT 行业的领先者告诉 IDC,在有助于实现实时决策的技术上投入是当务之急。

实时的定义

 

人类平均眨眼时间为 100 毫秒,平均反应时间约为 250 毫秒。因此,在 250 毫秒以内发生的任何事情都被认为是“实时”的。

 

操作系统对硬件有不同的要求,“硬实时”的内核承诺延迟小于 5 毫秒。另一个要求低延迟的领域是多人游戏,它要求延迟低于 50 毫秒。在本文中,我们要讨论的实时是一种符合人类对“瞬时”理解的实时。

常见的实时用户体验

实时体验

 

许多人都熟悉这种实时体验——根据内容或数据的变化,实时数据从源向用户单向传递。

 

这类例子包括:

 

  • 在线购物网站,显示商品库存数量或商品存放在其他用户购物篮中的数量;

  • 作为对银行帐户活动的反映,即时更新银行应用程序;

  • 将体育和新闻更新发送到应用程序或网页上。

实时体验的例子:Reddit

 

Reddit 是全球访问量最大的 20 个网站之一,它最近推出的实时更新功能表明,在与 Facebook 等其他在线社区的竞争中,实时体验具有重要的战略意义。Reddit App 用户现在可以看到其他 Reddit 用户的活动,比如当其他 Reddit 用户在阅读同一篇文章或输入回复时会显示动画和提示。除此之外,还有其他的一些实时功能。

共享的实时体验

 

当实时数据双向流动时,就形成了共享的实时体验。打字聊天消息的传递就是一个典型的例子。其他的例子还包括民意调查、测验和问答,例如在 Twitch 流媒体直播中,参与者可以与主持人互动。

共享的实时体验示例:Mentimeter

 

Mentimeter可以作为直播的一个补充环节,可用于进行民意调查或测验。例如,主持人可以问观众:“你们最喜欢的曼达洛人角色是哪一个?”参与者可以打开一个短 URL,并进行在线投票,他们的回答会被实时可视化,并在直播中显示。

协作体验

 

协作体验类似于共享的实时体验,但通常使用点对点通信,用户可以实时编辑共享的状态和数据。一个典型的例子是我们在远程工作中使用的协作生产力工具,如 Figma、Google Docs 或 Miro。

协作体验示例:Figma

 

Figma是一个协作设计工具,允许多个用户同时处理一个文件。它被称为“设计协作的分水岭”和设计软件的变革者

 

用户可以直接共享 Figma 文件的链接,不需要下载或发送文件,也不需要离线编辑和合并修改。对于文档、电子表格和演示文稿的协作来说,这些已经相对标准化了,但对于复杂的设计软件来说,这是一种新的工作方式。



对于许多组织(无论是现有的头部公司还是挑战者)来说,被Adobe以破纪录的200亿美元收购的 Figma 是一个有趣的案例。共享的实时和协作体验是未来趋势,没有实时功能的产品需要找到一种方法来引入这些功能。

 

通常,当我们讲到实时体验时,我们想到的是速度和延迟,但实时交互的根本在于架构。

基于事件驱动的实时架构

 

对于一个成功的实时解决方案,你需要考虑采用事件驱动模型。在事件驱动模型中,事件表示可能触发客户端(或事件消费者)执行某些操作的变更,例如更新 UI。事件将作为消息通过事件通道传递给消费者。事件生成器负责传递反映数据或状态实时变化的事件。

 

事件驱动系统的典型模式是“发布和订阅”。当状态发生变化时,事件生产者(发布者)发送事件消息,事件订阅者可以消费这些消息,并做出响应时执行业务逻辑。

用于实时解决方案的协议

 

在事件驱动架构中,事件消费者需要能够异步地接收更新。可供选择的协议包括:

 

  • HTTP长轮询——服务器保持客户端连接处于打开状态,在新数据可用或连接超时时发送响应。

  • WebSocket——通过持久 TCP 连接提供双向、全双工通信通道,开销要比半双工替代方案(如 HTTP 长轮询)低得多

  • MQTT——用于在 CPU 功率或电池寿命有限的设备(如物联网设备)之间传输数据的首选协议。

  • SSE——用于事件驱动数据流的轻量级开放协议(仅订阅)。

 

WebSocket 可以说是使用最为广泛的支持实时用户体验的协议。WebSocket 于 2011 年实现标准化(RFC 6455),它是建立在TCP/IP协议栈之上的一个薄传输层。

 

WebSocket 的出现标志着 Web 开发的一个转折点。WebSocket 连接是为事件驱动架构而设计的,并针对最小化开销和延迟进行了优化,它通过持久的单套接字连接实现了客户端和服务器之间的双向全双工通信,并尽可能接近原始的 TCP 通信层。

 

与HTTP相比,WebSocket 连接提高了效率,可伸缩性更好。WebSocket 协议是基于推送的,因此一旦有事件发生,连接的客户端就会收到更新。



用于事件驱动系统的 WebSocket

 

我们有几种方法可以将 WebSocket 集成到我们的技术栈中。

 

第一种方法是从头开始构建一个基于 WebSocket 的消息传递解决方案,并根据需要对其进行定制。例如,DAZN 使用 WebSocket 协议设计了一个自定义解决方案,用于向数百万用户广播消息。



另一种方法是使用 WebSocket 开源项目作为消息传递层的主干。Socket.IO是一个基于原始 WebSocket 构建的框架,提供了额外的功能,比如支持回退、自动重连和发布/订阅消息(房间)。一种常见的方法是结合使用 Socket.IO 和Redis Pub/Sub,在不同的进程或服务器上运行多个 Socket.IO 实例,并在节点之间传递事件。



然而,这种方法仍然存在一些限制,例如缺乏消息排序、有限的原生安全性和单区域可用性设计。因此,要在生产环境中大规模使用Socket.IO仍然存在很大的挑战。

为实时数据构建 WebSocket 解决方案所面临的挑战

 

上面描述的两种 WebSockets 集成方式都存在工程方面的挑战,可能会影响项目成本和交付期限。从表面上看,构建 WebSocket 解决方案就是从添加接收实时更新的功能开始。然而,随着功能的演进,基本的实时体验会延伸出共享实时体验和协作功能等额外需求。

 

为这些实时体验构建和维护一个专有的 WebSocket 解决方案可能极具挑战性。支撑解决方案的基础设施必须稳定可靠,需要有经验的工程师来构建和维护。开发团队可能会更关注实时需求方面的东西,而不是增强核心产品的特性,并面临可伸缩性和弹性、延迟、容错以及数据完整性和连接管理等工程挑战。

可伸缩性和弹性

 

为了能够可靠地处理数百万个并发 WebSocket 连接,解决方案需要具备可伸缩性,这是一项复杂且耗时的工作,需要专门的工程资源、大量的基础设施成本和时间。

 

水平伸缩带来了更复杂的架构、负载均衡、路由以及基础设施和维护成本的增加,这些还只是其中的一部分挑战。

 

为了能够成功地处理规模不可预测的 WebSocket 连接,解决方案还需要具备弹性,让系统能够自动添加更多的服务器,有足够的容量来处理潜在的流量高峰。

延迟

 

网络延迟是大规模分布式系统中的一个关键因素。延迟随着距离的增加而增加,因此为了保持较低的网络延迟,建议借助托管数据中心和边缘加速点让数据尽可能地靠近用户。良好的用户体验还需要尽量减少延迟抖动。

容错

 

要让系统具备容错能力,必须要有服务实例甚至数据中心冗余。这意味着至少要将基础设施分布到同一地区的多个可用性区域,甚至分布到多个地区。这涉及大量的工程和 DevOps 工作以及与基础设施相关的成本。

数据完整性和连接管理

 

事件驱动架构依赖了事件消息序列,要求没有消息丢失或没有的无序消息。

 

如果用户设备断电或网络出了问题,则可能导致连接中断。当用户重新连接时,需要从断开连接的点继续处理事件。系统需要在不重复已处理消息的情况下传递遗漏的消息。整个过程必须是完全无缝的。

 

所以还需要解决一些复杂的工程问题,以保证消息排序和精确一次语义所需的数据完整性。

DIY 的困境

 

一些组织试图尽早发布产品,将这些困难的问题留到以后解决。但是,如果产品无法满足它创造出来的需求,那么迅速进入市场并获得早期成功可能会弄巧成拙。

 

另一种选择是尽早进行伸缩性设计,并为未来的增长建立可持续的架构。但这种方法可能会导致延迟进入市场,成为竞争对手的可乘之机。另一个常见的问题是,最初的设计会在产品获得足够的市场反馈以了解其发展方向之前就已经在产品中加入了重大的限制。

无服务器 WebSocket 的优势

 

一个可行的解决方案是将构建业务关键型实时平台的复杂性转移到专门的云服务上。全托管的无服务器 WebSocket 解决方案为基于事件驱动的消息传递提供了基础设施,它将底层基础设施变成了商品。用户使用提供者服务发送/接收低延迟消息,并专注于构建业务逻辑来处理实时更新。

 

将 WebSocket 技术与无服务器模型结合起来有几个好处:

 

  • 无需维护基础设施——构建专有的 WebSocket 基础设施既耗时又耗费资源。无服务器 WebSocket 提供商减轻了管理实时基础设施的负担。

  • 降低运营成本——大多数无服务器 WebSocket 提供商都提供按使用付费的定价模型。这比预先租用或购买固定数量的服务器容量更具成本效益,后者通常会存在大量未充分使用或空闲的时间。

  • 可伸缩性和可用性——无服务器 WebSocket 架构在设计上是可伸缩的。使用无服务器基础设施构建的应用程序可能会遇到很大其波动的流量,需要基础设施能够自动伸缩以处理不可预测且快速变化的并发 WebSocket 连接。

  • 降低延迟——在无服务器模型中,应用程序并不是托管在原始的服务器上。这意味着,根据无服务器 WebSocket 基础设施提供商的设置,无服务器应用程序可能会在全球多个地区和边缘位置的用户附近运行,从而提高了性能并降低了延迟。

无服务器 WebSocket 解决方案

 

一些云供应商提供了无服务器 WebSocket 解决方案,如AWS AppSyncAWS API GatewayCloudflare WorkersGoogle Cloud RunAzure Web PubSub。然而,这些解决方案并没有提供一个完整的端到端解决方案来处理最常见的场景,具体例子见DAZN对AWS AppSync和AWS API Gateway的评测

 

一些平台,如AblyPusher,致力于帮助组织应对在采用无服务器 WebSocket 事件驱动架构时面临的挑战,并添加了额外的功能来解决常见的痛点。

 

例如,它们很少只使用一个通用的协议,因为不同的协议可以更好地实现某些目的。Ably 提供了多种协议,如 WebSocket、MQTT、SSE 和 HTTP,并且还扩展了原始协议之外的功能,如设备状态、流历史、通道回流和处理连接突然断开。

 

采用供应商提供的端到端无服务器 WebSocket 平台有很多好处,因为它们可以应对处理大规模实时数据时所面临的挑战,让工程团队可以专注于核心产品创新,不需要操心与实时基础设施相关的问题。

总结

 

实时体验由实时、事件驱动的 API 提供支撑,可以满足现代终端用户的需求。

 

稳定的低延迟、数据完整性(顺序和传递保证)、容错、可用性和可伸缩性是实时系统的基础,并不是每个组织都有能力处理好构建可靠和不间断体验的复杂性。

 

新一代提供无服务器 WebSocket 的 PaaS 可以促进架构、构建、交付和维护解决方案的过程,让用户更加满意,并使产品更具竞争力,无需花费高成本自行开发解决方案。

 

作者简介:

Matthew O'Riordan 是 Ably(无服务器 WebSocket 提供商)的首席执行官和联合创始人。他已经做了 20 多年的软件工程师,其中有很多时间在担任 CTO。他从在 20 世纪 90 年代中期开始从事商业互联网方面的工作,当时 IE 3 和网景还在你争我抢。他喜欢写代码,同时,作为初创企业家,扩大业务所面临的挑战是他前进的动力。Matthew 之前曾创办过两家科技公司,并成功退出。

 

原文链接

https://www.infoq.com/articles/serverless-websockets-realtime-messaging/


相关阅读:

WebSocket 原理浅析与实现简单聊天

构建通用WebSocket推送网关的设计与实践

Serverless实战:利用云函数 + API网关实现Websocket聊天工具

2023-03-07 11:0311599

评论

发布
暂无评论
发现更多内容

学会IDEA REST Client后就可以丢掉postman了

Java 程序员 后端

女生适合学编程吗?

Java 程序员 后端

好好编程-物流项目04【Mybatis逆向工程】

Java 程序员 后端

040022-week3-design

InfoQ_70156470130f

好好编程-物流项目07【SpringMVC整合】

Java 程序员 后端

如何设计一个高可用系统?简单总结了10来种方法,今天全部告诉你们!

Java 程序员 后端

字节面试官:你觉得HTTPS能防止重放攻击吗?

Java 程序员 后端

通过程序来介绍Node.js 的几个文件读写和事件监听API

Regan Yue

nodejs js Node 11月日更

如何让Kafka在保证高性能、高吞吐的同时通过各种机制来保证高可用性?

Java 程序员 后端

如何给网关设计一款专属的权限控制「责任链设计模式」(1)

Java 程序员 后端

JavaScript 中对象处理之Object.freeze 与 Object.seal

devpoint

JavaScript Object 11月日更

好好编程-物流项目13【登录认证-shiro实现】

Java 程序员 后端

【Promise 源码学习】第四篇 - 翻译并理解 Promise A+ 规范

Brave

源码 Promise 11月日更

如何设计一个高性能Elasticsearch mapping

Java 程序员 后端

字节跳动武汉招聘2000人,这套JAVA面试题被刷爆了

Java 程序员 后端

Prometheus HTTP API 查询(五)告警接口

耳东@Erdong

Prometheus PromQL HTTP API 11月日更

学生管理系统架构设计文档

唐敏

「架构实战营」

字节后端开发3+4面,终于拿到秋招第一个offer(1)

Java 程序员 后端

进击的Java(三)

ES_her0

11月日更

如何封装原生的-Java-NIO-以及扩展?详细到让你分分钟搞定Netty

Java 程序员 后端

如何给网关设计一款专属的权限控制「责任链设计模式」

Java 程序员 后端

好好编程-物流项目01【搭建maven工程】

Java 程序员 后端

好险!一入职就遇到MySQL这么大Bug!差点背锅走人!

Java 程序员 后端

如何用RabbitMQ实现延迟队列

Java 程序员 后端

解决:http: TLS handshake error from *

liuzhen007

11月日更

字节后端开发3+4面,终于拿到秋招第一个offer

Java 程序员 后端

学会5位大牛撰写756页大规模Linux集群架构实践PDF,成功入职华为

Java 程序员 后端

如何在本地部署多个Tomcat服务

Java 程序员 后端

如何调优 Java 垃圾收集

Java 程序员 后端

字节跳动Java面试题精选——算法与数据结构「跳槽面试必备」

Java 程序员 后端

安卓程序员必备hook技术之进阶篇

Java 程序员 后端

无服务器WebSocket:开启实时数据传递新时代_软件工程_InfoQ精选文章