草庐IT

短视频、直播App性能优化调研

a乾坤大挪移a 2023-03-28 原文

前言

偶然间发现20年在负责58部落直播间性能优化时的一些方案的调研文章,由于58部落是偏业务的模块,并且直播底层框架用的是TEG团队开发的SDK,因此我们在做性能优化的时候也比较偏向于业务。因为我不能要求TEG团队去为了我们的业务上的优化去增加一些业务逻辑,这个方向肯定是不可行的,并且从SDK设计上来看也不符合整体的架构设计(底层逻辑中不可以掺杂业务逻辑)。那么我们如果做才能优化我们直播间的性能呢?针对这个方向我做了一些简单的调研,主要是了解当时业内的一些方案(22年各大厂有重新产出了很多直播间的优化方案,可以自行了解),并进行了总结。针对下面提到的方案我们通过对我们的业务分析进行了部分优化,优化效果可以说是十分明显的。例如直播间弱网或者无网络情况下的长链接禁止重连操作,观众端CPU直接优化30%+,主播端CPU优化甚至达到了50%+。

以下是具体的方案内容,注意:方案是20年的。

一、映客App的优化方向有三点:

1、直播大厅优化

2、直播间优化

3、私信消息模块优化

1、直播大厅

优化方案:

1)直播大厅列表刷新机制优化,目的优化大厅列表排名,提高正在直播的房间排名,为主播吸粉;保证直播间入口高可用。

实现策略:采用多种刷新机制相结合的方式。

1)全量刷新,登录之后全量拉去一次数据;

2)顶部刷新,TOP10通过直播流刷新,一个流一个刷新;

3)局部刷新,这个策略主要来说是从用户体验还有服务端缓存策略两个方面进行的。我们对于直播流进行分组,因为实际上当用户来浏览直播大厅时需要对当前一些直播信息进行刷新,比如当前的直播人数。刷新时间间隔通过server端配置。

用户体验方面:

1)滚动大厅或者返回时停止刷新,刷新降频。

2)直播间大厅预先解析房间的视频流地址,加快获取视频流数据的速度,减少直播间起播时间。

2、直播间

关于直播间优化,主要从4个方面讲一下。

1、定时器事件调度

2、房间内长连接消息的处理

3、动画展示

4、主播端的体验优化

下图描述的就是定时器一个事件调度,开始不同的开发人员负责不同的房间内业务模块,使用各种各样的定时器做一些请求,通知等等。后来使用统一的定时器,我们按照不同的时间间隔,对于这些事件进行调度处理。


下面会介绍模块优化的过程。第一个公聊消息列表刷新,用户在下方跟主播进行互动,我们遇到了一个问题,在直播间内公聊消息快速刷新会导致主线的CPU占用非常高,引起整体界面交互卡顿,后面就是怎么一步步解决这个问题。

第一,我们使用长连接消息库,默认就是把代理方法的执行设置到主现场。然后在做一些运营活动或者主播人气特别高的时候,大量广播消息就会导致客户端收到消息过多,很容易引起CPU比较高。针对这个问题,我们的思路是将SocketIO 库中的block执行线程设置为非主线程,缓解主线程中CPU的占用问题。

第二,我们主要是针对性能较低机型上面,会根据收到消息的速度进行实时地统计,根据收到的消息数目来动态调整公聊列表的刷新频率。

接下来我们讲一下怎么进行大量礼物动画的流畅展示,因为这是现在直播APP里面一个标配,这一部分我们优化思路就是下面3点。

首先,我们会对业务里面各种各样的礼物进行分类,收到礼物消息的时候我们就用不同优先级队列进行管理。

然后具体到展示上面,对于点赞还有弹幕,我们使用内存池,缓存点赞和弹幕中执行动画view/layer,以重复使用。

第三点,全屏动画,最开始的时候我们尝试着直接用Gif动画。从UI到产品发布,这个时间迭代时期非常短。后来我们上了一些动画试了效果以后,发现动画在CPU消耗方面会特别严重,需要图片的解码包括加载之类的,非常耗性能。

然后我们逐渐对一些全屏动画采用了Core Animation来进行一些改写。这一块也是需要开发人员对这个框架,对动画里面一些使用特别的熟悉。当然,这个也是结合UI,产品一些效果来对动画里面一些参数进行各种各样的调优。

下面讲一下我们是怎么测试这个系统的?我们会分为下面几点。

