写点什么

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

  • 2021-03-07
  • 本文字数:3601 字

    阅读完需:约 12 分钟

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

HTTP 协议是一种无状态的、基于 TCP 的请求/响应模式的协议,请求只能由客户端发起、服务端进行响应。在大多数场景,这种请求/响应的 Pull 模式已经可以满足需求。但在某些情形,例如消息推送、通知等应用场景,需要实时将数据同步到客户端,这就要求服务端支持主动 Push 数据。


服务端推送技术历史悠久,经历了短轮询、长轮询的发展,一定程度上能够解决问题,但也存在着不足,例如时效性、资源浪费等。HTML5 标准带来的 WebSocket 规范基本结束了这一局面,成为目前服务端推送技术的主流方案。


在系统中集成 WebSocket 十分简单,相关讨论与资料很丰富。但如何实现一个通用的 WebSocket 推送网关尚未有成熟的方案。目前的云服务厂商主要关注 iOS 和安卓等移动端推送,也缺少对 WebSocket 的支持。本文介绍了我们基于 Netty 实现 WebSocket 长连接网关时的一些思考和经验。

1 爱奇艺号 WebSocket 使用现状

爱奇艺号是爱奇艺内容创作、分发和变现的平台,涵盖自媒体、网大、网剧、儿童、知识、纪录片等多个业务,是爱奇艺内容生态的重要组成。爱奇艺号作为前台系统,对用户体验有较高要求,直接影响着创作者的创作热情。目前,爱奇艺号有多个业务场景中用到了 WebSocket 推送技术,包括:


  • 用户评论。实时的将评论消息推送到浏览器。

  • 实名认证。合同签署前需要对用户进行实名认证,用户扫描二维码后进入第三方的认证页面,认证完成后异步通知浏览器认证的状态。

  • 活体识别。类似实名认证,当活体识别完成后,异步将结果通知浏览器。


在实际的业务开发中,我们发现,WebSocket 推送技术在使用中存在以下问题:首先,WebSocket 技术栈不统一,既有基于 Netty 实现的,也有基于 Web 容器实现的,给开发和维护带来困难;其次,WebSocket 实现分散在在各个工程中,与业务系统强耦合,如果有其他业务需要集成 WebSocket,面临着重复开发的窘境,浪费成本、效率低下;第三,WebSocket 是有状态协议的,客户端连接服务器时只和集群中一个节点连接,数据传输过程中也只与这一节点通信。


因此,WebSocket 集群需要解决会话共享的问题。如果只采用单节点部署,虽然可以避免这一问题,但无法水平扩展支撑更高负载,有单点的风险;最后,缺乏监控与报警,虽然可以通过 Linux 的 Socket 连接数大致评估 WebSocket 长连接数,但数字并不准确,也无法得知用户数等具有业务含义的指标数据;无法与现有的微服务监控整合,实现统一监控和报警。

2 长连接网关的设计与实现

为了解决以上问题,我们实现了统一的 WebSocket 长连接网关,具备如下特点:


1. 集中实现长连接管理和推送能力。统一技术栈,将长连接作为基础能力沉淀,便于功能迭代和升级维护。


2. 与业务解耦。将业务逻辑与长连接通信分离,使业务系统不再关心通信细节,也避免了重复开发,浪费研发成本。


3. 使用简单。提供 HTTP 推送通道,方便各种开发语言的接入。业务系统只需要简单的调用,就可以实现数据推送,提升研发效率。


4. 分布式架构。实现多节点的集群,支持水平扩展应对业务增长带来的挑战;节点宕机不影响服务整体可用性,保证高可靠。


5. 多端消息同步。允许用户使用多个浏览器或标签页同时登陆在线,保证消息同步发送。


6. 多维度监控与报警。自定义监控指标与现有微服务监控系统打通,出现问题时可及时报警,保证服务的稳定性。

2.1. 技术选型

在众多的 WebSocket 实现中,从性能、扩展性、社区支持等方面考虑,最终选择了 Netty。Netty 是一个高性能、事件驱动、异步非阻塞的网络通信框架,在许多知名的开源软件中被广泛使用。


WebSocket 是有状态的,无法像直接 HTTP 以集群方式实现负载均衡,长连接建立后即与服务端某个节点保持着会话,因此集群下想要得知会话属于哪个节点,有两种方案,一种是使用类似微服务的注册中心来维护全局的会话映射关系,一种是使用事件广播由各节点自行判断是否持有会话,两种方案对比如表 1 所示。

方案

优点

缺点

注册中心

会话映射关系清晰,集群规模较大时更合适

实现复杂,强依赖注册中心,有额外运维成本

事件广播

实现简单更加轻量

节点较多时,所有节点均被广播,资源浪费

表 1:WebSocket 集群方案


综合考虑实现成本与集群规模,选择了轻量级的事件广播方案。实现广播可以选择基于 RocketMQ 的消息广播、基于 Redis 的 Publish/Subscribe、基于 ZooKeeper 的通知等方案,其优缺点对比如表 2 所示。从吞吐量、实时性、持久化、实现难易等方面考虑,最终选择了 RocketMQ。


