高性能 RPC 框架 CloudWeGo-Kitex 内外统一的开源实践

日前,字节跳动技术社区 ByteTech 举办的第七期字节跳动技术沙龙圆满落幕,本期沙龙以《字节高功用开源微服务结构:CloudWeGo》为主题。在沙龙中,字节跳动字节跳动根底架构服务结构资深研制工程师杨芮,跟咱们共享了《高功用 RPC 结构 Kitex 表里一致的开源实践》,本文依据共享整理而成。

本文将从以下四个方面介绍 CloudWeGo 高功用 RPC 结构 Kitex 的实践及开源:

  1. 由内至外 – 开源过渡;
  2. 开源一年改变回忆;
  3. 社区共建完善生态及企业落地;
  4. 总结和展望。

1. 由内至外 – 开源过渡

许多同学或许刚刚了解 CloudWeGo,先介绍一下 CloudWeGo 和 Kitex 的关系。

1.1 CloudWeGo 和 Kitex

Kitex 是 CloudWeGo 开源的榜首个微服务结构,它是一个支撑多协议的Golang****RPC结构,从网络库、序列化库到结构的完结基本彻底自研的。特别地,Kitex 对 gRPC 协议的支撑运用了 gRPC 官方的源码,可是咱们对 gRPC 的完结做了深度且定制的优化,所以 Kitex 支撑的 gRPC 协议功用优于 gRPC 官方结构,功用数据后边会给出比照说明。一起这也是 Kitex 与现在现已开源的支撑 gRPC 协议的其他 Golang 结构的首要差异。假如用户想运用 gRPC 又对功用有很高的要求,那么 Kitex 结构将会是一个很不错的挑选。

继 Kitex 开源后,本年 CloudWeGo 又陆续开源了 Golang HTTP 结构 Hertz ,Rust RPC 结构 Volo,一起环绕这些微服务结构和微服务的一些通用才能,咱们还开源了一些高功用的根底库。关于更多 CloudWeGo 开源的子项目,能够进入 CloudWeGo 官网详细了解。

CloudWeGo 官网:www.cloudwego.io/

高性能 RPC 框架 CloudWeGo-Kitex 内外统一的开源实践

社区同学向我反应,一些开源群里咱们会讨论 Kitex 会不会是一个字节跳动的开源 KPI 项目呢?它的稳定性、继续功用够得到保障吗?我能够负责任地讲,Kitex 不是一个 KPI 项目,它是来自字节跳动内部大规模实践的真实项目。在 Kitex 开源后始终保持表里一致,依据表里代码的一致咱们保证了 Kitex 的继续迭代。为了进一步消除咱们的顾忌,下面详细介绍一下 Kitex 的诞生和开源进程。

高性能 RPC 框架 CloudWeGo-Kitex 内外统一的开源实践

1.2 Kitex 发展前史

2014 年,字节跳动开端引进 Golang。2015 年,字节跳动内部的服务化开启。在 RPC 调用的场景挑选了 Thrift 协议,内部开端支撑 RPC 结构。2016 年,榜首个 Golang RPC 结构 Kite 正式发布。通常在一个公司高速发展的初期,根底才能都是为了快速支撑需求落地,面对的需求场景也较单一,规划上不会有较多考量,其实这也是合理的,因为探究阶段并不彻底清楚还需求支撑哪些场景,过多的考虑反而会呈现过度规划的问题。

可是,跟着事务场景复杂化,需求也会多样化,并且接入服务及调用量逐年增长,Kite 现已不足以支撑后续的迭代,在线上服役三年多后,2019 年咱们开启了新的项目 Kitex,2020 年初发布了正式版别,在 2020 年底字节内部现已有 1w+ 服务接入 Kitex。

