写点什么

如果微博、贴吧变成即时聊天,程序员该怎么办?

  • 2022-03-01
  • 本文字数:3842 字

    阅读完需:约 13 分钟

如果微博、贴吧变成即时聊天,程序员该怎么办?

刷微博是许多人每天的“例行指部锻炼”,一扫一划,就能评论热点话题,订阅热门动态。当然,也有不少人对明星不感兴趣,转而去刷 Reddit、贴吧、虎扑、知识星球或是其他 BBS 社区。对于 90、80 后来说,这个被“刷”的对象可能是曾经的即刻、糗百,天涯、猫扑。


可以说,“聚众看热闹”是人类永恒不变的爱好,但我们看热闹的方式却并不丰富:要么刷 BBS 社区,要么扎进社交软件的群聊。


不知你有没有想过,如果将二者合二为一,让微博、贴吧这样的社区,全部变成即时聊天,各个博主、吧友的动态,全部以群聊消息的形式推送给你,你又可以即时地回复、互动,甚至和这些博主、吧友连麦视频,情况会是怎样的?


这将是一个超级社区,或者更准确地说,这将是一个无人数上限的“超级群”。


可是,这个“超级群”,实现起来将非常困难。在程序员看到产品设计的那一刻,就有精神崩溃的风险。

真正的服务器压力


“崩溃”主要源自技术挑战,更确切地说,是服务器面临的巨大的读写压力和存储压力。


微博曾出现过几次著名的故障:赵丽颖领证、关晓彤官宣、王宝强离婚。在调侃微博崩溃的各种网络段子背后,我们能看到的是,一个架构师面对一条微博下几秒新增数万条评论,服务器压力瞬间暴涨几十倍的无奈身影。


与此类似的是直播弹幕的分发场景。无论是近期的视频号五月天跨年演唱会,还是 B 站春晚,弹幕过百万轻而易举(“二零一九最美的夜”bilibili 晚会弹幕超过 170 万条)。


理论上讲,每一条弹幕都要向直播间内观众做全量分发。以五月天跨年演唱会为例,当晚有 1,680 万人在线上观看,如果保守假设当晚共发送 100 万条弹幕,那么单是弹幕的写操作,就至少要执行 16,800,000 x 1,000,000 次。因为实际支撑有困难,又要顾及用户的屏幕根本无法同屏显示上万条评论,所以弹幕的转发一般都是降级处理 —— 只分发一小部分给你看,其他的略过。


而如果将微博评论、直播弹幕,全部“群聊化”,问题会更加恐怖。“群聊化”后,产品形态成为“超级群”,问题进入 IM 场景,可以做相应的流控,但不能丢弃信息。且无论是微博评论还是直播弹幕,对信息上下文的关注度都不高,但这恰恰是 IM 关注的重点。


可以说,至少在 3 年以前,能够系统解决这些问题并将其打磨为一个成熟产品的人不多。直到 2018 年,国外出现了一个名叫 Discord 的软件,网友才体验到了这种全新的社区形式。Discord 最初只服务于游戏语音连麦,但很快演化为一个超级社区。2021 年,据 CNN 报道,Discord 已有超过 1.4 亿名注册用户,微软正在谈判以 100 亿美元收购它。而在 npr 的采访中,美国芝加哥地区的一名 18 岁少年表示,他 2020 年的大部分时间都在 Discord 上闲逛,并将其形容为“Reddit 和群聊的混合体”。元宇宙的支持者们也惊奇地发现,所谓的“Discord 模式”,不就是未来元宇宙虚拟社区的基础模式么?在元宇宙里,总不能先加个 500 人的群再开始聊天吧。


抛开模式创新不谈,如果要深究 Discord 的技术核心,恰恰就是我们前面所描述的“超级群”。而在 2022 年 1 月 11 日,融云也发布了一款名为“超级群”的 PaaS 产品,以此为例,我们或许能搞清楚,这种带了点科幻色彩的未来社区,究竟是如何实现的。

超级群的设计架构和实施方案


超级群的底层技术支撑能力,可以简单分为两部分来谈,分别是超级群业务能力、IM 底层技术能力。



超级群的业务能力,在架构设计层面共分为四层,分别是加速网络、接入层、核心服务层以及底层存储。之所以要做这样的划分,是为了充分利用融云自身的统一加速网络机制, 保障网络连通性以及连接质量,让超级群可以根据自身业务需求, 在连接通道的基础上,专心实现更高效的业务交互。


在融云,传统的群消息建立在收发模型(收件箱、发件箱)的基础上,独立维护会话列表和历史消息存储。从用户发送群消息,到群内 (成员数量为 N ) 接收群消息。整个过程将产生四类消息:


  1. 一条发送方发件箱记录;

  2. N-1 条接收方的收件箱记录;

  3. 1 条群历史消息记录;

  4. N 条会话列表记录。


消息存储投递流程为:


