随着企业用户逐步增多,面对不同场景下不同需要和技术问题,CloudWeGo 团队将会继续分享不同企业的落地实际,蕴含不同行业面临的技术问题、选型参考和最终落地性能和应用分享,来帮忙更多用户开始应用 CloudWeGo。
飞书治理后盾是飞书套件专为企业管理员提供的信息管理平台,在单体利用架构下,它面临了一系列的挑战。它通过引入 Kitex 泛化调用对飞书治理后盾进行平台化革新,使之变为业务网关,提供一套对立的规范和通用服务,让有管控诉求的套件业务方能疾速实现能力集成,并且提供统一的体验。最终实现了飞书治理后盾作为企业对立数字化治理平台的愿景。
本文将从三个方面为大家解说 Kitex 泛化调用在飞书治理后盾平台化革新过程中的落地实际:
- 架构和挑战,即飞书治理后盾单体架构面临的各种挑战;
- 平台化构想,即飞书治理后盾平台化构想和架构降级;
- 平台化实现,包含微前端技术架构、泛化调用实际和性能扩大。
以下内容来自飞书业务中台后端架构师汪浩在 CloudWeGo 携手稀土掘金独特举办、以《CloudWeGo:从开源、凋谢到企业落地》为主题的 Meetup 流动中的分享。
01 架构和挑战
飞书是真正的一站式企业沟通与合作平台,整合视频会议、即时消息、日历、云文档、邮箱、工作台等性能于一体,立志打造高效的办公形式,减速企业成长。飞书治理后盾(以下简称 Admin)是飞书套件专为企业管理员提供的信息管理平台,企业管理员可通过后盾治理企业设置、组织架构、工作台和会议室等性能。下图是飞书治理后盾的界面。
平台革新背景
飞书采纳的是 all-in-one 的套件模式,Admin 作为整个套件对立的治理后盾,承接了包含组织治理、云文档、视频会议、邮箱、开放平台等 10 多个业务线的管控需要。始终以来的开发模式是各业务方间接在 Admin 的代码仓库提交代码或者由 Admin 团队负责 Web 层逻辑的开发。
下图是目前飞书治理后盾中包含的一些性能。之前的开发模式是业务方间接在 Admin 的代码仓库中提交代码,或者由业务方给 Admin 团队提供一些需要,由飞书来负责 Web 层逻辑的开发。
从飞书初创开始,Admin 就是以单体利用的模式开发的,随着后续飞书整体的演进,团队越来越多,不同业务线的团队也会有一些管控需要要接入 Admin 平台,因而他们就间接在代码仓库中提交代码。
Admin 架构
下图是 Admin 旧架构图。下面是 Admin 前端,它其实就是 Node 层的单体,两头是 Admin 后端,它基于外部单体 HTTP 的 Web 服务,会通过 RPC 调用到其余业务线的微服务。
面临的问题
而在这个架构下会面临一些问题。第一个问题是业务迭代慢,因为所有业务线都只能在 Admin 的代码仓库里进行开发和发版,因而这些业务线齐全依赖 Admin 的研发资源和迭代流程,Admin 的研发资源被过多的耗在各业务的迭代中,无奈疾速反对本身的业务布局,如组织架构、平安、KA 等因为飞书是 To B 的产品,因而发版节奏不会很快。如果各个业务线有一些比拟紧急的需要,也只能跟 Admin 的节奏,这就会造成发版节奏不统一,研发资源不匹配,导致 Admin 会成为业务迭代的瓶颈。
第二个问题是研发效率低,因为各个业务线须要在 Admin 的代码仓库里进行批改,因而须要理解 Admin 仓库的设计模式,而咱们在为各个业务线提供服务时,也须要理解各业务的上下文,单方都须要破费大量工夫沟通。联调、Oncall 的链路也很长,单方的责任也划不分明,导致整体的研发效率偏低。
第三个问题是工程质量差,多个团队独特保护一个代码仓库,代码品质参差不齐,设计规范也各不相同,底层的代码的批改还会相互影响,造成线上问题。
面临的挑战
首先面临的是多环境互通与隔离的挑战,咱们须要解决不同环境的网络隔离、版本异构问题。
其次是接入业务复杂性的挑战,Admin 须要集成十几个业务线,接入诉求不对立。接口协议蕴含 HTTP 协定和 Thrift 协定,还有各种自定义插件需要和权限校验需要。
最初还有平安保障的挑战,Admin 作为飞书套件的治理配置核心,关系到整个企业的数据安全。平安始终是 Admin 最重要的需要,为了保障 Admin 的接口数据安全,须要提供鉴权中间件、管理员权限验证、参数校验、风控、频控等性能,晋升业务方的平安能力。
02 平台化构想
第二局部介绍飞书平台化构想,即如何进行飞书治理后盾平台化构想和架构降级。
首先要明确的是指标,次要指标是通过提供一套对立的规范和通用服务,让有管控诉求的套件业务方能疾速实现能力集成,并且能给客户带来统一的体验。因为咱们各个业务线的管控需要都是集成在 Admin,咱们不心愿每个业务线提供的 Web 页面展现、性能和 UI 等差异较大,心愿他们是绝对对立的,最终实现 Admin 作为企业对立数字化治理平台的愿景。
对于在技术上须要达到的成果,咱们心愿业务方不要持续在 Admin 代码仓库中进行代码开发,而是间接提供咱们的后端接口和前端页面动静接入,Admin 无需代码革新和服务公布即可无缝上线,Admin 从单体利用进化为业务网关,是蕴含 UI 交互在内的独立产品模块的集成。
咱们并不是要做一个搭建零碎。目前很多平台型产品都提供 Low Code / No Code 的工具不便开发者疾速搭建所须要的性能。然而目前通过咱们对客户诉求的调研,没有相干的需要(然而不代表将来也没有,这块咱们会持续保持关注)。咱们须要做的是制订相干的规范,比方 UI、交互、API 等,业务依照规范去实现。
咱们也不是要做一个 API Gateway 或者 Service Mesh。API Gateway 的外围是 Exposes your services as managed APIs,将外部的服务以更加可控可治理的形式裸露进来,能够认为是后端服务的一个代理。Service Mesh 能够看成是 API Gateway 的去中心化实现形式,用来解决单点、隔离、耦合等问题。咱们须要解决的不仅仅是服务路由、协定转换、平安管控等问题,而是蕴含 UI 交互在内的独立产品模块的集成。
旧的框架
旧架构的前端架构是前后端拆散的 Node 单体我的项目。后端架构(Golang 实现)采纳 Hertz 框架对前端裸露 HTTP 接口,Handler 层通过 Kitex 调用依赖的各个业务线的微服务。
框架介绍
CloudWeGo 现有的两款框架别离是 Hertz 和 Kitex。Hertz [həːts] 是一个 Golang 微服务 HTTP 框架,在设计之初参考了其余开源框架 Fasthttp、Gin、Echo 的劣势,并联合字节跳动外部的需要,使其具备高易用性、高性能、高扩展性等特点,目前在字节跳动外部已宽泛应用。现在越来越多的微服务抉择应用 Golang,如果对微服务性能有要求,又心愿框架可能充沛满足外部的可定制化需要,Hertz 会是一个不错的抉择。
Kitex [kaɪt’eks] 是字节跳动外部的 Golang 微服务 RPC 框架,具备高性能、强可扩大的特点,在字节外部已宽泛应用。如果对微服务性能有要求,又心愿定制扩大融入本人的治理体系,能够思考抉择 Kitex。
新的框架
新架构次要包含:
1. Gaia 管制面。咱们减少了 Gaia 平台(基于 Hertz 框架的 Web 服务)来作为咱们整个 Admin 的控制系统,负责整体的公布和管控需要,包含接口的生命周期治理、微利用生命周期治理、监控告警、业务线接入、多环境公布等。
2. 前端架构。前端采纳微前端架构,各个业务方通过构建微利用接入 Admin 基座,应用对立封装好的组件库实现前端页面。
3. 后端架构。后端应用字节通用 BAM 标准,通过泛化调用的形式买通 Admin 和各接入业务方服务,并形象公共组件以插件的形式进行性能扩大。
Admin 架构
下图就是新的 Admin 架构图。左上方是微前端,它蕴含前端外面各个业务线的微利用。微前端通过 HTTP 接口和 Admin 网关进行交互,Admin 网关把业务逻辑都剥离到下一层,而本身只负责公共组件、登录鉴权、协定代理和通用配置等通用需要,同时它会通过泛化调用来调用上游的业务服务。业务服务包含组织治理、云文档、视频会议和邮箱等微服务。右侧是 Gaia 管制面,包含一些管控性能,如接口生命周期治理、监控大盘、微利用治理、工单零碎等等。另外如果咱们有一些独立的自定义性能,会通过插件的形式集成。
Gaia 平台性能
Gaia 平台次要包含以下性能:
1. 业务线治理。业务线是实现以业务为维度进行接入 Admin 而提出的概念。通过业务线来聚合业务为维度的所有资源,相干资源包含微利用、菜单、接口、监控等。图中就是业务线治理的菜单页面。
2. 接口生命周期治理。包含接口创立、更新、编排、公布、上线、下线、删除等。同时保护接口 IDL 文件。
3. 微利用生命周期治理。包含微利用的申请、接入、微利用版本创立、公布、下线等。
4. 管制大盘。包含业务整体维度和单接口维度的 SLA 大盘,以及谬误告警治理。
5. 插件治理。包含默认插件和自定义插件的配置管理。
03 平台化实现
微前端技术架构
第三局部具体介绍飞书平台化实现,包含微前端技术架构、泛化调用实际和性能扩大。
下图是微前端的技术架构。这里波及到三个概念,第一个是基座,即指微前端入口模块,负责组装各个模块;第二个是微利用,指独立的业务模块;第三个是微利用市场,负责管理微利用的创立、治理、版本公布等。
通过微利用市场下发的配置进行微利用组合,将根底能力下放到各个业务方。例如,现有一个新的业务线须要接入,那么它须要开发本人的微利用,打包测试并公布到咱们的微利用市场,咱们的基座就会从微利用市场接管到这个微利用,最初进行公布之后,就能够从 Web 看到对应模块的页面。
泛化调用计划调研
如何通过泛化调用实现整体依赖的剥离?首先讲一下这个问题的背景,Admin 的前端和后端是通过 JSON 实现序列化传递的,如果把 Admin 变成一个平台化的网关,不再保护业务逻辑,只解决通用逻辑,泛化调用是咱们最好的抉择。因为通过泛化调用,Admin 的网关就不须要写各种业务代码,间接通过 RPC 接口就能够把前端传过来的 JSON 序列化数据、申请参数再传递到微服务,而后通过微服务的返回值把 JSON 序列化数据返回前端,跟前端进行交互。
咱们通过调研现有框架,如网关与微服务之间应用 gRPC、Thrift 等协定进行通信,都是通过代码生成实现的协定解析和协定传输,不能动静更新,都须要生成代码,再从新公布。而咱们外部旧的 Kite 框架(Thrift 协定)不反对泛化调用,而新框架 Kitex 是字节跳动外部的 Golang 微服务 RPC 框架,具备高性能、强可扩大的特点。
在咱们应用 Kitex 的泛化调用性能之前曾调研了一些泛化调用的计划,也基于 Kitex 实现了泛化调用的相似性能。然而咱们认为飞书外部实现泛化调用不如推动 Kitex 的研发人员,让他们把泛化调用变为一个通用的性能,这样不仅仅是咱们团队,公司外部其余团队以及 Kitex 开源后其余内部团队都能够应用这个性能。目前 Kitex 曾经反对基于 Thrift 协定的泛化调用。
非泛化调用
那么非泛化调用的实现形式和泛化调用的实现形式有什么不同呢?这张图就是非泛化调用的实现形式,无论 gRPC、Thrift 还是 Kitex 都是基于 IDL 生成协定代码,服务端和客户端都须要依赖 IDL 生成动态代码,接口的迭代意味着服务端和客户端都须要降级代码从新公布。在 Admin 场景下意味着其余业务方的业务迭代,须要咱们引入代码依赖并公布服务,这并不合乎咱们平台化的需要。
Kitex 泛化调用在 Kitex 泛化调用中,服务端 无需做任何革新 。客户端只有一份通用的协定解决代码,基于已有的 IDL 信息来动静生成协定字节流,IDL 信息能够动静更新,以保护最新的接口协议,无需生成代码。在 Admin 场景下,网关作为客户端,动静保护业务方接口的 IDL,通过泛化调用来实现 HTTP 接口到 RPC 接口的转换, 不再依赖业务服务客户端代码,实现了网关和业务在代码层面的解耦。
相干地址:https://github.com/cloudwego/…
HTTP 协议映射
Admin 网关是基于 Hertz 对外裸露 HTTP 协定的接口,Hertz 路由反对运行时新增,通过自定义 Middleware 和 HandlerFunc 能够实现接口运行时的增删改,这样能够实现解析批改后的 IDL 来进行接口调用。
这段代码就是初始化客户端的 Client,其实就是泛化调用的 Client,能够看到它会读业务方的 IDL,如果业务方的 IDL 有接口更新,咱们能够通过这个进行业务更新,动静实现接口的高低线。而后再结构 HTTP 类型的泛化调用 Client,每个业务方都会结构一个 Client 实例,比方有十几个业务线,就会生成十几个业务线微服务的实例。
泛化调用的路由其实是 HandlerFunc 的实现,通过这个形式能够动静注册路由,注册之后将 Hertz Request 转化成泛化调用 Request,再通过前一步生成的泛化调用 Client 实现泛化调用,最初失去 HTTPResponse,再将它写回 Hertz Response 中,这就是简略的泛化调用路由的实现。通过这个能够做很多业务拓展,比方错误码解决等等。
性能扩大接下来具体介绍一下性能扩大。性能扩大的第一类就是 Kitex 提供的自定义注解,Kitex 内置了 API 注解来实现路由解析、参数传递等性能。这外面有三个接口,第一个是 HTTPMapping,实现了参数传递、返回值等等自定义注解;第二个是 Route,实现了 Kitex 路由解析的性能;第三个是 ValueMapping,是指将参数进行映射,比方目前 JSON 不反对 Int64,但 Go 能够反对 Int64,在应用 JSON 序列化的时候就要把参数类型定义为 String,因而从 JSON 到 Go 有一个转换的过程,这就能够通过映射来实现。咱们通过自定义注解形式实现了框架未提供的性能,例如文件上传和下载、自定义参数注入、参数校验、自定义鉴权等。
性能扩大的第二类就是接口编排,曾经实现的单接口泛化调用,不能齐全满足咱们一些简单场景的应用需要,例如:简略组装两个接口的后果,比方同时调用接口 A 和 B,再将两个接口进行组装;接口有程序依赖,一个接口后果是其余接口的参数,比方先调用 A,A 的返回值作为参数去调用 B,再将 B 的返回值作为整体接口的返回值。Kitex 和 Hertz 还不能反对接口编排的性能,所以咱们通过自定义 DSL 引擎来对简略接口进行编排,以便实现一些简单场景的接口调用需要。
04 成绩展现
最初介绍一下飞书治理后盾平台化的演进成绩,次要有以下三点:
1. 业务迭代减速。Admin 不再关注其余业务线的需要,更加专一于本身的迭代需要。各个业务方公布齐全隔离,使得他们不再依赖 Admin,放慢了 Admin 整体的业务性能迭代速度。
2. 研发效率晋升。丰盛的前后端组件和简略的接入形式,业务方不须要再破费工夫相熟咱们的代码仓库,使得业务方接入更加便捷,研发效率大大晋升。
3. 工程质量进步。
* 其余团队不再向 Admin 仓库提交代码,仓库代码格调趋势对立;* 去除了大量的业务逻辑,聚焦网关通用逻辑,进步了单测覆盖率;* Bug 率显著降落,服务 SLA 显著晋升。
05 将来布局
咱们目前制订了一些将来的倒退布局,次要有以下四点:
- 凋谢更多的组件,让接入的业务方聚焦在业务逻辑自身,例如组织治理外面的选人组件,之前须要各个业务方本人外部实现,之后咱们会提供一套公共组件,业务方能够间接应用,包含音讯核心、工作治理、平安风控、短信邮件等;
- 欠缺服务治理和运维能力,包含灰度、降级、限流、精细化大盘等;
- 建设通用的动态页面托管解决方案,为开发者提供便捷、稳固、高扩展性的动态页面托管服务;
- 对接集成测试平台,闭环路由治理生命周期,保障接口稳定性和安全性。
我的项目地址
GitHub:https://github.com/cloudwego
官网:www.cloudwego.io