即时消息技术剖析与实战
袁武林
微博研发中心技术专家
立即订阅
6503 人已学习
课程目录
已完结 24 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 搞懂“实时交互”的IM技术,将会有什么新机遇?
免费
基础篇 (8讲)
01 | 架构与特性:一个完整的IM系统是怎样的?
02 | 消息收发架构:为你的App,加上实时通信功能
03 | 轮询与长连接:如何解决消息的实时到达问题?
04 | ACK机制:如何保证消息的可靠投递?
05 | 消息序号生成器:如何保证你的消息不会乱序?
06 | HttpDNS和TLS:你的消息聊天真的安全吗?
07 | 分布式锁和原子性:你看到的未读消息提醒是真的吗?
08 | 智能心跳机制:解决网络的不确定性
场景篇 (4讲)
09 | 分布式一致性:让你的消息支持多终端漫游
10 | 自动智能扩缩容:直播互动场景中峰值流量的应对
11 | 期中实战:动手写一个简易版的IM系统
12 | 服务高可用:保证核心链路稳定性的流控和熔断机制
进阶篇 (10讲)
13 | HTTP Tunnel:复杂网络下消息通道高可用设计的思考
14 | 分片上传:如何让你的图片、音视频消息发送得更快?
15 | CDN加速:如何让你的图片、视频、语音消息浏览播放不卡?
16 | APNs:聊一聊第三方系统级消息通道的事
17 | Cache:多级缓存架构在消息系统中的应用
18 | Docker容器化:说一说IM系统中模块水平扩展的实现
19 | 端到端Trace:消息收发链路的监控体系搭建
20 | 存储和并发:万人群聊系统设计中的几个难点
21 | 期末实战:为你的简约版IM系统,加上功能
22 | 答疑解惑:不同即时消息场景下架构实现上的异同
结束语 (1讲)
结束语 | 真正的高贵,不是优于别人,而是优于过去的自己
即时消息技术剖析与实战
登录|注册

10 | 自动智能扩缩容:直播互动场景中峰值流量的应对

袁武林 2019-09-18
你好,我是袁武林。
随着近几年各种直播 App 和百万答题 App 的火爆和风靡,具有高实时性要求的直播互动场景开始纷纷借助即时消息技术,来保证直播过程中的各种互动消息和行为能够及时、可靠地投递,比如用户给主播打赏或者送礼的互动行为,不能有超过 10 秒的延迟,更不能丢失,否则会导致主播和房间其他用户看不到。即时消息技术凭借其在实时性和可靠性方面的优势,已经被广泛应用在互动直播场景中。
那么,和传统的消息聊天场景相比,直播互动在业务形态上究竟有哪些区别?在技术层面又有哪些高难度的挑战?

业务形态区别和技术挑战

