西瓜视频基于 Hertz 的微服务落地实践

news2025/1/12 20:55:50

# 1.  西瓜视频微服务架构设计

## 1.1 西瓜视频介绍

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

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

## 1.2 微服务架构设计时关注哪些方面

### 业务域划分

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

-   单一职责原则:确保每个微服务只负责一个特定的业务功能,避免职责混乱。
-   领域驱动设计:使用领域驱动设计方法来划分服务边界,确保各个服务独立、可复用。

这样设计之后,可以保证:

-   业务模块的独立性:每个微服务可以独立开发、测试、部署和扩展,提升了开发效率和系统的灵活性。
-   技术栈灵活性:不同的微服务可以使用最适合其业务需求的技术栈,不需要统一技术选型。
-   故障隔离:一个服务的故障不会影响其他服务的运行,提高了系统的可用性和稳定性。
-   按需扩展:可以根据每个服务的负载情况独立扩展,优化资源使用和成本。

### 性能

## 1.3 架构设计

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

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

### 接入层

-   不同的分端:包括西瓜app,西瓜pc,我们的TV端鲜时光以及M站。

-   负载均衡及网关

    -   使用公司内部组件来提供负载均衡和通用网关能力。

-   API服务:使用Hertz框架的服务。

### 业务层

-   消费侧业务,基础业务,和其他的一些互动社区等RPC业务,这些服务采用的是Kitex框架。

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

-   互动模块

    -   在这些业务之外,我们还会有其他的一些互动和社区的功能模块。这种都是有公司专门的关系中台、评论中台去维护。同时,我们的业务还会依赖业务用到的存储,像mysql、redis等。

## 基础组件

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

# 2.  Hertz框架介绍

## 2.1 背景

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

## 2.2 为什么选择Hertz

-   **极致的性能**

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