首先,就是测试环境里面会在服务端配置一些自动的脚本,对于各种各样的礼物进行压力测试,会关注一些性能指标,例如CPU,内存占用等等,包括有没有一些限制方面的问题。

第二块是要和其他的业务模块结合起来进行测试,这一点其实是很多时候往往会被忽略的。可能添加了一些其他业务模块,就会发现整体APP性能不够用。这一点是比较明显的,我们上了美颜功能,还有今年5月份3.0版本的连麦功能的时候,直播间内有三个播放器同时进行工作,一个主播放器,两个小播放器。这个时候如果再有很多的礼物画面进行展示。无论是CPU,GPU压力都是非常大的。

第三点,最终上线以前,我们导入一些线上真实广播消息数据来对这些系统进行压测,看一下整体APP表现形式什么样子。

我们在做直播端体验方面的优化时发现其中非常普遍的一个现象也是很多APP都存在的一个问题,就是一个直播做了很久,好不容易上了一下热门人气非常高了,这个时候APP突然崩溃了怎么办?

这个解决方法说起来比较简单,我们在开始直播的时候保存一些地址,还有直播间的信息。当APP真的是因为性能问题崩溃了以后。会再次启动APP弹出继续直播的按纽,实际上不会对房间内很多的一些业务造成太多的影响。然后,恢复效果其实就是相当于切后台的一个操作。

第二,我们配合后端做的一个优化,在运营时房间内的广告消息压力是非常大的。主要的现象有以下两点,包括礼物持续刷屏,实际上直播体验是非常糟糕的。大家可以看到这一张图,就是前一段时间里约奥运的洪荒之力。


针对这个运营活动的压力,我们主要的解决思路一个是采用服务降级,会在协议上和服务端做一些商定,服务端可以下发很多限制客户端公聊和礼物消息发送频率的一些命令。然后,客户端这一部分我们也会进行一些限制例如点赞及部分礼物的动画展示,尽可能保证主播端的体验。

接下来主要讲下映客在减轻服务端并发请求方面的优化。

关于用户关注关系的拉取。当你进入一个直播间的时候,都需要拉取上面的用户列表中的关注关系,主播结束直播时可能一下子有非常多用户拉取和主播的关注关系。关于这个场景,实际上会给服务端造成非常大的压力。

还有推送消息这一块。当一些明星用户进行开播全量推送时,可能会唤起大量客户端同时拉取大厅直播列表 。关于这一方面的解决思路,主要是采取缓存的策略。我们会对用户profile,关注关系等进行缓存,收到直播推送的时候,不立即刷新直播列表,延迟到退出直播间后再启动大厅刷新机制。

最后讲一点,就是客户端首次安装启动的问题,当用户首次下载映客了以后,点击登陆时会出现卡顿,这个问题的原因在于什么呢?当客户端启动的时候需要下载大量的图片资源,包括对于各种各样的礼物资源,还有很多等级资源进行请求。这个过程当中有很多大量的文件操作,这就需要我们对部分资源首先进行内置保证基本的使用,另外对于资源进行一个增量下载变现。

上面就是直播间里面一些优化的点。最后简单讲一下私信消息模块的整体设计,我们没有用第三方,而是用自己的一个整套方案。

3、私信消息


在私信里面也是涉及到一些送礼,定制化的东西,我们想做的是提高私信聊天页面的打开速度和提供一个好的浏览消息体验,只需要在内存里面缓存少量的几十条数据来进行整个展示。滑屏浏览时,动态更新缓存内容,这样用户点击某一个人进入到聊天界面,体验会得到优化。