从 2014 年到 2020 年,Golang 现已是字节跳动内部首要的事务开发言语,应该是业界 Golang 运用最多的公司,咱们的服务结构支撑着数万个 Golang 微服务的牢靠通讯,经过数量许多的微服务和海量流量的验证,咱们现已有了较为老练的微服务最佳实践,所以考虑将内部的实践开源出去丰厚云原生社区的 Golang 产品系统。在 2021年,咱们以 CloudWeGo 品牌正式开源了榜首个服务结构 Kitex。截止本年 8 月,Kitex 现已为字节跳动内部6w+ 的服务供给支撑,峰值QPS到达上亿级别

咱们或许还有疑问,完好的微服务系统离不开根底的云生态,无论在公有云、私有云,都需求建立额外的服务以很好地支撑微服务的管理,比方管理渠道、注册中心、装备中心、监控、链路盯梢、服务网格等,并且还存在一些定制的标准。字节跳动自然也有完善的内部服务支撑微服务系统,但这些服务短期还无法开源,那 CloudWeGo 怎么表里保护一套代码,一致迭代呢?

关于这个问题,咱们看一下 Kitex 的模块划分。Kitex 的模块分为三个部分:中间是 Kitex 主干部分Kitex Core,它界说了结构的层次结构、接口中心逻辑的完结以及接口的默许完结;左面的Kitex Tool则是与生成代码相关的完结,咱们的生成代码东西便是编译这个包得到的,其间包括 IDL 的解析、校验、代码生成、插件支撑等。不过为了便于用户运用一起供给更友爱的扩展,首要才能也做了拆分作为根底库独立开源,如 Thriftgo、Thrift-validator 插件、Fastpb;右边的Kitex Byted是对字节内部根底才能集成的扩展完结,咱们在开端就将内部的才能作为扩展收敛到一个 package 下。

高性能 RPC 框架 CloudWeGo-Kitex 内外统一的开源实践

如此就能够将 Kitex Core 和 Tool 部分开源出去,咱们将代码做了拆分,Kitex 的中心代码和东西部分迁移到开源库,集成内部扩展的模块作为 Kitex 的扩展保留在内部库,一起内部库封装一层壳保证内部用户能够无感知地升级。

那么 Kitex 的开源就只是代码拆分这么简略吗?明显不是。2021年2月,咱们开端筹备 Kitex 的开源,尽管依据 Kitex 的扩展性,咱们能够与内部根底设施集成的才能解耦,可是 Kitex 仍然依靠内部的一些根底库,假如要开源必须先开源根底库的才能。所以咱们首要做了依靠库的整理,与相关的同学协作先开源了b yte d ance/gopkg库。这个库由 CloudWeGo 与字节跳动的言语团队协作保护,里边包括也了对 Golang 标准库才能的增强,感兴趣的同学能够重视运用。

bytedance/gopkg: github.com/bytedance/g…

在 gopkg 库开源后,咱们调整代码进行开源适配。2021 年 7 月,Kitex 正式开源,在内部发布中版别运用开源库。但 Kitex 毕竟支撑了内部几万的微服务,咱们必须要保证内部服务在这个改变后能够滑润过渡,所以在开源初咱们没有对外官宣,在确认稳定性后,2021年9月,Kitex 正式对外官宣开源。

介绍完了 Kitex 诞生、开源的进程,期望能够消除外部同学关于“Kitex 会不会是一个 KPI 项目?”的顾忌。

1.3 开源的价值

榜首部分的最后,简略讲一下开源能为咱们带来的价值。Kitex不是为了开源而完结的,但它的完结是面向开源的。 Kitex 自身是一个经过内部大规模完结的项目,咱们期望 Kitex 开源后能帮助更多用户在内部快速建立微服务,一起开源能让咱们搜集更多社区和企业的反应,也能招引外部开发者共建,促进 Kitex 面向多元场景支撑的演进,丰厚产品才能,然后能在更多场景和企业得到落地,这是一个正向循环,互利共赢的进程。

高性能 RPC 框架 CloudWeGo-Kitex 内外统一的开源实践

