Posted in

西瓜视频基于 Hertz 的微服务落地实践_AI阅读总结 — 包阅AI

包阅导读总结

1. 关键词:西瓜视频、Hertz、微服务、性能、迁移

2. 总结:西瓜视频是国内领先的中长视频平台,业务域划分细,微服务架构设计遵循服务划分与解耦原则。字节为解决原有框架问题开发 Hertz,西瓜视频进行服务迁移,效果显著,降低了 CPU 使用率。

3. 主要内容:

– 西瓜视频

– 是开眼界、涨知识的视频 App,月活跃创作人、用户多,日均播放量高,用户使用时长长。

– 业务域划分较细,包括中视频、电商、长视频和作者侧等。

– 微服务架构设计

– 遵循业务模块独立性、技术栈灵活性、故障隔离、按需扩展原则。

– 分为接入层、业务层和基础组件层。

– Hertz

– 字节自研高性能 Go 框架,性能指标核心,相较其他框架有优势。

– 经过两年多迭代并开源,广泛应用,降低资源使用和服务延时。

– 迁移过程

– 选择 CPU 资源消耗大的服务。

– 进行 SDK 库适配、执行一键迁移脚本、手动修改。

– 踩坑经验

– Query tag 缺失导致请求参数解析失败,解决方式为结构体添加 query tag 并通过单元测试规避。

– 未配置 looseZero 模式导致绑定数值类型报错。

– 性能收益

– CPU 使用率下降约 10%。

思维导图:

文章地址:https://mp.weixin.qq.com/s/SbCw1gOduXlICARKCpZQcg

文章来源:mp.weixin.qq.com

作者:初泽良

发布时间:2024/8/14 4:20

语言:中文

总字数:3953字

预计阅读时间:16分钟

评分:88分

标签:微服务架构,Hertz 框架,性能优化,字节跳动,技术实践


以下为原文内容

本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com

西瓜视频是一个开眼界、涨知识的视频 App (Informative Video Platform),作为国内领先的中长视频平台,它源源不断地为不同人群提供优质内容,让人们看到更丰富和有深度的世界,收获轻松的获得感,点亮对生活的好奇心。

同时,西瓜视频鼓励多样化创作,帮助人们轻松地向全世界分享视频作品,创造更大的价值。目前平台月活跃创作人超过 320 万,月活跃用户数超过 1.8 亿,日均播放量超过 40 亿,用户平均使用时长超过 100 分钟。

业务域划分

上面四张图分别对应我们的中视频、电商、长视频和作者侧的业务。当然我们的业务场景远不止这些,但是也反映出了 C 端场景多,业务域划分较细的特点,因此我们在微服务架构设计的时候需要着重考虑服务划分与解耦,在设计期间我们主要遵循两个原则:

  • 业务模块的独立性:每个微服务可以独立开发、测试、部署和扩展,提升了开发效率和系统的灵活性。

  • 技术栈灵活性:不同的微服务可以使用最适合其业务需求的技术栈,不需要统一技术选型。

  • 故障隔离:一个服务的故障不会影响其他服务的运行,提高了系统的可用性和稳定性。

  • 按需扩展:可以根据每个服务的负载情况独立扩展,优化资源使用和成本。

性能

架构设计

上图是西瓜视频整体的微服务架构设计。

从上到下我们分为三层,分别是接入层,业务层和基础组件层。

接入层

业务层

  • 消费侧业务,基础业务,和其他的一些互动社区等 RPC 业务,这些服务采用的是 Kitex 框架。
    • 消费侧业务主要面向 C 端用户的场景就是信息流和详情页。
    • 信息流:主要是西瓜 APP 的全部频道模块,包括进入西瓜视频后的首页看到的推荐精选都对应我们的信息流服务。
    • 详情页:我们知道推荐频道更多对应的是一个沉浸式的场景,但是我们的视频也会有其他的入口进入,比如个人主页等场景,这个时候点击一个视频就会进入详情页,相对于沉浸式那种更专注于视频本身播放的体验,详情页会包含更多的视频信息。
    • 推荐系统:这里是一些推荐、广告的服务,主要是提供底层的数据的 id 返回,包含广告混排,推荐排序,广告投放等功能。
    • 打包服务:公司的业务线会比较繁杂,所以随着发展抽象出了打包层,各个业务会有自己数据结构的打包服务,作为最终返回给客户端的数据。这里就包括小视频、中视频、长视频、直播等数据的打包。
    • 在这些业务之外,我们还会有其他的一些互动和社区的功能模块。这种都是有公司专门的关系中台、评论中台去维护。同时,我们的业务还会依赖业务用到的存储,像 mysql、redis 等。