终端 A -> 发送消息 -> 接入服务 -> 群管理 (群消息上行) -> 分发 -> 群聊消息分发节点 -> 消息节点 -> 通知拉取 (直接发送) -> 终端 B/C/D


在这样的流程下,消息分发节点与消息节点交互密切,通常合并部署。同时,消息节点也会直接触发收件箱、发件箱的消息存储。


但在超级群的场景下,群成员数量理论上是无上限的,无论是消息的上行、下行,还是消息在存储层的写入和查询,都将导致空前的服务承载压力,以上方案因此不再适用。于是,融云在现有连接机制之上, 针对超级群做了交互设计优化,设计了两种分发模型: 分别叫做消息驱动模型和会话驱动模型。


对于消息驱动模型而言,消息节点将不再直接触发收件箱存储操作。融云特别设计了一个环状消息队列, 通过内存搭配外部缓存的方式,完成最近 N 条消息的缓存, 并通过对消息存储模型优化, 完成热点数据的快速读写。对消息的下行,则做聚合处理,保障客户端能够处理大量消息变更通知,并且尽量减少交互次数,也让消息的拉取变得更快速、精准。


会话驱动模型则是在消息驱动模型的基础之上, 做进一步的优化。


首先,消息节点不会再通知客户端拉取消息,而是通过触发实时会话, 通知客户端会话发生变更。而这里的实时会话,则是实现客户端订阅机制的基础, 让客户端可以只获知已订阅的会话变更消息,从而进一步缩小需要处理的会话以及消息数量。


其次,客户端在收到会话变更通知后, 会根据通知,判断是否要发起会话消息查询操作。如果是,则按照一定的机制查询最新或特别范围的消息。


除消息分发层面的优化外,对存储的优化也非常关键。融云超级群的所有服务,均按照业务维度进行一致性哈希分发。比如,上行服务可以按照群 ID 或 channel ID 做哈希,分发服务可以按照接收方 ID 做哈希。核心目标在于确保热数据的命中,优先使用内存、LRU 缓存、再使用分布式缓存、磁盘冷存储。


APP、群组、信令级别的流控,则是另一重保障,它将一个看似无边界的产品需求,转化为了可琢磨、可实现的技术问题。因此,虽然流控不是超级群实现方案的重点,但依然不可或缺。


整体而言,融云的超级群构建方案可以分为四个要点:


  1. 弱化原发件箱 / 收件箱模型, 尤其是收件箱, 以极大提升读写性能,避免因 I/O 而产生的性能瓶颈;

  2. 通过"变更通知"聚合等方式,尽量减少终端与服务端交互次数,减少因网络交互而产生的延时;

  3. 设计专用数据结构 (环形队列), 并设置内存、外部缓存等多级缓存结构, 提升超大规模下的消息分发存储速度, 并提供快速查询能力;

  4. 通过会话驱动模型, 进一步减少网络交互过程中,待传输的数据量。


那么,有了以上方案,是否就可以构建出一个“超级群”呢?显然还不够,在超级群的场景之下,IM 底层技术能力的积累可能更为重要。

IM 底层技术能力与网络层性能优化


如果要对融云超级群所依赖的 IM 基础能力做一个解读,恐怕一本迷你书也写不完,其粗略架构图如下:



但好在,关于超级群,我们只需重点关注其在网络层面的依赖即可。对于所有的 IM 服务而言,底层网络的加速能力都是关键。融云的底层服务网络全称是融云全球通信网络 (以下简称为 SD-CAN,Software Defined - Communication Accelerate Network) ,集合了 BGP anycast、SD-WAN、对等连接、动态 CDN、智能 DNS 等多种网络加速方式。


对于超级群来说,SD-CAN 允许客户端 SDK 通过查询和探测确定地域和运营商以及最后一公里的网络情况,将用户就近调度到融云的网络边缘节点, 边缘节点依据信令的请求目标地址投递到路由节点,完成数据汇集,再由路由节点识别并转发到对应的数据中心。


举个例子,如果北美用户要访问中国国内的数据中心,典型的两条路径是:


  1. 北美用户 -> 直接连接 -> 国内数据中心接入服务 -> 业务服务;

  2. 北美用户 -> anycast -> 北美数据中心边缘节点 -> 北美数据中心路由节点 -> SD-WAN/ 对等连接 -> 国内数据中心路由节点 -> 国内数据中心接入服务 -> 业务服务;


客户端会按照服务下发的策略,做并行探测并同时建立连接。对最优链路的选择,依赖于建连延迟、心跳间隔、链路发送接收状况等信息。服务器也会定期检查连接的健康度,主动关闭长尾连接,结合客户端的重连机制,一起保障对最优链路的调用。

PaaS 产品接近完备,或将填补元宇宙到来前的空白


除了技术实现,挑战也出现在产品设计层面。