2. 开源一年改变回忆

2.1 结构的衡量目标

在介绍 Kitex 开源一年改变前,先共享一下结构的衡量目标,这是咱们在挑选一个结构时要考虑的。

  • 扩展性

假如一个结构与内部才能强耦合,就无法移植到其他渠道,或结构的支撑场景单一也无法进行扩展,这样的结构很难得到外部的运用。

  • 易用性

结构的易用性体现在两个方面。榜首是面向事务开发者,假如一个结构在运用进程中需求让用户重视许多结构的细节,那么对研制功率要求很高的团队或许无法接受。第二是面向结构的二次开发者,他们需求对结构做一些定制支撑,假如结构供给的扩展才能过于广泛,扩展本钱很高,或许可扩展的才能不够多,那么这个结构也是存在局限性的。

  • 功用的丰厚度

尽管依据扩展功用够对结构进行定制,但不是一切开发者都有足够的精力做定制开发,假如结构自身对各种扩展才能供给了不同挑选的支撑,关于开发者来说只需求依据自己的根底设施进行组合就能在自己的环境中运行。

  • 高功用

前面三点是初期挑选结构需求重点重视的目标,但跟着服务规模和资源耗费变大,功用就成了不容忽视的问题。从长期的视点来说,挑选结构的时分一定要重视功用,否则后续只能面对结构替换的问题,或许被迫对这个结构做定制保护。

关于以上四点结构的衡量目标,尽管 Kitex 现在还没做到最好,可是这四个要素都是 Kitex 规划和完结中一直在统筹的,咱们不会顾此失彼。

2.2 功用特性

下面就几个开源一年来重要的功用特性进行介绍。

2.2.1 Proxyless

Proxyless 是 Kitex 面向开源场景供给的支撑。在 Kitex 开源初期,咱们内部讨论过是否要支撑 xDS 对接 Istio,关于外部用户来说,运用 Istio 能够快速建立一套基本的微服务架构,处理服务发现、流量路由、装备下发等问题,可是假如运用完好的 Istio 的处理方案,就要引进 Envoy,这会添加运维本钱,并且直接运用官方的 Envoy 方案对功用有损,会引进额外的 CPU 开销且添加推迟。假如 Kitex 能直接对接 Istio,既能让用户享受到部分 Istio 的才能,又能够避免 Envoy 带来的功用损失和部署运维本钱。 可是在开源初期,咱们没有看到很清晰的用户诉求,因而没有对此做高优的支撑。

高性能 RPC 框架 CloudWeGo-Kitex 内外统一的开源实践

后来 gRPC 官方也发布了 Proxyless 的支撑,一起 Istio 的官方也将 Proxyless 作为运用 Istio 的一种办法。Kitex 现在也已完结支撑,现在首要是对接服务发现,xDS 支撑的扩展独自开源到了 kitex-contrib/xds 库中,后续还会完善。咱们能够依据 README 了解怎么运用 Kitex 对接 Istio。

xDS Support: github.com/kitex-contr…

2.2.2 JSON 和 Protobuf 泛化调用支撑

之前,Kitex 支撑了运用在网关场景的 HTTP 泛化,以及支撑了运用在一些通用服务场景的 Map 和二进制泛化。开源后,依据用户的需求反应又新增了 JSON 和 Protobuf 的泛化。

Protobuf 的泛化也是运用在 API 网关的场景。本来的 HTTP 泛化传输的数据格式是 JSON,可是 JSON 的序列化体积大、功率低,对功用有影响,所以许多移动端的接口挑选运用 Protobuf 传输数据,因而添加了 Protobuf 泛化的支撑。

高性能 RPC 框架 CloudWeGo-Kitex 内外统一的开源实践

现在Kitex的泛化首要针对后端的Thrift服务,无论是Protobuf Map仍是 JSON,Kitex 都会在调用端结合IDL解析,将这些数据映射编码为 Thrift 包发给后端服务。