方案

优点

缺点

基于RocketMQ

吞吐量高、高可用、保证可靠

实时性不如Redis

基于Redis

实时性高、实现简单

不保证可靠

基于ZooKeeper

实现简单

写入性能较差,不适合频繁写入场景

表 2:广播的实现方案对比

2.2. 系统架构

网关的整体架构如图 1 所示。



图 1:WebSocket 长连接网关架构

网关的整体流程如下:


1. 客户端与网关任一节点握手建立起长连接,节点将其加入到内存维护的长连接队列。客户端定时向服务端发送心跳消息,如果超过设定的时间仍没有收到心跳,则认为客户端与服务端的长连接已断开,服务端会关闭连接,清理内存中的会话。

2. 当业务系统需要向客户端推送数据时,通过网关提供的 HTTP 接口将数据发向网关。

3. 网关在接收到推送请求后,将消息写入 RocketMQ。

4. 网关作为消费者,以广播模式消费消息,所有节点都会接收到消息。

5. 节点接收到消息后判断推送的消息目标是否在自己内存中维护的长连接队列里,如果存在则通过长连接推送数据,否则直接忽略。


网关以多节点方式构成集群,每节点负责一部分长连接,可实现负载均衡,当面对海量连接时,也可以通过增加节点的方式分担压力,实现水平扩展。同时,当节点出现宕机时,客户端会尝试重新与其他节点握手建立长连接,保证服务整体的可用性。

2.3. 会话管理

长连接建立起来后,会话维护在各节点的内存中。SessionManager 组件负责管理会话,内部使用了哈希表维护了 UID 与 UserSession 的关系;UserSession 代表用户维度的会话,一个用户可能会同时建立多个长连接,因此 UserSession 内部同样使用了一个哈希表维护 Channel 与 ChannelSession 的关系。为了避免用户无限制的创建长连接,UserSession 在内部的 ChannelSession 超过一定数量后,会将最早建立的 ChannelSession 关闭,减少服务器资源占用。SessionManager、UserSession、ChannelSession 的关系如图 2 所示。



图 2:SessionManager 组件

2.4. 监控与报警

为了了解集群建立了多少长连接、包含了多少用户,网关提供了基本的监控与报警能力。网关接入了 Micrometer,将连接数与用户数作为自定义指标暴露,供 Prometheus 进行采集,实现了与现有的微服务监控系统打通。在 Grafana 中方便地查看连接数、用户数、JVM、CPU、内存等指标数据,了解网关当前的服务能力与压力。报警规则也可以在 Grafana 中配置,当数据异常时触发奇信(内部报警平台)报警。

2.5. 性能压测

压测选择两台配置为 4 核 16G 的虚拟机,分别作为服务器和客户端。压测时选择为网关开放了 20 个端口,同时建立 20 个客户端,每个客户端使用一个服务端端口建立起 5 万连接,可以同时创建百万个连接。连接数与内存使用情况如图 3 所示。



图 3:百万级连接

给百万个长连接同时发送一条消息,采用单线程发送,服务器发送完成的平均耗时在 10s 左右,如图 4 所示。


图 4:服务器推送耗时

一般同一用户同时建立的长连接都在个位数。以 10 个长连接为例,在并发数 600、持续时间 120s 条件下压测,推送接口的 TPS 大约在 1600+,如图 5 所示。



图 5 :长连接 10、并发 600、持续时间 120s 的压测数据

当前的性能指标已满足爱奇艺号的实际业务场景,可支持未来的业务增长。

3 业务案例

为了更生动的说明优化效果,文章最后,我们也以封面图添加滤镜效果为例,介绍一个爱奇艺号使用 WebSocket 网关的案例。


爱奇艺号自媒体发表视频时,可选择为封面图添加滤镜效果,引导用户提供提供更优质的封面。当用户选择一个封面图后,会提交异步的后台处理任务。当异步任务处理完成后,通过 WebSocket 将不同滤镜效果处理后的图片返回给浏览器,业务场景如图 6 所示。



图 6:爱奇艺号视频封面图滤镜


从研发效率方面考虑,如果在业务系统中集成 WebSocket,至少需要 1-2 天的开发时间;如果直接使用网关的推送能力,只需要简单的接口调用就实现了数据推送,开发时间降低到分钟级别,研发效率大大提高。从运维成本方面考虑,业务系统不再含有与业务逻辑无关的通信细节,代码的可维护性更强,系统架构变得更加简单,运维成本大大降低。

4 写在最后

WebSocket 是目前实现服务端推送的主流技术,恰当使用能够有效提供系统响应能力,提升用户体验。通过 WebSocket 长连接网关可以快速为系统增加数据推送能力,有效减少运维成本,提高开发效率。


长连接网关的价值在于它封装了 WebSocket 通信细节,与业务系统解耦,使得长连接网关与业务系统可独立优化迭代,避免重复开发,便于开发与维护。其次,网关提供了简单易用的 HTTP 推送通道,支持多种开发语言接入,便于系统集成和使用。另外,网关采用了分布式架构,可以实现服务的水平扩容、负载均衡与高可用。最后,网关集成了监控与报警,当系统异常时能及时预警,保证服务的健康和稳定。

 