由于超级群中的信息量太大,需要支持将群分割为不同的频道,类似传统的 topic 或 channel。即使相同的群和群成员,通过不同的频道,仍然能将会话、消息、未读数分门别类聚合。用户可以更关注自己感兴趣的部分,提升用户黏性。


这也反映了用户在超级群场景下的真正需求:我或许会希望在一个有数十万网友的超级群中建立社交关系,但却不希望被数十万消息打扰生活。


此外,对于融云来说,超级群是个 PaaS 产品,这意味着要为客户端留下充裕的可定制空间,在不同的场景,对信息推送的方式、逻辑、频率都有不同的要求。同时,将信息和聊天结合的场景,一般都有多端的需求。不同的平台,比如 Android、iOS、Web 等,在海量消息的网络请求和存储方面都有不同的技术特点,甚至同平台不同厂商的推送通道特性也不同,这些都需要一一考虑。


最近几年,社交领域的新兴公司新增不多,整体增长呈下降趋势。这一方面是因为流量向头部高度集中,挤压了新玩家的空间;另一方面也是因为缺少新模式,大家仍在围绕存量用户做竞争。


超级群这一新应用形态,可能会对社交软件整体的发展,产生巨大的牵引作用,从而带来新的机会。同时,PaaS 产品的完备,也标志着实现产品创新的技术基础已经夯实,这或将在产品层面,填补从微信、语聊房迈入元宇宙的最后一段空白。


2022-03-01 14:373521

评论 2 条评论

发布
用户头像
写的真好,从熟悉的热搜刷屏话题联系到IM的设计架构,视野开阔,长见识了!
2022-03-04 14:28
回复
过奖啦,能对大家有帮助就好
2022-03-08 11:45
回复
没有更多了
发现更多内容

Java开发五年,java百度人脸识别,最全153道Spring全家桶面试题

Java 程序员 后端

Java开发人员不得不收集的代码,史上最全的微服务专业术语面试50问

Java 程序员 后端

模块一作业

忘记喝水的猫

架构训练营

Java开发经验的有效总结,以商品超卖为例讲解Redis分布式锁

Java 程序员 后端

第1周作业

波波

「架构实战营」

Java工程师最容易遇到4个瓶颈是什么,Java架构面试题spring原理

Java 程序员 后端

Java工程师面试该怎么准备,尚硅谷java百度网盘,Java技术图谱

Java 程序员 后端

Java开发三年月薪才12K,java图形化界面教程,linux网络架构详解

Java 程序员 后端

Java开发人员不得不收集的代码,精选Java面试真题集锦

Java 程序员 后端

Java开发你需要了解的那些事,Java线程池基础入门和简单实践以及使用技巧

Java 程序员 后端

Java开发岗还不会这些问题,想拿高工资

Java 程序员 后端

Java工程师进阶,马士兵架构师破解吧,我的Java春季历程

Java 程序员 后端

XA 分布式事务

风翱

分布式事务 10月月更

Java开发经验谈,linux视频教程百度网盘,逆袭面经分享

Java 程序员 后端

Java开发前景怎么样,java全套教程百度云,linux基础入门教程

Java 程序员 后端

Java开发工程师笔试题目,图灵学院vip百度云盘,阿里P8大牛手把手教你

Java 程序员 后端

Java开发入门与实战!极客学院和黑马程序员,Java高级工程师系列学习路线介绍

Java 程序员 后端

Java开发教程,极客时间架构师训练营,面试流程4轮技术面+1轮HR

Java 程序员 后端

Java开发经典实战!自学java教程百度云盘,阿里程序员的Java之路

Java 程序员 后端

Java开发中遇到最难的问题,redis视频教程韩顺平,附小技巧

Java 程序员 后端

Java开发实战讲解,牛客网面试经验,Java编程入门教材

Java 程序员 后端

Java开发最佳实践手册全网独一份,vue视频教程百度网盘,正式加入字节跳动

Java 程序员 后端

Java开发者应该会哪些东西才不会被公司淘汰,美团Java面试

Java 程序员 后端

Java开发实战讲解,牛客网面试经验,Java高级知识图谱

Java 程序员 后端

Java开发核心知识笔记共2100页,如何保证Redis与数据库的双写一致性

Java 程序员 后端

Java开发究竟该如何学习,年末阿里百度等大厂技术面试题汇总,程序员翻身之路

Java 程序员 后端

Java并发原理解析!图灵学院四期java架构师,Java零基础入门视频

Java 程序员 后端

Java开发从零开始,java基础入门传智播客网页版,Java后端路线图

Java 程序员 后端

Java开发从零开始,牛客网java选择题库,程序员Javaweb源码

Java 程序员 后端

Java工作资料,java编程思想第五版百度云,面试官6个灵魂拷问

Java 程序员 后端

最近几天在 InfoQ 连更的再反思

baiyutang

10月月更

如果微博、贴吧变成即时聊天,程序员该怎么办?_语言 & 开发_王一鹏_InfoQ精选文章