那么为什么把泛化放在调用端而不是服务端呢?咱们广泛了解的泛化都是服务端对泛化恳求做了解析处理,当然调用端也要相应地供给泛化的 Client。可是泛化面向的是通用服务,泛化运用本钱其实是比较高的,它并不适用于普通的 RPC 场景,而通用服务面向的是一切后端的服务,有 Golang/Java/C++/Python/Rust,假如每一种言语结构都支撑泛化,本钱是非常高的。就算各个言语都对泛化做了支撑,结构版别收敛又是一个漫长的进程,关于通用服务来说,对接一切的服务就显得不太实际。综合以上原因,泛化放在调用端支撑。

2.2.3 重试才能增强

去年开源时,Kitex 现已支撑了重试功用。之前支撑的重试有两类,一个是超时重试,一个是 Backup Request。

关于超时来重试来说,咱们只会对超时这一种反常进行重试,但为了进一步进步恳求成功率,用户期望对其他的反常也进行重试,或许用户或许会界说一些用户恳求的状况码,结合用户状况码进行重试,在这种情况下,明显咱们只支撑超时重试是不满足用户需求的。依据这个布景,Kitex新增了 指定成果重试,用户能够指定其他反常或指定某一类 Response,结构会结合用户指定的成果进行重试。

其次,用户在装备重试时,假如经过代码装备的办法设置重试,它会对整个 Client 的一切 RPC 办法收效,可是用户期望针对不同的 RPC 办法运用不同的重试战略,甚至同一个办法也期望能够选用不同的重试战略,因为不同链路上发起的同一个办法的恳求对目标要求也会不同。比方有些想运用 Backup Request 削减推迟,有些想做反常重试进步成功率,关于这种情况,Kitex新的版别支撑了恳求粒度装备重试

下图是运用示例。以恳求粒度重试装备为例,比方 RPC 办法是Mock,那么咱们在发起 RPC 调用的时分,在后边能够装备一个callopt指定重试战略,此次恳求就会运用这个重试战略。

高性能 RPC 框架 CloudWeGo-Kitex 内外统一的开源实践

2.2.4 Thrift Validator

Thrift-gen-validator 是 Thriftgo 的一个东西插件,它能够依据 Thrift IDL 中界说的注解描绘束缚给对应的struct生成IsValid() error办法,校验值的合法性。通常做 RPC 调用的时分,用户或许会对一些字段校验合法性,用户假如直接写这些校验代码,投入的本钱会很高。所以咱们就供给了注解支撑,只需用户在 IDL中依据标准界说注解,Kitex 就能够帮助用户生成校验代码

下图是代码生成的命令和一个 IDL 注解界说示例,在生成代码的时分指定 Thrift Validator 的插件,咱们的插件东西就会解析注解,为用户生成这一套合法性校验的代码。现在咱们也将 Thrift Validator 的功用贡献给了 Apache Thrift。

高性能 RPC 框架 CloudWeGo-Kitex 内外统一的开源实践

2.3 功用优化

介绍完几个重要的功用特性,再介绍几个在功用上的优化特性。

2.3.1 Thrift 高功用编解码

Frugal是一 无需生成编解码代码、 依据JIT的高功用动态Thrift编解码器。 尽管咱们针对官方 Thrift 编解码现已做了优化,支撑了 FastThrift,这个在咱们开源前发布的优化实践里也有介绍,但咱们期望能有进一步的功用提高,参阅咱们开源的高功用 JSON 库 Sonic 的规划,完结了 Thrift JIT 编解码器。下图中的表格是 Frugal 结合 Kitex 与 FastThrift 的功用比照。

高性能 RPC 框架 CloudWeGo-Kitex 内外统一的开源实践

