据介绍,作为项目维护方,字节跳动基础架构团队已推进项目以 CloudWeGo 开源库为主进行迭代,未来团队将坚持内外维护一套代码,统一迭代演进,并逐步分享更多内部微服务佳实践
CloudWeGo 批开源了四个项目,以 RPC 框架 Kitex 和网络库 Netpoll 为主。
Kitex
Kitex 是一个 Golang 微服务 RPC 框架,具有高性能、强可扩展的特点。
字节跳动使用 Golang 作为主要业务开发语言。早在 2016 年,基础架构团队就已经开始基于 Golang 开发内部框架 Kite,并在 2019 年围绕性能和可扩展启动重构,使其能更好地满足业务发展和技术体系演进需求。
2020 年 10 月,Kitex 正式上线。虽然是一个全新的框架,但经过一年的线上应用,目前字节跳动内部已有超过 50% 的 Golang 微服务迁移到了 Kitex。
下面是 Kitex 的一些特性:
高性能:Kitex 默认集成自研网络库 Netpoll 作为网络传输模块,性能相较使用 go net 有显著优势;除了网络库带来的性能收益,Kitex 对 Thrift 编解码也做了优化,这在之前的性能优化实践文章中有介绍。关于性能数据,可参考 https://g***/cloudwego/kitex-benchmark。
扩展性:Kitex 设计上做了模块划分,提供了较多的扩展接口以及默认的扩展实现,使用者也可以根据需要自行定制扩展。Kitex 未耦合 Netpoll,开发者可选择其他网络库扩展使用。
消息协议:RPC 消息协议默认支持 Thrift、Kitex Protobuf、gRPC。Thrift 支持 Buffered 和 Framed 二进制协议;Kitex Protobuf 是 Kitex 自定义的 Protobuf 消息协议,协议格式类似 Thrift;gRPC 是对 gRPC 消息协议的支持,可以与 gRPC 互通。除此之外,使用者也可以扩展自己的消息协议。
传输协议:传输协议封装消息协议进行 RPC 互通,传输协议可以额外透传元信息,用于服务治理,Kitex 支持的传输协议有 TTHeader、HTTP2。TTHeader 可以和 Thrift、Kitex Protobuf 结合使用;HTTP2 目前主要是结合 gRPC 协议使用,后续也会支持 Thrift。
多消息类型:支持 PingPong、Oneway、双向 Streaming。其中 Oneway 目前只对 Thrift 协议支持,双向 Streaming 只对 gRPC 支持,后续会考虑支持 Thrift 的双向 Streaming。
服务治理:支持服务注册/发现、负载均衡、熔断、限流、重试、监控、链路跟踪、日志、诊断等服务治理模块,大部分均已提供默认扩展,使用者可选择集成。
代码生成工具:Kitex 内置代码生成工具,可支持生成 Thrift、Protobuf 以及脚手架代码。
Netpoll
Netpoll 是字节跳动内部的 Golang 高性能、I/O 非阻塞的网络库,专注于 RPC 场景。
RPC 通常有较重的处理逻辑(业务逻辑、编解码),耗时长,不能像 Redis 一样采用串行处理(必须异步)。而 Go 的标准库 net 设计了 BIO(Blocking I/O) 模式的 API,为了保证异步处理,RPC 框架设计上需要为每个连接都分配一个 goroutine,这在空闲连接较多时,产生大量的空闲 goroutine,增加调度开销。此外,ne***nn 没有提供检查连接活性的 API,很难设计出的连接池,池中的失效连接无法及时清理,复用低效。开源社区目前缺少专注于 RPC 方案的 Go 网络库。类似的项目如:evio、gnet 等,均面向 Redis、Haproxy 这样的场景。
因此 Netpoll 应运而生,它借鉴了 evio 和 Netty 的设计,具有出色的性能,更适用于微服务架构。
Thriftgo
Thriftgo 是 Go 语言实现的 Thrift IDL 解析和代码生成器,支持完善的 Thrift IDL 语法和语义检查,相较 Apache Thrift 的 Golang 生成代码,Thriftgo 做了一些问题修复且支持插件机制,用户可根据需求自定义生成代码。
Kitex 的代码生成工具就是 Thriftgo 的插件,CloudWeGo 近期也会开源另一个 Thriftgo 的插件 thrift-gen-validator,支持 IDL Validator,用于字段值校验,解决开发者需要自行实现代码校验逻辑的负担,弥补 Thrift 缺失的能力。
Thriftgo 目前虽然仅支持生成 Golang Thrift 代码,但其定 位是可支持各语言的 Thrift 代码生成,未来如果有需求,我们会考虑生成其他语言的代码。同时我们也会尝试将其回馈至 Apache Thrift 社区。
Netpoll-http2
Netpoll-http2 基于 Golang 标准库 g***/x/net/http2 的源码替换 go net 为 Netpoll,目前用于 Kitex 对 gRPC 协议的支持,对 HTTP2 有需求的外部开发者也可以使用此库。
前面提到字节跳动会坚持内外维护一套代码,为了遵守长期投入承诺,其基础架构团队已经将与内部生态没有耦合的项目,如 Netpoll,直接迁移到 CloudWeGo 开源库,并将内部依赖调整为开源库。
对于需要集成治理能力融入微服务体系的 Kitex,他们基于其扩展性,对内外部代码做了拆分,把 Kitex 的核心代码迁移到开源库,内部库封装一层壳保证内部用户无感知升级,而集成内部治理特性的模块则作为 Kitex 的扩展保留在内部库。字节跳动基础架构团队表示,未来也会持续把已经在内部经过稳定性验证的新特性,迁移到开源库。
谈到 CloudWeGo 的未来规划,字节跳动基础架构团队表示:“CloudWeGo 不仅仅是一个开源项目,它也是一个真实的超大规模企业级实践项目。通过开源,我们希望 CloudWeGo 能丰富云原生社区的 Golang 工具体系,为更多开发者和企业搭建云原生化的大规模分布式系统,提供一种现代的、资源的的技术方案。”
未来他们会进一步推动 CloudWeGo 走向完善:
继续开源其他内部项目。开源更多字节跳动常用 Golang 项目,如 HTTP 框架 Hertz、基于共享内存的 IPC 通信库 ShmIPC 等,为开发者提供更多场景的微服务需求支持。
逐步开源经验证的、稳定的特性。CloudWeGo 的主要项目均为字节内部微服务提供支持,许多新特性仍在内部验证,相对成熟后会逐步开源,如对 ShmIPC 的集成、无序列化、无生成代码的支持等。
结合内外部用户需求,持续迭代。项目开源后会根据开发者需求开展迭代。例如近一个月来,团队收到了来自开发者的大量关于 Protobuf 的诉求,为了提供良好的支持,他们已经在筹备开展 Kitex 对 Protobuf 支持的性能优化。