首先,在业务形态上,与传统的即时消息场景不太一样,直播互动的流量峰值具有“短时间快速聚集”的突发性,流量紧随着主播的开播和结束而剧烈波动。
另外,直播互动是以房间为单位,传统的群聊业务和聊天室业务虽然也有千人群和千人聊天室,但和直播间动辄几十万、上百万人的规模相比还是小巫见大巫的。而且,直播互动由于房间有时效限制和明星效应,用户发言和互动的积极性会更高,毕竟可能“错过这村就没这店了”。
超大的房间规模及高热度的互动导致的一个问题,就是消息下推的并发峰值。这里我们可以简单用数字来直观感受一下:点对点聊天场景,如果两个人每 10 秒说一句话,实际上每秒的消息下推数只有 0.1;群聊或者聊天室场景,假设是一个 500 人群,如果群里每个人也是每 10 秒说一句话,实际每秒的消息下推数是 500 / 10 * 500 = 25000;那么对于一个 10w 人在线的直播互动场景,如果直播间里每个人也每 10 秒说一句话,实际每秒可产生的消息下推数就是 100000 / 10 * 100000 = 10 亿。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《即时消息技术剖析与实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(33)

  • 老师,直播回放是如何保持播放进度与聊天内容在时间上同步的,用什么技术实现的

    作者回复: 可以通过插帧的方式来解决。视频流每隔一定帧数内,插入服务器的时间戳,聊天内容也埋入服务器的时间戳。回放视频时到达相应的时间戳,获取跟这个时间戳相匹配的消息在页面上渲染出来即可。

    2019-09-18
    7
  • 饭团
    长链接在服务器缩容的时候需要做:
    1)需要告诉网管机,自己准备停止接入新的链接!
    2)在最后一个链接断掉后后才能退出
    短链接 和 长链接比 变化实效性要高很多

    作者回复: 是的,实际上也不需要等到最后一个长连断开哈,对于剩余的少量的长连接可以采取强制断开方式,等待客户端断连重连即可。

    2019-09-18
    1
    6
  • 淡蓝小黑
    文中提到【通过这个优化,相当于是把直播消息的扇出从业务逻辑处理层推迟到网关层】和 您回复我的【业务层在把消息扇出给到网关机时,就已经具体到接收人了,所以不需要通知网关机来进行变更。】

    这两条不冲突吗?(我看唯一的区别是文中说的是直播间场景,您回复我的是群聊场景,还是说群聊和直播间是用不同的模式扇出消息的?),其实我想问的是,用户加入直播间,网关机本地维护【本机某个直播间有哪些用户】这个数据的话,当用户离开直播间,加入另一个直播间时,业务处理层还要通知网关层更新本地维护的那个数据,有可能会出现数据不一致的情况,导致用户加入新直播间了,但由于网关层数据没有更新,用户收到不到新直播间的消息。

    作者回复: 嗯,这是个好问题,我们来理一理。
    先想一想群聊和直播的使用场景,对于直播场景来说,房间和房间之间是隔离状态,也就是说每次用户进入到一个房间,都需要通过信令告诉网关机自己当前连接的是哪个房间,这样网关机才不会推错消息。正是通过这个加房间的信令,网关机有机会来维护一个 房间 - 用户 -连接的关系,因此对于直播间消息,我们的消息给到网关机时只需要按房间维度来pub消息就可以;但是对于群聊来说,群和群之间不是隔离状态,我们的长连接对于任何群的消息都是需要推送的,因此在app打开建立好长连后,客户端不需要再告知自己当前进入了哪个群,所以网关机在建立长连时只能建立一个 用户 - 连接的映射,所以对于群聊我们需要在提交给网关机时扇出成用户维度才可以。
    理解了上面说的就不难解答你的问题,用户离开直播间加入另一个直播间都会通过长连通道下发一个退出旧直播间信令和加入新直播间信令(或者一个切换房间信令),这多个信令都是被长连接那一台网关机接收到并处理的,所以不存在需要多网关机同步数据的问题哈。

    2019-09-26
    4
  • yic
    老师,为了避免每条消息都查询用户的在线状态,所有的消息都发送给所有的网关节点,这样也会造成每台网关机器的流量成倍数增长吧。这样,是不是会影响消费者推送消息的速率呢?毕竟,如果有50台网关节点,原来每台网关节点只需要取1条消息,现在却需要取50条消息,其中有49条是无效的。

    作者回复: 是的,所以这个需要一个权衡,如果业务场景大部分都是点对点场景那么使用全局在线状态来精确投递是更好的选择,如果是群聊和直播类似扇出较大的场景推荐使用所有网关来订阅全量消息的方式。

    2019-11-15
    1
  • Derek
    对于高在线的房间,做全量网关转发是合适的,到对于低在线,极端情况就是2个人,这种方式有点浪费,而其实绝大部分大型直播平台,低在线占绝对比例。

    作者回复: 嗯,看具体业务的在线率和网关机数量吧。低在线直播间本来没量也不是重点,我们的重点是要解决那少数几个高热度、高并发的直播间的问题。

    2019-09-26
    1
  • 王棕生
    通过长连接的接入网关机,缩容时与普通的 Web 服务机器缩容相比有什么区别?
    答: 普通的Web服务器机器提供http的短连接服务,缩容时拿掉机器,会导致前端连接失败,但通过nginx的负载均衡算法,会使重连的客户端连接到另外一台服务器上,这对客户端来说,基本是无感知的; 但是长连接的接入网关机,在缩容拿掉机器时,会导致这台机器上的所有的长连接全部断掉,此时是会影响到所有连接到这台网关机的所有用户,当然通过入口调度服务,客户端可以通过重连连接到新的网关机上,但是用户的体验始终是不好的。
    2019-09-24
    2
    1
  • 听到老师在回复同学的“监控当前总连接数、每秒建连数、close_wait的连接数、Send-Q、Recv-Q、backlog队列、重传率、pps、带宽使用情况“,深感自己不足,tcpip协议详解这本书没啃下来,老师有推荐的有关网络的书籍吗

    作者回复: 个人感觉还是需要理论结合实际来学习哈,平时没事的时候可以用wireshark抓点包来分析研究一下,印象和理解都会不一样的。推荐一下林沛满的两本wireshark的书吧。。

    2019-09-18
    1
  • 晴天
    通过类似redis的pub/sub实现服务端与客户端长连接消息投递,和队列记录长连接的服务端ip对应客户端标识;这2中方式哪一种应用的更为广泛?

    作者回复: 直播和聊天室场景第一种使用更多,点对点的也有很多使用第二种的,对于网关服务器不太多的业务,个人倾向都使用第一种。

    2019-09-18
    1
  • 卫江
    思考题:基于长连接与web的服务缩容的区别。本质的区别是长连接与短链接的问题,基于长连接就意味着服务器在内核中保存了一些连接状态,而为了更好的扩缩容保持服务的无状态是最好的,因为这些状态会在服务回收后消失,当然了基于web的服务,我们可能也会在应用层保存用户的session等信息,不过这一块可以放在外部存储,比如缓存,所以,基于长连接的服务缩容一定会造成连接信息的丢失,从而触发客户端断线重连以及建立长连接的整个流程。

    作者回复: 是的,对于长连接的网关服务,我们缩容是只需要禁止新的建连请求接入,已存在的长连接尽量等用户自动断开后关闭,对于剩余的少量的长连接可以采取强制断开方式,等待客户端断连重连即可。

    2019-09-18
    1
  • 鱼向北游
    不知道老师还关注不关注这个留言,想问老师个问题,上面说的直播间那个把消息直接广播扇出过各个网关再由各网关来判断这个消息该推给哪个用户。感觉这个没法对网关做到水平扩容呀,因为即使扩容了,扩容网关所收到的消息也是全量的广播消息,压力一点都不会分摊,前阵子做过压测,用这种架构在原网关达到瓶颈后,新添加机器后,新添加的机器在没有用户连接的情况下光分拣消息判断消息不该发,这个操作已经占用到新机器70%的资源了,新机器承载不了多少新量,在这种广播模式下反而是用户都集中在某台或某几台机器上效果会更好

    作者回复: 扩容网关机收到的是扇出前的单条房间维度的消息呀,扇出是在网关机的逻辑里实现的,扇出完就推送出去了。分拣消息慢这一块可以优化一下,在用户上线时在网关机以房间维度建立当前房间的本地用户连接列表,下推时直接获取连接列表就可以了。我们线上下推qps实际能到千万级别,绝大部分机器都是弹性扩容的。

    2019-11-05
    1
  • 唯我天棋
    通过长连接的接入网关机,缩容时与普通的 Web 服务机器缩容相比有什么区别?

    web服务器扩容,只需要再http网关服务下线机器,不再把流量打过来就可以。
    长连接网关发布,则需要多一个通知客户端断链重连的过程

    作者回复: 是的,一般还需要先禁止新的连接接入,可以通知客户端断线重连或者等待大部分旧连接断线后再杀进程。

    2019-11-04
  • wuhaka
    老师您好,基于这节内容我有个问题请教下,你这边IM集群负载均衡的方案和架构是怎样的?听文中意思好像客户端通过http接口拉一个负载低的ip然后直连,不知道我理解错没,或者是否有其他的负载方案,客户端只连一个固定ip就可以,请您分享下业界主流的一些方案,多谢。

    作者回复: 这个具体还是需要根据你的业务访问量来决定,一般单个域名搭配多个vip能满足大部分场景的,对于访问量很大、对DNS解析性能不满意的可以通过HTTPDNS方式来解析域名并根据后端vip的压力进行均衡和调度。

    2019-11-01
  • Ricky Fung
    web服务器在设计时都是无状态的 可随意扩容与缩容,接入层网关机器保存的有用户长连接 可以理解为有状态的,缩容时需要本机上的长连接都失效
    2019-10-23
  • lecy_L
    老师,我现在有个这样的在线教育的场景。实时性要求极高,延迟要在200ms以下,直播是用第三方的通道,鼠标互动等是自己的socket服务。如果采用发布订阅模式的话,队列会成为单点极有可能延迟高,有其他的设计方案参考吗?场景是房间教学,一个房间有几个或者10来个人

    作者回复: 个人理解如果你这里指的200ms的延迟是从客户端发出到另一个客户端接收的话,这个估计比较有挑战呀,光速绕地球一圈也得一百多毫秒,国内一般rtt在几十毫秒比较正常,海外用户的话就够呛了。发布订阅都在主库上延迟实际也还好呀,如果担心这一块也可以尝试通过rpc来直接从业务层调用网关层推消息,不过不维护中央的在线状态的话就需要并发来调用所有网关机了。

    2019-10-15
  • 黄海
    老师, qq 上下线通知好友时,是要先查询好友们的在线状态以取得他们所连接的服务器,然后向这些服务器推送上下线消息吗? 从几亿人的在线状态数据中,查询出几百个在线好友,有什么优化手段吗?

    作者回复: 这个问题可以思考一下:一个用户的好友是有限的,在线状态如果是通过中央kv型存储的,并发查询几百个好友也并不是个问题,性能上不会太慢,只是存储压力会比较大。如果真要优化,好友数太多的情况下,我个人觉得可以把这个用户的好友查出后,组装成一条特殊消息下发给所有网关机,由各台网关机认领各自本机维护的这些好友中的那些在本机登录连接的,然后push上下线消息就可以。

    2019-10-09
  • 黄海
    请问袁老师, 微信和qq这种量级的 IM, 做文字群聊时,服务端用什么方法获知群内每个在线成员连接在哪台服务器呢?

    作者回复: 什么业务场景需要知道每个成员连接在哪一台服务器呀?实现上倒是不难,这个用户上线的时候把他连接的服务器ip也当做一条业务消息push给这个用户加入的所有群里的用户就行。不过一个用户加入的群会比较多,你说的应该是类似聊天室场景吧,同时一个用户只能在一个聊天室里面。

    2019-10-09
  • 时隐时现
    Q1:这个全局消息队列是所有直播间共用的吗,还是说可以按照直播间划分?如果是前者,有没有可能某个直播间消息过多导致其他直播间消息延迟?如果是后者,如何根据压力动态调整每个直播间所属的队列?
    Q2:入口调度服务是不是就是基于负载均衡层实现的,如果负载均衡层本身进行了扩容,如何保证新加入的负载均衡节点执行更多的转发服务?

    作者回复: 一般全局共享的就行,因为直播间上行消息本来不多,考虑到消息频率过快一般都还有每秒消息数限频,所以扇出前需要下推的消息数不多的。
    第二个问题就是课程里讲过的,根据后端服务器压力比如连接数,pps,带宽等来调度,让后端接入服务器压力小的入口vip承接更多请求。vip和后端接入服务器成组成组的扩容,所以比较方便处理。

    2019-09-30
  • 墙角儿的花
    老师 短链接难以控制消息到达服务端的顺序 为什么发消息采用短链接呢

    作者回复: 大部分场景发消息可以不用短连接,都使用同一个长连。对于直播互动场景,由于下推压力大,为了不影响用户发消息行为,所以可以通过短连来隔离一下。为什么不是再多维护一个长连主要是出于维护成本考虑,支持一定idle的短连基本上够用了。

    2019-09-24
    1
  • YidWang
    您好 关于长链接容器话 可以简单介绍一下嘛

    作者回复: 容器化这个在后面的课程会讲到哈,依托docker能够非常简单的实现。

    2019-09-24
  • YidWang
    长链接所有如果暴力下,会导致存储脏数据。如果慢慢下 ,会导致所容时间过久,这个怎么处理啊?

    作者回复: 没看懂呀~

    2019-09-24
收起评论
33
返回
顶部