Kitex源码阅读——脚手架代码是如何通过命令行生成的(二)
前言
Kitex是字节跳动内部的Golang微服务RPC框架,先已开源。
Kitex文档:https://www.cloudwego.io/zh/docs/kitex/getting-started/
Kitex体验:https://juejin.cn/post/7098966260502921230
Kitex源码阅读—脚手架代码的生成(一):https://juejin.cn/post/7100867939829563422
在Kitex体验的文章中,我们使用Kitex从零构建了自己的服务,只要定义好
IDL(接口描述语言),按照Kitex提供的命令行规则,就可以生成支持
Thrift、
Protobuf的客户端和服务端相关的脚手架代码,使得我们可以直接着手编写服务端的响应实现和客户端的请求发起逻辑。
这篇文章我们继续探究Kitex究竟是怎么生成脚手架代码的,通过上篇文章的分析,已经明白
main.go文件中,
init()函数的作用是注册命令解析参数
flag,提供给后续使用Go原生命令行解析库
flag做解析。接下来我们继续分析
main.go文件中剩余的部分,探究如何在解析得到命令行输入参数之后,根据参数内容完成脚手架代码的自动生成。
提醒:Kitex源码阅读系列的文章连贯性很大,建议按顺序阅读。并且随着源码的阅读,我会从零开始,不断扩展我们自己基于Kitex编写的kitexx框架的功能(目前kitexx已经拥有了解析命令行参数的功能) 。
源码分析
分析main.go的main()函数
通过观察注释,main函数分为两个部分,下面分析。
以插件模式运行
这一部分是一个
switch结构,获取命令行的第一个参数值,如果满足则case条件则会调用给定的
Run()方法,完成初始化,并且执行完成后退出程序。虽然我们还没继续深入,但是可以猜测,这里kitex集成了
protoc和
thriftgo创建客户端服务端脚手架的功能,这里根据命令行需求去调用对应代码生成逻辑。
只有在不满足这两个case的情况下,main函数继续执行,运行kitex自己的脚手架代码生成逻辑。这里我们先着重于分析kitex自己逻辑,越过这个部分。
以kitex模式运行
分析args.parseArgs()函数
- 用于解析命令行参数,并且对属于的命令行参数进行有效性检查,可以说整个args.parseArgs()都在完成各种检查。
关于
a.buildFlags()方法这里再说明一下,所有能在命令行输入的flag参数都是事先注册在
FlagSet中的,并且赋予默认值,随之使用
flag库解析命令行输入的
flag和紧跟着的
value之后,将会用输入
value替换注册的
flag的默认值,完成解析后,这些
flag的
value已经保存了你需要创建的服务的各种信息,只要提供给脚手架生成部分的代码使用即可。
- 这里着重分析一下
args.parseArgs()
内最后路径检查方法a.checkPath
的源码,因为其包含的内容较多。
通过分析
checkPath()函数,可以找到
Kitex文档中对应的下方
-module参数需要择情况添加的原因,针对两种模式管理的go项目
(go path / go mod),
kitex工具采用不同的路径管理逻辑(因为最终要确定脚手架代码生成的位置)。
分析buildCmd()函数
cmd := buildCmd(&args, out)是main函数体完成参数初始化和检查后的核心部分,下面将具体分析:
由于
buildCmd()函数中
lookupTool()函数比较重要,这里先深入分析:
再来看
buildCmd()函数:
关于thriftgo
:因为字节内部使用RPC的IDL为thrift
格式,因此用Go语言实现了自己的thrift编译器thriftgo
,它有着与apache/thrift
编译工具相似的命令行接口,并且通过插件机制对其进行了增强。
thriftgo地址:https://github.com/cloudwego/thriftgo
而
protoc则是对应于
protobuf格式IDL的编译器,这样是使用Google原生的没有对其增强。
最后再调用
cmd.Run()方法,则将执行这个定义好的外部命令。(要确保thriftgo编译工具已经安装)
小结
这里整体梳理一下通过命令行生成IDL定制的脚手架的过程:
- 向
FlagSet
注册会有哪些命令行参数会被输入(flag
键值对) - 解析输入的
flag
键值对并且保存,并且对其进行语法检查 - 从
FlagSet
中获取输入的参数,封装成外部命令Cmd
,用于调用thriftgo
或者protoc
的命令 cmd.Run()
在指定的文件路径中生成客户端和服务端脚手架代码kitex_gen
当然在我们分析main函数源码的时候,没有分析kitex命令行工具作为插件的工作流程,这里希望你触类旁通,尝试自己去分析一下。
为kitexx增加脚手架代码生成功能
编写kitexx框架
首先要确保你已经安装了
thriftgo编译工具,然后编写
kitexx工具的主函数,它的作用就是先通过
kitexx命令行获取到
g参数,指定
thriftgo将要编译IDL的生成语言为
go,然后就是将这些参数构建一个外部命令去调用
thriftgo编译工具,在指定的文件夹构建脚手架代码。
这里为什么我知道驱动
thriftgo编译工具最少只需要
-g参数呢?因为
thriftgo的代码仓库给出了最简单的使用方式:
编写IDL
然后使用
go build -o ~/go/bin/kitexx命令将其编译成一个可执行文件到
$GOPATH/bin目录下,接着编写IDL文件
echo.thrift,这里我使用
thrift格式
测试kitexx功能
然后在命令行输入命令:
kitexx -g go,就会在控制台显示:
并且在当前目录下生成了
gen-go文件,其中包含了生成的脚手架代码,当然由于
kitexx功能过于简单,我们输入的参数也仅仅只有一个
-g,难免生成的脚手架十分单薄,但我们的目的已经达到了。
总结
通过第二篇文章的讲解,已经很清晰的介绍了
kitex工具是如何通过命令行,生成go语言RPC服务的脚手架代码的(小结部分我已经有所概括),并且我们也自研了拥有脚手架生成功能的
kitexx微框架,通过实践印证了我们对源码的理解。
\
- 如何通过Git命令行把代码提交到github上
- 使用IDEA springboot 如何通过mybatis-generator自动生成代码
- 如何通过命令行或者使用代码打开一个apk文件
- 收了100元辛苦费,写了一个最简单的C#ASP.NET的3层架构例子代码,源码是通过代码生成器生成的【写程序的效率神奇的高】
- 一起谈.NET技术,创建代码生成器可以很简单:如何通过T4模板生成代码?[上篇]
- 一起谈.NET技术,创建代码生成器可以很简单:如何通过T4模板生成代码?[下篇]
- myEclipse注册码如何通过代码生成
- OGRE学习之路02:手把手教你如何通过Doxygen从源码生成OGRE 1.10.11 的离线API文档
- (2)通过脚手架自动生成controller和view ----代码先行/数据库先行
- 如何通过hg(水银)代码管理系统搭建完整的ecos源码平台
- 如何通过阅读别人的代码提高自己的编程能力
- Xcode中如何通过代码运行命令行工具
- 【译】MVC3 20个秘方-(2)通过脚手架自动生成controller和view ----代码先行/数据库先行
- 【转】如何通过T4模板生成代码?
- 如何通过命令行或者使用代码打开一个apk文件
- KEIL生成的bin文件如何通过代码有效性检测?
- Java如何搭建脚手架(自动生成通用代码),创建自定义的archetype(项目模板)
- C#如何通过T4自动生成代码详解
- 如何在Linux系统通过命令行生成随机文件
- 光脚丫学LINQ(024):如何通过修改DBML文件生成自定义代码