能够看到在大部分场景 RPC 功用体现都较优。除了功用上的优势,Frugal 还有另一个优势是无需生成编解码生成代码。Thrift 的生成代码比 Protobuf 深重,一个复杂的 IDL 代码生成文件能够到达几万行,而这些代码本来对用户来说无需重视,却需求由用户来保护。Frugal 只需求生成结构体代码,不需生成编解码代码,就大大处理了这个问题。

关于怎么在 Kitex 中运用 Frugal,能够参阅库房的 Readme。当然用户也能够独自运用 Frugal 作为 Thrift 高功用编解码器,Kitex 后续也会考虑默许运用 Frugal。

Frugal: github.com/cloudwego/f…

2.3.2 Protobuf 高功用编解码

尽管咱们内部首要支撑 Thrift,但开源之后咱们发现外部用户关于 Protobuf 或 gRPC 的重视会更多,所以参阅 Kitex FastThrift 的优化思路,从头完结了 Protobuf 的生成代码。在 v0.4.0 版别,假如用户运用 Kitex 的东西生成 Protobuf 的代码,就会默许生成 Fastpb 的编解码代码,在发起 RPC 调用的时分,Kitex 也会默许运用 Fastpb。

下图是 Fastpb 与官方 Protobuf 序列化的功用比照,能够看到无论是编码仍是解码,在功率和内存分配上,Fastpb 都远远优于官方 Protobuf 序列化库。

高性能 RPC 框架 CloudWeGo-Kitex 内外统一的开源实践

2.3.3 gRPC 功用优化

开源初期,咱们对 gRPC 整体稳定性和功用的重视是比较少的。因为内部运用的场景不是许多。开源后收到了许多外部同学的反应,所以咱们针对 gRPC 做了一个专项的问题管理以及功用优化。本年中旬咱们现已把相关的优化正式提交到开源库,在 v0.4.0 版别发布。

Kitex v0.4.0: mp.weixin.qq.com/s/ezifbQkHc…

下图中左侧是优化前 Kitex-gRPC 和官方 gRPC 结构对Unary 恳求的压测吞吐比照,在并发比较低的情况下,Kitex 的吞吐并不具有优势,运用 Fastpb 的时分,Kitex 的吞吐体现会好一些,但低并发的吞吐仍然低于官方 gRPC。在优化之后,吞吐比照如右图所示。相比优化前吞吐提高 46% – 70% ,相比官方 gRPC 结构,吞吐高 51% – 70%

下图中右侧是优化后Unary 恳求的推迟比照,在吞吐比官方 gRPC 高出许多的情况下,Kitex 的推迟也明显低于官方的 gRPC。一起就 Kitex 自身而言,在优化后推迟体现也好了许多。

高性能 RPC 框架 CloudWeGo-Kitex 内外统一的开源实践

咱们再看下Streaming 恳求的压测功用比照,优化前 Streaming 恳求的体现相同在低并发的情况下,相对 gRPC 结构没有优势。经过优化后,Kitex 吞吐明显高于官方 gRPC,如下图,一起低并发下吞吐高但推迟持平,添加并发后能看到推迟呈现分叉。所以在功用上, Kitex 支撑的 gRPC 协议相对官方有明显的优势。

高性能 RPC 框架 CloudWeGo-Kitex 内外统一的开源实践

尽管在部分功用上,Kitex 还没有彻底对齐,可是现在现已能够满足大部分的场景需求,咱们后续也会继续进行功用对齐。

3. 社区共建完善生态及企业落地

3.1 社区共建的 Kitex 扩展生态

开源后,咱们很欣慰得到了许多开发者的重视,坦白说内部团队精力有限,无法快速建立起面向外部用户的 Kitex 扩展生态。可是一年以来借助社区的力气,Kitex 在服务注册/发现可观测性服务管理几部分的扩展得到了许多弥补,尤其是服务注册/发现相关的扩展,现在开源的干流注册中心都已完结对接,尽管在功用丰厚度上咱们还有待加强,但结合已有的支撑,关于外部用户现已具有了建立微服务架构的才能。