有关短视频、直播App性能优化调研的更多相关文章

  1. ruby-on-rails - 每次我尝试部署时,我都会得到 - (gcloud.preview.app.deploy) 错误响应 : [4] DEADLINE_EXCEEDED - 2

    我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie

  2. ruby-on-rails - 如何重命名或移动 Rails 的 README_FOR_APP - 2

    当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?

  3. ruby - 使用 postgres.app 在 rvm 下要求 pg 时出错 - 2

    我正在使用Postgres.app在OSX(10.8.3)上。我已经修改了我的PATH,以便应用程序的bin文件夹位于所有其他文件夹之前。Rammy:~phrogz$whichpg_config/Applications/Postgres.app/Contents/MacOS/bin/pg_config我已经安装了rvm并且可以毫无错误地安装pggem,但是当我需要它时我得到一个错误:Rammy:~phrogz$gem-v1.8.25Rammy:~phrogz$geminstallpgFetching:pg-0.15.1.gem(100%)Buildingnativeextension

  4. Ruby 的数字方法性能 - 2

    我正在使用Ruby解决一些ProjectEuler问题,特别是这里我要讨论的问题25(Fibonacci数列中包含1000位数字的第一项的索引是多少?)。起初,我使用的是Ruby2.2.3,我将问题编码为:number=3a=1b=2whileb.to_s.length但后来我发现2.4.2版本有一个名为digits的方法,这正是我需要的。我转换为代码:whileb.digits.length当我比较这两种方法时,digits慢得多。时间./025/problem025.rb0.13s用户0.02s系统80%cpu0.190总计./025/problem025.rb2.19s用户0.0

  5. ruby - Ruby 性能中的计时器 - 2

    我正在寻找一个用ruby​​演示计时器的在线示例,并发现了下面的代码。它按预期工作,但这个简单的程序使用30Mo内存(如Windows任务管理器中所示)和太多CPU有意义吗?非常感谢deftime_blockstart_time=Time.nowThread.new{yield}Time.now-start_timeenddefrepeat_every(seconds)whiletruedotime_spent=time_block{yield}#Tohandle-vesleepinteravalsleep(seconds-time_spent)iftime_spent

  6. ruby-on-rails - 如果条件与 &&,是否有任何性能提升 - 2

    如果用户是所有者,我有一个条件来检查说删除和文章。delete_articleifuser.owner?另一种方式是user.owner?&&delete_article选择它有什么好处还是它只是一种写作风格 最佳答案 性能不太可能成为该声明的问题。第一个要好得多-它更容易阅读。您future的自己和其他将开始编写代码的人会为此感谢您。 关于ruby-on-rails-如果条件与&&,是否有任何性能提升,我们在StackOverflow上找到一个类似的问题:

  7. ruby - 为 capybara 设置 app_host 的内容 - 2

    我的测试尝试访问网页并验证页面上是否存在某些元素。例如,它访问http://foo.com/homepage.html并检查Logo图像,然后访问http://bar.com/store/blah.html并检查页面上是否出现了某些文本。我的目标是访问经过Kerberos身份验证的网页。我发现Kerberos代码如下:主文件uri=URI.parse(Capybara.app_host)kerberos=Kerberos.new(uri.host)@kerberos_token=kerberos.encoded_tokenkerberos.rb文件classKerberosdefini

  8. ruby - 如何找到我的 Ruby 应用程序中的性能瓶颈? - 2

    我编写了一个Ruby应用程序,它可以解析来自不同格式html、xml和csv文件的源中的大量数据。我如何找出代码的哪些区域花费的时间最长?有没有关于如何提高Ruby应用程序性能的好资源?或者您是否有任何始终遵循的性能编码标准?例如,你总是用加入你的字符串吗?output=String.newoutput或者你会使用output="#{part_one}#{part_two}\n" 最佳答案 好吧,有一些众所周知的做法,例如字符串连接比“#{value}”慢得多,但是为了找出您的脚本在哪里消耗了大部分时间或比所需时间更多,您需要进行分

  9. STM32的HAL和LL库区别和性能对比 - 2

    LL库和HAL库简介LL:Low-Layer,底层库HAL:HardwareAbstractionLayer,硬件抽象层库LL库和hal库对比,很精简,这实际上是一个精简的库。LL库的配置选择如下:在STM32CUBEMX中,点击菜单的“ProjectManager”–>“AdvancedSettings”,在下面的界面中选择“AdvancedSettings”,然后在每个模块后面选择使用的库总结:1、如果使用的MCU是小容量的,那么STM32CubeLL将是最佳选择;2、如果结合可移植性和优化,使用STM32CubeHAL并使用特定的优化实现替换一些调用,可保持最大的可移植性。另外HAL和L

  10. ruby - 导轨 3 : Creating app with internal plugin system - 2

    我想在Rails中使用插件系统创建一个应用程序。潜在用户应该能够上传(或更好地从存储库安装)一个插件并安装它,使我的应用程序能够做更多的事情。这应该在没有FTP/SSH/对服务器的任何低级别访问的情况下完成。关于如何在Rails3中完成它,是否有任何好的gems或教程? 最佳答案 你看过http://edgeguides.rubyonrails.org/plugins.html了吗??它似乎不是100%兼容Rails3,但它可以帮助您入门。我看过的大多数插件文章都涉及Rails2。 关于

随机推荐