基础组件

基础组件,比如语言框架,像前面提到的 Hertz、Kitex 等框架,还有一些日志、监控,配置系统。

背景

字节跳动从 2014 年开始使用 Golang,2016 年基于 Gin 框架封装了 Ginex。但 Ginex 在迭代受开源 Gin 项目限制、代码混乱膨胀导致维护困难、无法满足性能敏感和功能扩展需求等问题。2020 年部分业务线尝试魔改其他开源框架如 Fasthttp,但带来了分散生产力和巨大维护成本的问题。为解决这些痛点,字节于 2020 年初立项开发自研高性能 Go 框架 Hertz,经过两年多的迭代,Hertz 于 2022 年 6 月正式开源,目前已广泛应用于字节内部逾 1.4 万个服务,支撑日峰值 QPS 超 5000 万,显著降低资源使用和服务延时,接替大量基于 Gin 的存量服务,助力公司降本增效。

为什么选择 Hertz

  • 极致的性能

    • Hertz 的性能指标是作为一个核心指标开展设计和实现的。Hertz 默认使用自研的高性能网络库 Netpoll,在一些特殊场景相较于 go net,Hertz 在 QPS、时延上均具有一定优势。关于性能数据,大家可以看一下 hertz-benchmark(https://github.com/cloudwego/hertz-benchmark),可以看到 Hertz 的 QPS 和时延指标在和其他三个知名框架对比中已经全面占优,对比 Gin 更是遥遥领先。
    • 并且,框架整体的持续优化会贯穿框架的整个生命周期,持续不断地进行下去。

迁移过程

1. 选择要迁移的服务

迁移的第一步就是要先选择要迁移的服务,根据帕累托原则,我们优先找出占据最大比例的成本来源,并处理这些高成本项目,以最大化资源利用效率。根据性能分析平台,我们选择了目前西瓜 CPU 资源消耗最大的两个 api 服务进行迁移,分别对应我们的观看历史、点赞和弹幕的有关服务。

2. SDK 库适配

西瓜业务线对 Ginex 做了封装,提供一个 SDK 给其他 api 服务使用,比如在获取观看历史的接口中,我们会先使用 SDK 中的 newRequestContext 方法来做一些请求上下文的初始化操作。在这个请求上下文中我们会有 ab 实验、设备信息、地理位置信息等上下文的初始化。所以我们第一步就是针对 SDK 库中相应的代码进行适配。在这个适配过程中有一些三方的 SDK 库的依赖,可以直接升级 SDK 对应的 Hertz 版本。

3. 执行一键迁移脚本

Hertz 同学提供了一键迁移脚本,只需在当前服务目录下执行脚本即可完成大部分重复性的改造工作。

脚本通过正则匹配的方式完成大部分重复性替换工作,对于一些 gin、ginex 字样会替换为Hertz 中的相应的实现。

4. 手动修改

Hertz 中间件的设计采用了洋葱模型,洋葱模型是一种中间件流程控制方式,做到核心逻辑和通用逻辑分离。

中间件可以做日志记录、性能统计、安全控制、事务处理、异常处理等场景。

Hertz 预置了几款中间件:

对于业务自己实现的特殊中间件需要进行迁移,关于如何实现一个中间件 Hertz 也给出了实例。

以西瓜业务自己的特殊中间件 default_stable 为例,我们会在 header 中将 stable 设置为 1,用于做 SLO 数据统计。这种中间件我们就需要做一些适配工作,这里的话就会面临接口不匹配的问题,可以参考Gin —> Hertz API 对照表(https://github.com/hertz-contrib/migrate/blob/main/gin_to_hertz.md)进行修改。

踩坑经验

1. Query tag 缺失导致请求参数解析失败
  • 表现

  • 原因

    • 参考Hertz 支持的参数绑定与校验相关功能及用法,不通过 IDL 生成代码时若字段不添加任何 tag 则会遍历所有 tag 并按照优先级绑定参数,添加 tag 则会根据对应的 tag 按照优先级去绑定参数。

      Hertz 支持的参数绑定与校验相关功能及用法
      https://www.cloudwego.io/zh/docs/hertz/tutorials/basic-feature/binding-and-validate/

    • 请求参数有关的结构体未设置 query tag,导致 query 请求参数在服务端没有解析成功。

  • 解决方式

    • 结构体添加 query tag

    • 通过单元测试提前规避

2.未配置 looseZero 模式导致绑定数值类型报错

  • 表现

  • 原因

  • 解决方式

上线前后对比发现 CPU 使用率下降约 10%,优化效果明显,详细的性能收益如下:

GitHub:https://github.com/cloudwego

点击【阅读原文】查看