衷心感谢积极参与 CloudWeGo 社区建造的同学们!关于 Kitex 相关的生态支撑,咱们能够进入 Kitex-contrib 了解更多的开源库房。

Kitex-contrib: github.com/kitex-contr…

3.2 对接外部企业,帮忙落地

咱们开源的初衷是为了助力其他外部企业快速地建立企业级的云原生架构。开源后,森马、华兴证券、贪玩游戏、禾多科技先后自动与咱们联系,反应运用问题、提出需求,的确让咱们发现了一些和内部场景不一样的问题,需求咱们去重视、支撑和优化,咱们很开心 Kitex 能在这些企业内部得到运用。在本年 6 月 25 日的 CloudWeGo Meetup 中,森马和华兴证券的研制同学也共享了他们运用 Kitex 的内部实践。

森马:mp.weixin.qq.com/s/JAurW4P2E…

华兴证券:mp.weixin.qq.com/s/QqGdzp-7r…

高性能 RPC 框架 CloudWeGo-Kitex 内外统一的开源实践

除了以上企业,还有一些公司也私下向咱们咨询过运用问题,咱们非常感谢这些企业用户的支撑,以及向咱们提出的反应信息。如榜首部分所讲,搜集社区和企业的反应能够促进 Kitex 面向多元场景支撑的演进,企业用户假如有相关需求,欢迎来联系咱们。

3.3 怎么运用 Kitex 与内部根底设施集成

这里再简略介绍下怎么运用 Kitex 与咱们的内部根底设施集成。以字节内部为例,内部库房里有开源库中的扩展完结,集成内部的才能,在 bytedSuite 中,咱们针对不同场景对 Kitex 进行初始化。如下面的代码示例,用户只需求在构造 Client 和 Server 时添加一个 option 装备就能够完结集成,不过为了让用户彻底不需重视内部才能的集成,咱们将该装备放在了生成的脚手架代码中,关于装备怎么内嵌在生成代码中,后续咱们也会敞开出来,便利外部的结构二次开发者能以相同的办法为事务开发同学供给集成才能。

高性能 RPC 框架 CloudWeGo-Kitex 内外统一的开源实践

4. 总结和展望

4.1 总结

本次共享首要介绍了以下内容:

  • Kitex 怎么保持表里一致地从内部运用较广的结构转为开源结构;
  • 开源一年以来发布了哪些重要的功用特性,做了哪些功用优化;
  • 借助社区的力气现在 Kitex 的周边生态怎么、企业落地情况以及怎么运用 Kitex 高雅地集成内部才能。

4.2 展望

  • 与社区同学共建,继续丰厚社区生态;
  • 结合工程实践,为微服务开发者供给更多便利;
  • 完善好 BDThrift 生态,继续优化 Protobuf/gRPC;
  • 更多特性支撑或开源,ShmIPC、QUIC、Protobuf 泛化…

5. 字节跳动 CloudWeGo 团队

CloudWeGo 是一套由字节跳动开源的、可快速构建企业级云原生微服务架构的中间件调集。它包括许多组件:Golang RPC 结构 Kitex,HTTP 结构 Hertz,Rust RPC 结构 Volo,网络库 Netpoll,Go 言语 Thrift 编译器 Thriftgo 等等。经过结合社区优异的开源产品和生态,能够快速建立一套完善的云原生微服务系统。项目一起的特点是高功用、高扩展性、高牢靠,专心于微服务通讯与管理。CloudWeGo 项目自 2021 年 9 月开源,至今开源 1 年,获得 1w+ star,代码贡献者人数已有 140+,年度 Awesome Contributor 提名 84 位。更多生态才能对接,请参阅 kitex-contrib 和 hertz-contrib。

以上内容整理自第七期字节跳动技术沙龙《字节高功用开源微服务结构:CloudWeGo》,获取讲师 PPT 和回放视频,请在大众号“字节跳动技术团队”后台回复关键词“0827”。