正式定档!QCon 北京站改期为2024年4月11-13日,地点:北京·国测国际会议会展中心 >>> 了解详情
写点什么

构建通用 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:004644

评论 3 条评论

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

字节跳动数据血缘图谱升级方案设计与实现

字节跳动数据平台

数据库 数据优化 数据血缘 数据研发

浅谈测试需求分析

霍格沃兹测试开发学社

Java岗秋招最全面试攻略,看这份Java架构面试核心手册,足够了

Geek_0c76c3

Java 数据库 开源 程序员 架构

20道高频vue面试题自测

bb_xiaxia1998

Vue 前端

从recat源码角度看setState流程

flyzz177

React

火山引擎CDN的技术演进与未来

火山引擎边缘云

存储资源盘活系统,“盘活”物联网架构难题(下)

天翼云开发者社区

anime4k 在真机租用上的应用尝试

霍格沃兹测试开发学社

差点自闭!京东面试官夺命连环问操作系统,幸好最后拿到了offer

Geek_0c76c3

Java 数据库 开源 程序员 开发

教育行业在用的云管平台是什么牌子?

行云管家

云计算 教育 云管平台 云管理

数据库连接池

C++后台开发

MySQL 数据库 后端开发 Linux服务器开发 连接池

《Vue.js技术内幕》有奖书评活动正式开启

图灵社区

vue.js 前端

帮助 Meta 解决 Presto 中的数据孤岛问题

Alluxio

sql 开源 presto Alluxio meta

基于TensorFlow Serving的YOLO模型部署

霍格沃兹测试开发学社

技术分享 | web自动化测试-PageObject 设计模式

霍格沃兹测试开发学社

荣耀开发者服务平台全新升级,助力开发者简单开发、高效分发

荣耀开发者服务平台

开发者 手机 安卓 荣耀 honor

《Vue.js技术内幕》有奖书评活动正式开启

图灵教育

vue.js 前端

云行| 加码算力网络布局,天翼云发布南京3AZ节点

天翼云开发者社区

中国信通院沙龙|火山引擎边缘云助力业务体验创新

火山引擎边缘云

云计算 云原生 边缘计算 边缘节点 信通院

凭这份堪称保姆级别的Java面试宝典,已怒斩3个大厂offer(阿里,美团,腾讯)

Geek_0c76c3

Java 数据库 开源 程序员 架构

opencv 使用 GPU 加速

霍格沃兹测试开发学社

云堡垒机能给公司带来哪些价值?选择哪款好?

行云管家

云计算 堡垒机 云堡垒机 云运维

React源码解读之React Fiber

flyzz177

React

Wallys//Industrial_Wireless_AP//network,card//QCN6024/QCN9074/QCN9024,WiFi,Card IPQ6010,802.11ax,2x2

wallys-wifi6

QCN9074 QCN6024 QCN9072

墨天轮沙龙 | 麦杰科技卢学东:openPlant 实时数据库系统及应用

墨天轮

数据库 工业 国产数据库 实时数据库

vue进阶面试题

bb_xiaxia1998

Vue 前端

软件测试 丨 真实面试经历分享,不用再看其他面试题

测试人

软件测试 面试题 自动化测试 测试开发

2022年下半年如何备考 CKS

baiyutang

云原生 k8s 云安全 CKS

突破研发效能瓶颈,详解价值流分析的五大流动指标

万事ONES

英特尔为开源注入创新力量,加速AI应用

科技之家

天翼云ECK云边一体化

天翼云开发者社区

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