sponge的发展阶段
sponge的发展主要经过下面几个阶段:
🔸第一阶段,把配置文件yaml转换为go代码,把mysql表转换为gorm代码,生成简单的gorm CRUD代码,现阶段作为开发辅助写代码工具用。
🔸第二阶段,支持生成dao CRUD代码、handler CRUD代码、web服务代码,现阶段支持生成标准化CRUD api的web服务代码,但不支持生成自定义api代码,有一定的局限性。
🔸第三阶段,支持使用protobuf协议来生成自定义api,增加了生成通用的web服务代码,现阶段支持
sql web开发
和protobuf web开发
两种方式。🔸第四阶段,支持
基于sql生成grpc服务代码
、基于protobuf生成通用的grpc服务代码
、基于protobuf生成grpc网关服务代码
,现阶段微服务框架已经成型。🔸第五阶段,支持生成代码命令UI界面化、支持丰富的开箱即用的组件、支持生成多种代码仓库类型(multi-repo,mono-repo)、支持多种主流数据库类型、支持构建部署自动化等,已经具备作为基础开发框架。
经过多个阶段的发展,sponge已经变成了一个集成自动生成代码
、Gin和GRPC
的基础开发框架。
代码仓库类型
sponge生成的服务代码支持两种类型代码仓库,如下图所示:
单体应用单体仓库(monolith) 或 微服务多仓库(multi-repo) : 每个服务代码都有自己的git仓库,即使把所有服务放在同一个git仓库下,服务之间代码不可以复用,默认是生成这种类型。
微服务单体仓库(mono-repo) : 所有服务都在同一个git仓库下,不同服务之间的代码可以复用,这种类型代码仓库也叫大仓库类型。
生成代码框架
生成代码主要基于sql和protobuf两种方式,每种方式拥有生成不同功能代码,其中sql支持常用的数据库mysql、mongodb、postgresql、tidb、sqlite,生成代码的框架图如下所示:
sponge生成代码框架图
从图中可以看出,基于sql创建项目有2种方式:
⓵基于sql创建web服务
⓶基于sql创建grpc服务
基于protobuf创建的项目有4种方式:
⓷基于protobuf创建web服务
⓸基于protobuf创建grpc服务
⓹基于protobuf创建grpc网关服务
⓺基于protobuf创建grpc+http服务
也就是说sponge一共支持6种创建项目方式,这6种创建项目方式适用于不同的项目场景:
⓵基于sql创建web服务
⓵基于sql创建web服务
是包括数据存储的完整web后端服务,包括了从开发到部署的完整功能、标准化的CRUD api。
适用场景: 绝大多数是标准化CRUD api的web项目,例如后台管理项目。
特点:
- 支持数据库mysql、mongodb、postgresql、tidb、sqlite。
- 不需要编写任何一行go代码就可以运行使用,只需连接数据库,一键生成包含标准化CRUD api的完整项目工程代码,开箱即用。
- 支持批量添加标准化CRUD api,生成的标准化CRUD api代码无缝嵌入项目代码中。
- 支持自定义api,但需要像web开发那样人工去编写完整的api代码。
如上图所示,生成的web服务代码包括 handler
、 dao
、model
三个子模块代码,向内包含,web服务代码支持无缝嵌入生成的handler CRUD代码。
⓶基于sql创建grpc服务
⓶基于sql创建grpc服务
是包括数据存储的完整grpc服务,包括了从开发到部署的完整功能、标准化的CRUD api、grpc客户端测试代码。
适用场景: 使用指定数据库存储的通用微服务项目。
特点:
- 支持数据库mysql、mongodb、postgresql、tidb、sqlite。
- 不需要编写任何一行go代码就可以运行使用,只需连接mysql数据库,一键生成包括标准化CRUD api的完整项目工程代码,开箱即用。
- 通过解析sql来生成proto文件里的标准化CRUD api描述信息,不需要人工定义。
- 支持批量添加标准化CRUD api。
- 支持自定义api,只需在proto文件填写自定义api描述信息,然后在api模板中填写业务逻辑代码。
- 支持单独生成dao CRUD代码无缝嵌入到grpc服务项目代码中,然后在
service
调用dao
接口。 - 自动生成grpc客户端测试和压测代码,不需要借助第三方grpc客户端工具测试grpc服务,直接在
Goland
或Visual Studio Code
上测试api。
如上图所示,生成的grpc服务代码包括了 service
、dao
、model
、protobuf
四个子模块,向内包含,grpc服务代码支持无缝嵌入生成的service CRUD代码。
⓷基于protobuf创建web服务
⓷基于protobuf创建web服务
是不包括数据库存储的通用web服务,包括了从开发到部署所需功能、api模板代码,支持自选的数据库类型和ORM。
适用场景: 通用的web服务项目。
特点:
- 支持批量生成自定义api模板代码。
- 新增api时,会自动合并新增的api代码到模板代码,简化了web服务的api开发,在proto文件编写自定义api描述信息,在生成api模板代码填写业务逻辑代码。
- 如果选用了mysql作为数据存储,其实就是
⓵基于sql创建web服务
的增强版,不仅支持批量添加标准化的CRUD api,自定api代码(除了业务逻辑代码)也是自动生成的,添加一个完整的自定义api时,不需要像传统开发api那样人工编写接口全部代码。 - 如果选用非mysql类型数据时,必须人工编写连接数据代码、dao代码,在handler调用dao接口。
- 需要了解使用protobuf。
如上图所示,生成的web服务代码包括了 handler template
,支持无缝嵌入生成的handler CRUD代码。
⓸基于protobuf创建grpc服务
⓸基于protobuf创建grpc服务
是不包括数据库存储的通用grpc服务,包括了从开发到部署所需功能、api模板代码,支持自选数据库类型作为数据存储。
适用场景: 通用的微服务项目。
特点:
- 支持批量生成自定义api模板代码。
- 新增api时,会自动合并新增的api代码到模板代码。
- 如果选用了mysql作为数据存储,则与
⓶基于sql创建grpc服务
是完全一样,支持批量添加标准化的CRUD api,也支持单独生成dao CRUD代码无缝嵌入到grpc服务项目代码中,然后在service
调用dao
接口。 - 如果选用非mysql类型数据时,必须人工编写连接数据代码、dao代码,在service调用dao接口。
- 自动生成grpc客户端测试和压测代码,不需要借助第三方grpc客户端工具测试grpc服务,直接在
Goland
或Visual Studio Code
上测试api。 - 需要了解使用protobuf。
如上图所示,生成的grpc服务代码包括了service template
,支持无缝嵌入生成的service CRUD代码。
⓹基于protobuf创建grpc网关服务
⓹基于protobuf创建grpc网关服务
是grpc服务的统一入口的web服务,包括了从开发到部署所需功能、api模板代码。
适用场景: 微服务架构、分布式系统、跨平台系统。
特点:
- 支持批量生成自定义api模板代码,只需在protobuf定义api描述信息,在生成的模板文件编写业务逻辑代码。
- 新增api时,会自动合并新增的api代码到模板代码。
- 支持无缝嵌入生成的连接grpc服务代码。
- 支持负载均衡、路由、鉴权、监控功能。
- 需要了解使用protobuf。
如上图所示,生成的grpc网关服务代码包括 router
和 service template
两个子模块,这里的service
模板代码主要是调用grpc服务api。
⓺基于protobuf创建grpc+http服务
⓺基于protobuf创建grpc+http服务
是不包括数据库存储的通用的grpc+http服务,包括了从开发到部署所需功能、api模板代码,支持自选数据库类型作为数据存储。
适用场景: 微服务架构、分布式系统、跨平台系统。
特点:
- api同时支持grpc和http两种协议
- 根据protobuf批量生成api的service(grpc)和handler(http)模板代码,只需在生成的service和handler模板代码文件编写业务逻辑代码。
- 新增api时,会自动合并新增的api代码到模板代码。
- 支持无缝嵌入生成的连接grpc服务代码。
- 支持负载均衡、路由、鉴权、监控等功能。
- 需要了解使用protobuf。
如上图所示,生成的grpc+http服务代码包括 service template
、router 和 handler template
两个子模块,支持无缝嵌入生成的service+handler CRUD代码。
微服务框架
sponge也是一个的微服务框架,框架图如下图所示,这是典型的微服务分层结构,具有高性能,高扩展性,包含常用的服务治理功能,可以很方便替换或添加自己的服务治理功能。
微服务框架图
微服务主要功能:
- Web 框架 gin
- RPC 框架 grpc
- 配置解析 viper
- 配置中心 nacos
- 日志组件 zap
- 数据库orm组件 gorm, mongo-go-driver
- 缓存组件 go-redis, ristretto
- 自动化api文档 swagger, protoc-gen-openapiv2
- 鉴权 jwt
- 参数校验 validator
- 消息组件 rabbitmq
- 分布式事务管理器 dtm
- 自适应限流 ratelimit
- 自适应熔断 circuitbreaker
- 链路跟踪 opentelemetry
- 指标监控 prometheus, grafana
- 服务注册与发现 etcd, consul, nacos
- 自适应采集 profile
- 资源统计 gopsutil
- 代码规范检查 golangci-lint
- 持续集成部署 jenkins, docker, kubernetes
项目代码目录结构
sponge创建的项目代码目录结构遵循 project-layout,如下所示:
.
├── api # proto文件和生成的*pb.go目录
├── assets # 其他与资源库一起使用的资产(图片、logo等)目录
├── cmd # 程序入口目录
│ └── serviceName
│ ├── initial # 程序初始化,有三个文件,initApp是初始化配置,registerServers是注册服务(http或grpc),registerClose是注册释放资源
│ └── main.go # 程序入口文件
├── configs # 配置文件的目录
├── deployments # IaaS、PaaS、系统和容器协调部署的配置和模板目录
├── docs # 设计文档和界面文档目录
├── i(I)nternal # 业务逻辑代码目录,如果首字母是小写(internal),表示私有代码,如果首字母大写(Internal)表示可以被其他代码复用。
│ ├── cache # 基于业务包装的缓存目录
│ ├── config # Go结构的配置文件目录
│ ├── dao # 数据访问目录
│ ├── ecode # 自定义业务错误代码目录
│ ├── handler # http的业务功能实现目录
│ ├── model # 数据库模型目录
│ ├── routers # http路由目录
│ ├── rpcclient # 连接grpc服务的客户端目录
│ ├── server # 服务入口,包括http、grpc等
│ ├── service # grpc的业务功能实现目录
│ └── types # http的请求和响应类型目录
├── pkg # 外部应用程序可以使用的库目录
├── scripts # 用于执行各种构建、安装、分析等操作的脚本目录
├── test # 额外的外部测试程序和测试数据
└── third_party # 外部帮助程序、分叉代码和其他第三方工具
Tip
web服务和grpc服务目录结构基本一致,其中有一些是web服务独有的目录(internal目录下的routers、handler、types),有一些是grpc服务独有的目录(internal目录下的service)。
sponge核心功能
模板代码
sponge源码包括了生成代码工具
、web和微服务代码
和基础开发框架脚本
三大部分,其中web和微服务代码
和基础开发框架脚本
统称为模板代码
,6种方式创建的服务代码目录都是类似的,共用一套sponge源码中的模板代码。
如果看懂了sponge创建的项目代码,也就看懂了sponge源码(开发过项目都比较容易看懂),主要了解项目代码中api和internal两个目录下的代码,应该对这两个目录不陌生,api目录主要是定义api描述信息的,internal目录主要是存放业务逻辑代码的,使用sponge开发项目主要流程是在proto文件定义api
—> 在生成的模板代码中编写业务逻辑代码
,web和grpc服务开发都是一样的套路。
Tip
如果项目一开使用单体web服务(⓷基于protobuf创建web服务
),随着业务功能的增加,越来越复杂,如果想要把业务复杂的单体web服务拆分为grpc服务非常方便,基本不需要重写代码,只需简单的移植业务逻辑代码到grpc服务中即可,原因是web和grpc服务共用一套模板代码。
Tip
sponge的生成代码命令和模板代码是同步更新的,执行命令sponge upgrade
会更新到最新版本,不会出现生成代码命令和模板代码不一致情况。
生成代码
生成代码
是sponge项目的三大核心功能之一,自动把生成的代码与模板代码有规则的组织起来,构建成一个完整的项目代码。模板代码就像一个固定结构的楼房,生成代码
是给楼房添砖加瓦和装修。
sponge支持丰富的生成代码功能,使用sponge在开发项目过程中主要有两个地方可以生成代码,一是在UI界面,二是在创建的项目代码下的Makefile文件。
在sponge UI界面上支持6种方式创建项目, 分别是:
⓵基于sql创建web服务
⓶基于sql创建grpc服务
⓷基于protobuf创建web服务
⓸基于protobuf创建grpc服务
⓹基于protobuf创建grpc网关服务
⓺基于protobuf创建grpc+http服务
在sponge UI界面还支持生成多种公共代码,这些公共代码都可以无缝嵌入到项目代码中,分别是:
- 生成handler CRUD代码
- 生成service CRUD代码
- 生成service+handler CRUD代码
- 生成dao CRUD代码
- 生成protobuf CRUD代码
- 生成的model代码
- 生成config代码
- 生成grpc服务连接代码
- 生成cache代码
其实在UI界面的后台执行是sponge生成代码的命令行,在sponge web
和sponge micro
命令中可以找到一一对应的生成代码子命令。UI界面有记忆功能、有参数详细的说明、有生成代码后的使用步骤说明,因此使用UI界面比sponge命令行更加简单易用。
除了在UI界面的生成代码,更多生成代码命令集成在服务代码目录下的Makefile文件中,包括:
- 生成api模板代码
- grpc客户端测试代码
- 注册路由代码
- api错误码
- 自动合并模板代码
- protoc插件生成的*pb.go代码
通过Makefile生成的代码都是无缝嵌入到项目代码中的,不需要人工调整来适配项目代码。
sponge包括这么多种生成代码命令都是为了在开发项目过程中尽可能少写代码或者不写代码,让使用go也可以”低代码开发”。
生成服务代码的鸡蛋模型
sponge生成代码过程中剥离了业务逻辑与非业务逻辑两大部分代码,把sponge的生成代码功能看作是一个母鸡,sponge生成的服务代码看作是鸡蛋,以生成的一个web服务后端代码为例:
蛋壳
是web服务框架代码(自动生成,不需要人工编写)。蛋黄
是业务逻辑的核心,例如定义mysql表、在proto定义api、编写具体逻辑代码都属于蛋黄部分(需要人工编写的代码)。蛋白
是业务逻辑核心代码与web框架代码连接的桥梁,例如根据proto文件生成的注册路由代码、handler代码、dao代码、参数校验代码、错误码、swagger文档等都属于蛋白部分(自动生成,不需要人工编写)。
⓷基于protobuf创建web服务
代码的鸡蛋模型剖析图如下图所示:
⓶基于sql创建grpc服务
和 ⓸基于protobuf创建grpc服务
代码的鸡蛋模型剖析图如下图所示:
⓹基于protobuf创建grpc网关服务
代码的鸡蛋模型剖析图如下图所示:
⓺基于protobuf创建grpc+http服务
代码的鸡蛋模型剖析图如下图所示:
性能测试
sponge创建的http+grpc服务代码(⓺基于protobuf创建grpc+http服务
)的性能测试: 50个并发,总共100万个请求。
点击查看测试代码。