目前,WebSocket 长连接网关已在爱奇艺号图片滤镜结果通知、MCN 电子签章等多个业务场景中得到应用。未来还有许多方面需要探索,例如消息的重发与 ACK、WebSocket 二进制数据的支持、多租户的支持等。我们也会不断优化、丰富功能,带给开发者更好的使用体验。


本文转载自:爱奇艺技术产品团队(ID:iQIYI-TP)

原文链接:构建通用WebSocket推送网关的设计与实践

2021-03-07 08:005452

评论 3 条评论

发布
用户头像
该方案只降低了节点的连接数,但每个节点订阅全量信息,对系统资源消耗更大。维护全局注册关系也并不是特别复杂,核心是一致性哈希和注册表。
2023-07-13 22:09 · 浙江
回复
用户头像
由于多个consumer消费偏移量不一致,客户端重连时可能重复消费同一条消息,这个问题是怎么解决的
2021-06-17 11:26
回复
后端自己维护消费状态
2023-07-13 22:03 · 浙江
回复
没有更多了
发现更多内容

链上挖矿分红智能合约DAPP系统开发部署模式定制

开发微hkkf5566

从react源码看hooks的原理

flyzz177

React

python常用内置函数用法精要(二)

乔乔

11月月更

【看球和学Go】错误和异常、CGO、fallthrough

王中阳Go

Go golang 面试题 Go web 11月月更

BSN-DDC基础网络DDC SDK详细设计(六):交易查询、区块查询、签名事件

BSN研习社

BSN

袋鼠云数据湖平台「DataLake」,存储全量数据,打造数字底座

袋鼠云数栈

数据中台 数据仓库 数据湖 数据中台场景实践 数据湖分析

Spring中获取bean的八种方式,你get了几种?

小小怪下士

Java spring bean

HDC2022的无障碍参会体验,手语服务是如何做到的?

HarmonyOS SDK

HMS Core

【从零开始学爬虫】采集猫眼电影热门资讯数据

前嗅大数据

爬虫 数据采集 爬虫软件 爬虫教程 数据采集教程

OceanBase 4.0 解读:分布式查询性能提升,我们是如何思考的?

OceanBase 数据库

数据库 oceanbase

记录一次TiDB v5.2.3迁移到v6.1.0的过程

TiDB 社区干货传送门

迁移 实践案例

为什么 NGINX 的 reload 不是热加载?

API7.ai 技术团队

Apache nginx 开源 api 网关 APISIX

基于 RocketMQ 的 Dubbo-go 通信新范式

Apache RocketMQ

RocketMQ RPC dubbo-go dubbogo

好好的系统,为什么要分库分表?

程序员小富

Java 数据库 面试 分库分表

火山引擎 DataTester 应用故事:一个A/B测试,将产品DAU提升了数十万

字节跳动数据平台

大数据 AB testing实战

云原生系列 【轻松入门容器基础操作】

叶秋学长

云原生 沙箱实验 11月月更

数据卡顿怎么办,瓴羊Quick BI强劲数据引擎来帮忙

小偏执o

从元宇宙、地产数字化到呼叫中心,华为云携手伙伴共创新价值

华为云开发者联盟

云计算 华为云 元宇宙

记一次TiDB数据库Insert语句执行报错的处理过程

TiDB 社区干货传送门

只需5步注册成为亚马逊云科技 Marketplace (海外区)专家

亚马逊云科技 (Amazon Web Services)

亚马逊云科技 Tech 专栏 Marketplace

从recat源码角度看setState流程

flyzz177

React

Fiori Elements 框架里 Smart Table 控件的工作原理介绍

汪子熙

SAP Fiori SAP UI5 ui5 11月月更

信创产业多点开花,AntDB数据库积极参与行业标准研制,协同价值链伙伴共促新发展

亚信AntDB数据库

AntDB aisware antdb AntDB数据库

高性能数据访问中间件 OBProxy(六):一文讲透数据路由

OceanBase 数据库

oceanbase

经营型项目经理是不是伪需求?

PMO实践

项目管理 敏捷 PMO 项目经理

华为云区块链三大核心技术国际标准立项通过

华为云开发者联盟

区块链 华为云

六年三次架构迭代,OceanBase 单机分布式一体化会是大势所趋吗?

OceanBase 数据库

数据库 oceanbase

从源码角度看React-Hydrate原理

flyzz177

React

流程编排、如此简单-通用流程编排组件JDEasyFlow介绍

京东科技开发者

数据库 架构 服务端 流程引擎 流程编排

【11.18-11.25】写作社区优秀技术博文回顾

InfoQ写作社区官方

热门活动

云享·人物丨造梦、探梦、筑梦,三位开发者在华为云上的寻梦之旅

华为云开发者联盟

云计算 后端 华为云

构建通用WebSocket推送网关的设计与实践_架构_爱奇艺技术产品团队_InfoQ精选文章