-   **易用性,开发者友好**

    -   在开发过程中,快速写出正确的代码往往是重要的。[Hertz](https://github.com/cloudwego/hertz) 在设计 API 时,考虑到用户的使用习惯,参考业界主流框架使用 API 的方式,并加以优化。在 [Hertz](https://github.com/cloudwego/hertz) 在迭代过程中,积极听取用户意见,持续打磨框架, 比如很多用户希望 Client 也有 Trace 的能力,为此,[Hertz](https://github.com/cloudwego/hertz) Client 支持了中间件能力。[Hertz](https://github.com/cloudwego/hertz) 也提供了命令行工具,一键生成代码,提高框架的易用性。
    -   Hertz 提供了一个简单易用的命令行工具 Hz,用户只需提供一个 IDL,根据定义好的接口信息,Hz 便可以一键生成项目脚手架,开箱即用使用 Hertz;Hz 也提供更新能力,用户的 IDL 如果发生改变,Hz 可以更新脚手架。 目前Hz支持了 Thrift 和 Protobuf 两种 IDL 定义。命令行工具内置丰富的选项,可以根据自己的需求使用。

-   **丰富的文档体系**

    -   即使是从来没有使用过相关框架的新同学,都能够通过相应的文档,快速上手 Hertz,体验 Hertz 所带来的极致的开发体验。

-   **稳定性**

    -     Hertz对内对外支撑了大量的业务服务,业务选择hertz的一个重要考量就是稳定性。Hertz也制定了各种措施来保证框架的稳定性:
    -   基于线上流量特征的随机模拟。hertz会根据线上真实的流量曲线,通过模拟和重放的方式,在测试环境中复现各种极端的高并发场景,从而验证系统的承载能力和容错能力。
    -   核心API全覆盖。Hertz所有对外提供服务的API接口,无一例外都要经过完备的性能测试、压力测试和负载测试,确保在各种极限情况下也能保持稳定和高效。
    -   适配不同的线上部署环境。针对hertz服务的不同场景,会准备不同的线上环境,。这些环境硬件资源配置不尽相同,通过在不同环境中反复测试和验证,可以全面评估系统的稳定性和可扩展性。
    -   7*24小时监控大盘。全天候实时监控系统的各项核心指标,一旦发现异常,能够第一时间定位并通知值班人员介入处理。
    -   严格的发布流程。Hertz对系统的每一次上线升级都有特别严格的流程要求,必须经过线下测试、验证、代码review等多个环节,避免出现变更带来的风险。

-   **低廉的迁移成本**

    -   西瓜早期的api服务都是基于Ginex框架开发的。而Hertz 立项之初,就将针对存量 Ginex 服务的迁移作为一个高优需要照顾的环节。在一些业务常用API上做了许多兼容性的设计。
    -   同时,Hertz 也为存量项目提供了一键迁移的方案Ginex 项目快速迁移 Hertz 1.x 指南 ,使用一键迁移工具,用户可能无需/只需改动少量代码即可完成 Gin —> Hertz 项目的迁移。

-   丰富的扩展能力

    -   [Hertz](https://github.com/cloudwego/hertz) 采用了分层设计,提供了较多的接口以及默认的扩展实现,用户也可以自行扩展。Hertz目前支持了日志、监控、服务注册与发现、网络库和协议等扩展能力,未来有望为用户提供更多的扩展能力。

# 3.  Hertz迁移过程、踩坑经验

## 3.1 迁移过程

1.  选择要迁移的服务

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

2.  SDK库适配

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

3.  执行一键迁移脚本

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

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

4.  手动修改

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

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

Hertz预置了几款中间件:

•Recovery中间件:负责处理链路上的panic

•Metrics中间件:负责请求相关指标上报

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

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

## 3.2 踩坑经验

-   **Query tag 缺失导致请求参数解析失败**

    -   表现

        -   Query 请求参数在服务端没有解析成功,调用 RequestContext 进行参数绑定的时候报错。

    -   原因

        -   参考**[Hertz 支持的参数绑定与校验相关功能及用法](https://www.cloudwego.io/zh/docs/hertz/tutorials/basic-feature/binding-and-validate/)**,不通过 IDL 生成代码时若字段不添加任何 tag 则会遍历所有 tag 并按照优先级绑定参数,添加 tag 则会根据对应的 tag 按照优先级去绑定参数。
        -   请求参数有关的结构体未设置 query tag,导致 query 请求参数在服务端没有解析成功。

    -   解决方式

        -   结构体添加 query tag
        -   通过单元测试提前规避

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

    -   表现

        -   在一些场景下,前端有时候传来的信息只有 key 没有 value,这会导致绑定数值类型的时候报错。

    -   原因

        -   未配置looseZero模式

    -   解决方式

# 4.  落地Hertz后的收益

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

-   平均CPU核数从2730降为2443
-   单核QPS处理能力提升:10.7%
-   内存占用率变化—优化前:31.1% ,优化后: 29.3%
-   核心接口LatencyPct99下降:10.15%

**项目地址**

GitHub:https://github.com/cloudwego

官网:www.cloudwego.io

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1854214.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OpenAPI

大家好我是苏麟 , 今天带来一个前端生成接口的工具 . 官网 : GitHub - ferdikoomen/openapi-typescript-codegen: NodeJS library that generates Typescript or Javascript clients based on the OpenAPI specification 安装命令 npm install openapi-typescript-codegen --sa…

flex布局无法设置图片icon和文本垂直居中对齐问题

项目场景: 需要实现下面的效果,即图标和文字垂直对齐。 问题描述 直接使用flex布局并设置垂直居中,发现并没有垂直对齐,图片明显偏上。 .wrapper {display: flex;align-items: center; }.view-icon {height: 28px;width: 28px;m…

02_ESP32+MicroPython 点亮LED灯

书接第1篇《01_ESP32 MicroPython开发环境搭建_eps32开发板-CSDN博客》 想要让一个引脚输出高电平,只需要找到对应的GPIO然后通过on()或者value(1)操作就可以,同理如果想要输出低电平让LED灯灭,只需要调用off()或者value(0)就行。 一、点亮…

InfoMasker :新型反窃听系统,保护语音隐私

随着智能手机、智能音箱等设备的普及,人们越来越担心自己的谈话内容被窃听。由于这些设备通常是黑盒的,攻击者可能利用、篡改或配置这些设备进行窃听。借助自动语音识别 (ASR) 系统,攻击者可以从窃听的录音中提取受害者的个人信息&#xff0c…

Linux C/C++ socket函数

目录 socket函数 函数原型 头文件 功能 返回值 参数 错误码 socket函数 函数原型 int socket(int domain, int type, int protocol); 头文件 #include <sys/types.h> #include <sys/socket.h> 功能 创建一个用于通信的端点&#xff0c;并返回一个文件描述符…

档案数字化建设花费主要在哪里

在档案数字化建设中&#xff0c;主要花费包括以下几个方面&#xff1a; 1. 技术设备和软件&#xff1a;包括购买和维护服务器、计算机、扫描仪、存储设备等硬件设备&#xff0c;以及购买和使用专久智能档案数字化软件和系统。 2. 人力资源&#xff1a;数字化建设需要专业的技术…

K8S - 理解ClusterIP - 集群内部service之间的反向代理和loadbalancer

在Micro Service的治理中。 有两个很重要的点&#xff0c; 集群外部的用户/service 如何访问集群内的 入口服务(例如UI service&#xff09;集群内的service A 如何 访问 集群内的service B 为什么有上面的问题 无非是&#xff1a; 集群内的service 都是多实例的每个servic…

GIM: Learning Generalizable Image Matcher From Internet Videos

【引用格式】&#xff1a;Shen X, Yin W, Mller M, et al. GIM: Learning Generalizable Image Matcher From Internet Videos[C]//The Twelfth International Conference on Learning Representations. 2023. 【网址】&#xff1a;https://arxiv.org/pdf/2402.11095 【开源代…

什么是慢查询——Java全栈知识(26)

1、什么是慢查询 慢查询&#xff1a;也就是接口压测响应时间过长&#xff0c;页面加载时间过长的查询 原因可能如下&#xff1a; 1、聚合查询 2、多表查询 3、单表数据量过大 4、深度分页查询&#xff08;limit&#xff09; 如何定位慢查询&#xff1f; 1、Skywalking 我们…

AIGC系列之一-一文理解什么是Embedding嵌入技术

摘要&#xff1a;嵌入技术&#xff08;Embedding&#xff09;是一种将高维数据映射到低维空间的技术&#xff0c;在人工智能与图形学研究中被广泛应用。本文将介绍嵌入技术的基本概念、原理以及在 AIGC&#xff08;Artificial Intelligence and Graphics Computing&#xff09;…

轻松上手MYSQL:MYSQL事务隔离级别的奇幻之旅

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》《MYSQL》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 ✨欢迎加入探索MYSQL索引数据结构之旅✨ &#x1f44b; 大家好&#xff01;文本学习…

C++封装、继承、多态的应用---职工管理系统

C封装、继承、多态的应用—职工管理系统 文章目录 C封装、继承、多态的应用---职工管理系统1.需求分析2.抽象类的建立2.1抽象基类2.2员工类2.3经理类2.4老板类2.5存储类 3.抽象类的实现4.功能函数的实现4.1菜单功能的实现4.2增加职工功能函数实现4.2显示职工功能函数实现4.3删除…

力扣SQL50 销售分析III having + 条件计数

Problem: 1084. 销售分析III &#x1f468;‍&#x1f3eb; 参考题解 Code select s.product_id,p.product_name from sales s left join product p on s.product_id p.product_id group by product_id having count(if(sale_date between 2019-01-01 and 2019-03-31,1,nu…

【2024最新版】Mysql数据库安装全攻略:图文详解(Windows版本)

目录 1. 引言1.1 MySQL特性1.2 开源1.3 跨平台支持1.4 编程接口1.5 系统特性1.6 性能优势 2. 安装版本选择3. 安装MySQL3.1 下载MySQL3.2 安装MySQL 1. 引言 MySQL是一种流行的关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;具有高度的可靠性、可扩展性和性能…

C++系列-String(二)

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” #define _CRT_SECURE_NO_WARNINGS #include<string> #include<iostream> #include<list> #include<algorithm> using namespace std; void test_string…

计算机组成入门知识

前言&#x1f440;~ 数据库的知识点先暂且分享到这&#xff0c;接下来开始接触计算机组成以及计算机网络相关的知识点&#xff0c;这一章先介绍一些基础的计算机组成知识 一台计算机如何组成的&#xff1f; 存储器 CPU cpu的工作流程 主频 如何衡量CPU好坏呢&#xff1f…

基于stm32的温度采集并且显示

目录 一、I2C总线通信协议 &#xff08;一&#xff09;I2C简介 &#xff08;二&#xff09;I2C物理层 &#xff08;三&#xff09;I2C协议层 1、I2C基本读写过程 2、通信的起始和停止信号 3、数据的有效性 4、地址及数据方向 5、响应 &#xff08;四&#xff09;软件I…

常说的云VR是什么意思?与传统vr的区别

虚拟现实&#xff08;Virtual Reality&#xff0c;简称VR&#xff09;是一种利用计算机技术模拟产生一个三维空间的虚拟世界&#xff0c;让用户通过视觉、听觉、触觉等感官&#xff0c;获得与现实世界类似或超越的体验。VR技术发展历程可追溯至上世纪&#xff0c;经历概念提出、…

方差分析【单/双因素方差分析】

文章目录 方差分析一、单因素方差分析&#xff08;Analysis of Variance&#xff09;1.方差分析在做什么&#xff1f;2.方差分析的思路&#xff1a;3.方差分析中的计算&#xff1a;4.构造F统计量&#xff1a; 二、双因素方差分析(Two-way ANOVA)1.双因素方差分析在做什么&#…

HCIA 18 结束 企业总部-分支综合实验(上)

1.实验介绍及拓扑 &#xff08;1&#xff09;总部和分支机构都可以上互联网访问8.8.8.8&#xff1b; &#xff08;2&#xff09;总部和分支机构使用广域网专线互访作为主线&#xff0c;并且通过互联网建立GRE隧道互访作为备线&#xff1b; &#xff08;3&#xff09;总部内为…