Kratos
简介
官方文档:简介 | Kratos (go-kratos.dev)
首先我们要知道Kratos 是一套轻量级 Go 微服务框架,这里附一个架构图:
项目准备
根据官方文档的要求,我们可以先开启GO111MODULE
go env -w GO111MODULE=on
然后我们需要下载以下工具:
-
make命令工具
-
用于在我们构建好
.proto
文件后,使用make api
指令就可以将 protobuf 文件中定义的服务和消息转换为 HTTP 接口,使得服务可以通过 HTTP/JSON 进行通信。 -
先下载Chocolatey
bashSet-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
然后通过Chocolatey下载make
bashchoco install make
下载完成后我们可以使用
bashmake --version
命令进行校验,如果返回为:
说明安装成功。
-
-
proto编译器
-
我们依旧使用Chocolatey来下载:
bashchoco install protoc
安装完成后,我们使用
bashprotoc --version
来进行校验,如果返回为某个具体版本号,如:
说明安装成功。
-
-
kratos CLI工具
-
为了能够执行与kratos框架相关的命令如:
bashkratos run
和
bashkratos new
等,我们就需要安装该命令行工具。
bashgo install github.com/go-kratos/kratos/cmd/kratos/v2@latest
同样,我们可以使用
kratos --version
来对是否成功安装进行校验。 -
项目构建
这里以文档本身中提供的 helloword 模板为例
我们依次执行如下命令:
bash
kratos new helloworld
& 使用gitee的
bash
kratos new helloworld -r https://gitee.com/go-kratos/kratos-layout.git
bash
cd helloworld
Go
go mod download
如果存在部分依赖报错,我们就可以使用 go mod tidy
重新生成go.sum
文件,以确保所有依赖项都已正确记录。
依赖注入
关于依赖注入部分,在Wire 依赖注入 | Kratos (go-kratos.dev)中有详细的解释
然后我们需要下载kratos依赖注入的包:
Go
go get github.com/google/wire/cmd/wire@latest
关于依赖注入我们不妨看一下helloword 下的 wire.go包,,其中存在如下代码:
Go
// wireApp init kratos application.
func wireApp(*conf.Server, *conf.Data, log.Logger) (*kratos.App, func(), error) {
panic(wire.Build(server.ProviderSet, data.ProviderSet, biz.ProviderSet, service.ProviderSet, newApp))
}
本质上就是将 internal 包下的server、data、biz、service 进行依赖注入,以达到显式初始化以及解耦的目的,每个模块只需要一个 ProviderSet 提供者集合,就可以在 wire 中进行依赖注入。
然后执行:
Go
go generate ./...
生成:
项目结构
我们主要需要进行代码填充和操作的就是api包,configs包和internal包。
-
在api包中,我们需要在 .proto 文件中定义一些CURD相关的api,如:
rpc CreateUser (CreateUserRequest) returns (CreateUserReply){ option(google.api.http) = { post: "/usr", body: "*", }; }
然后我们需要定义其请求和返回的一些具体参数:
message CreateUserRequest { string username = 1 [(validate.rules).string.min_len = 3, (validate.rules).string.max_len = 32]; string email = 2; string password = 3; } message CreateUserReply { bool success = 1; string message = 2; }
-
cmd包就是使用flag库实现的一个cmd工具,我们无需在此处进行代码的编写。
-
configs里面就是我们的yaml配置文件,由于我们需要使用的是postgresql,所以我们需要在yaml文件里面添加postgresql相关的driver和source,如下:
-
internal
-
biz(业务逻辑层)
封装核心业务逻辑和规则,实现业务流程的控制和决策。它不直接与数据库或外部服务通信,而是依赖于
data
层来获取和存储数据。作为业务逻辑的中心,biz
包调用data
层的接口来实现业务操作,并且可能被service
层调用。 -
data(数据访问层)
负责与底层数据存储(如数据库、缓存等)进行交互,实现数据的CRUD操作(创建、读取、更新、删除)。它实现了
biz
层定义的数据访问接口。server
包使用service
包中定义的业务逻辑来处理外部请求,并可能直接或间接地与biz
和data
包交互。 -
server(服务启动层)
定义和启动服务的入口点,包括HTTP服务器和gRPC服务器。它负责服务的生命周期管理,如启动和停止服务。
server
包使用service
包中定义的业务逻辑来处理外部请求,并可能直接或间接地与biz
和data
包交互。在实际操作中,我们需要将自己定义的service结构体指针添加到NewHTTPServer方法的参数中,并且在其中进行注册,如:v1.RegisterUserHTTPServer(srv, user)
gRPC同理。
-
service(应用服务层)
作为
api
包和biz
包之间的桥梁,处理来自外部的请求(如API调用),并将其转换为业务逻辑调用。它负责请求的预处理和后处理,以及错误处理。service
包调用biz
包中的业务逻辑,并可能直接与data
包交互,或者通过biz
包与data
包交互。同时,它响应server
包中的请求。
-
-
使用
Gogo install entgo.io/ent/cmd/ent@latest
进行安装
-
然后使用
ent new 'projectname'
进行Schema实体创建- 由于我们是在kratos的框架下进行的开发,所以ent包应该创建在data包下(即我们使用cd命令到data下再使用实体创建命令),如:
ent.
官方文档:Quick Introduction | ent (entgo.io)
Ent 是 Facebook 开源的一个简单易用的 Database 实体框架。
-
使用
bashgo install entgo.io/ent/cmd/ent@latest
进行安装
-
然后使用
bashent new 'projectname'
进行Schema实体创建
-
由于我们是在kratos的框架下进行的开发,所以ent包应该创建在data包下(即我们使用cd命令到data下再使用实体创建命令),如:
-
关于这个Schame,再一篇博客中对其有很好的形容,"一生二,二生三,三生万物" 而Schame就是这里的一,我们要在这里面定义数据库表的详细信息包括了:字段(Fields | ent (entgo.io)),关系(外键)(Edges | ent (entgo.io)),索引(Indexes | ent (entgo.io)),如:
需要注意的是,我们需要让字段信息与数据库表的字段严格的一一对应,不仅要字段名称一致,字段赋予的一些属性,如:非空、自增等,都必须保持一致。
-
-
然后我们在ent包下使用
go generate ./ent
命令生成与数据库进行交互的命令。 -
然后我们再来定义我们的数据库的客户端,在data包中,定义与数据库的连接
Go// Data . type Data struct { db *ent.Client } // NewData . func NewData(conf *conf.Data, logger log.Logger) (*Data, func(), error) { log := log.NewHelper(logger) drv, err := sql.Open( conf.Database.Driver, conf.Database.Source, ) if err != nil { log.Errorf("failed opening connection to postgresql: %v", err) return nil, nil, err } // 创建 ent.Client 并设置驱动 client := ent.NewClient(ent.Driver(drv)) // 初始化 Data 结构体 d := &Data{ db: client, } // 返回关闭函数,用于在程序结束时关闭数据库连接 cleanup := func() { log.Info("closing the data resources") if err := d.db.Close(); err != nil { log.Error(err) } } return d, cleanup, nil }
注意,我们需要先下载驱动
go get -u github.com/lib/pq
,然后在data.go中引入_ "github.com/lib/pq"
,然后将NewData放到我们的providerSet中: -
在data下新建一个user.go文件,在这里面我们就写与数据库进行直接交互的代码CRUD。
源码
基于Kratos+ent+postgresql的用户管理系统后端api: 微服务框架的用户管理系统的简单crud,仅用于学习。 (gitee.com)
examples/blog at main · go-kratos/examples (github.com)
部署
服务器拉取依赖
解决方案直接在Windows本地进行下载,然后通过Xftp传输到Linux服务器上:
-
首先配置临时的环境,因为Windows拉下来的都是.exe文件,而Linux需要的是二进制文件。
bash$env:GOOS = "linux" $env:GOARCH = "amd64"
-
然后执行下载命令:
Gogo install -v github.com/haya14busa/goplay/cmd/goplay@v1.0.0
-
下载完成后将其传输到Linux的
usr\local\bin
目录下,然后为其赋予执行权限bashsudo chmod +x /usr/local/bin/goplay
当我们设置了临时环境后,我们同样也可以在Windows环境下使用 go build
将项目打包为Linux可运行的二进制文件。