今天,字节跳动正式宣布开源 CloudWeGo。这是一套以 Go 语言为核心、专注于微服务通信与治理的中间件集合,具有高性能、可扩展、高可靠的特点。
项目地址:https://github.com/cloudwego
作为项目维护方,字节跳动基础架构团队已推进项目以 CloudWeGo 开源库为主进行迭代,未来,团队将坚持内外维护一套代码,统一迭代演进,并逐步分享更多内部微服务最佳实践。
CloudWeGo 概述
多年来,在亿级流量背后,字节跳动基础架构团队开发的技术底座支撑着庞大的微服务生态系统,从 2018 年至今,团队维护的在线微服务数量增长了近 600%,超过 5 万。面对这样的规模和增速,提高性能、可扩展性和稳定性成了构建 CloudWeGo 的核心。
CloudWeGo 第一批开源了四个项目,以 RPC 框架 Kitex 和网络库 Netpoll 为主,关于它们的技术实践,可以参考此前发布的两篇文章:《字节跳动 Go RPC 框架 Kitex 性能优化实践》《字节跳动在 Go 网络库上的实践》。
Kitex
Kitex 是一个 Golang 微服务 RPC 框架,具有高性能、强可扩展的特点。
字节跳动使用 Golang 作为主要业务开发语言。早在 2016 年,基础架构团队就已经开始基于 Golang 开发内部框架 Kite,并在 2019 年围绕性能和可扩展启动重构,使其能更好地满足业务发展和技术体系演进需求。
2020 年 10 月,Kitex 正式上线。虽然是一个全新的框架,但经过一年的线上应用,目前字节跳动内部已有超过 50% 的 Golang 微服务迁移到了 Kitex。
下面是 Kitex 的一些特性:
高性能:Kitex 默认集成自研网络库 Netpoll 作为网络传输模块,性能相较使用 go net 有显著优势;除了网络库带来的性能收益,Kitex 对 Thrift 编解码也做了优化,这在之前的性能优化实践文章中有介绍。关于性能数据,可参考 https://github.com/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,增加调度开销。此外,net.Conn 没有提供检查连接活性的 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 标准库 golang.org/x/net/http2 的源码替换 go net 为 Netpoll,目前用于 Kitex 对 gRPC 协议的支持,对 HTTP2 有需求的外部开发者也可以使用此库。
内外版本维护
完整的微服务体系离不开底层云计算生态,无论是公有云、私有云还是本地基础设施等环境,开发者要搭建微服务,离不开配套的微服务治理,如治理平台、监控、链路跟踪、注册/发现、配置中心、服务网格等,此外还存在一些定制的规范。
字节跳动自然也有完善的内部服务支持微服务体系,但这些服务短期内无法开源。为了遵守长期投入承诺,内外维护一套代码、统一迭代,基础架构团队已经将与内部生态没有耦合的项目,如 Netpoll,直接迁移到 CloudWeGo 开源库,并将内部依赖调整为开源库。
而对于需要集成治理能力融入微服务体系的 Kitex,我们基于其扩展性,对内外部代码做了拆分,把 Kitex 的核心代码迁移到开源库,内部库封装一层壳保证内部用户无感知升级,而集成内部治理特性的模块则作为 Kitex 的扩展保留在内部库。未来,我们也会持续把已经在字节跳动内部经过稳定性验证的新特性,迁移到开源库。
对于使用 CloudWeGo 的开发者,大家同样可以对 Kitex 进行扩展,将 Kitex 融入自己所在组织的微服务体系中。我们也诚挚欢迎开发者能贡献自己的扩展到 https://github.com/kitex-contrib,为更多用户提供便利。
RoadMap
对于基础架构团队,CloudWeGo 不仅仅是一个开源项目,它也是一个真实的超大规模企业级实践项目。通过开源,我们希望 CloudWeGo 能丰富云原生社区的 Golang 工具体系,为更多开发者和企业搭建云原生化的大规模分布式系统,提供一种现代的、资源高效的的技术方案。
如前文所述,目前 CloudWeGo 只开源了第一批项目,未来,我们会进一步推动其走向完善:
继续开源其他内部项目。我们会开源更多字节跳动常用 Golang 项目,如 HTTP 框架 Hertz、基于共享内存的 IPC 通信库 ShmIPC 等,为开发者提供更多场景的微服务需求支持。此前,我们已将部分 Golang 基础工具库开源,统一在 bytedance/gopkg 维护,感兴趣的开发者也可以关注。
逐步开源经验证的、稳定的特性。CloudWeGo 的主要项目均为字节内部微服务提供支持,许多新特性仍在内部验证,相对成熟后我们会逐步开源,如对 ShmIPC 的集成、无序列化、无生成代码的支持等。
结合内外部用户需求,持续迭代。项目开源后,我们也会根据开发者需求开展迭代。例如近一个月来,我们收到了来自开发者的大量关于 Protobuf 的诉求,为了提供良好的支持,我们已经在筹备开展 Kitex 对 Protobuf 支持的性能优化。
欢迎大家向 CloudWeGo 提交 issue 和 PR 共建 CloudWeGo。我们诚心期待更多的开发者加入,也期待 CloudWeGo 助力越来越多的企业快速构建云原生架构。如果企业客户想内部试用,我们可以排期提供专项技术支持和交流,欢迎入群咨询。
相关链接
项目地址:
https://github.com/cloudwego
项目官网:
www.cloudwego.io
加入飞书社群:
点个在看杀个 Bug ❤