Kratos 一套轻量级 Go 微服务框架,包含大量微服务相关框架及工具。
由bilibili开源出来,在bilibili站大量使用。
准备
安装依赖
首先,您需要安装好对应的依赖环境,以及工具:
- go
- protoc
➜ protoc --version
libprotoc 3.21.7
- 安装protobuf的go扩展工具 protoc-gen-go
go install google.golang.org/protobuf/cmd/protoc-gen-go
- 建议开启GO111MODULE
go env -w GO111MODULE=on
- 安装kratos脚手架
GOPROXY=https://goproxy.io,direct go install github.com/go-kratos/kratos/cmd/kratos/v2@latest && kratos upgrade
创建项目
通过 kratos 命令创建项目模板:
$ kratos new helloworld -r https://gitee.com/go-kratos/kratos-layout.git
项目目录如下:
.
├── Dockerfile
├── LICENSE
├── Makefile
├── README.md
├── api // 下面维护了微服务使用的proto文件以及根据它们所生成的go文件
│ └── helloworld
│ └── v1
│ ├── error_reason.pb.go
│ ├── error_reason.proto
│ ├── error_reason.swagger.json
│ ├── greeter.pb.go
│ ├── greeter.proto
│ ├── greeter.swagger.json
│ ├── greeter_grpc.pb.go
│ └── greeter_http.pb.go
├── cmd // 整个项目启动的入口文件
│ └── server
│ ├── main.go
│ ├── wire.go // 我们使用wire来维护依赖注入
│ └── wire_gen.go
├── configs // 这里通常维护一些本地调试用的样例配置文件
│ └── config.yaml
├── generate.go
├── go.mod
├── go.sum
├── internal // 该服务所有不对外暴露的代码,通常的业务逻辑都在这下面,使用internal避免错误引用
│ ├── biz // 业务逻辑的组装层,类似 DDD 的 domain 层,data 类似 DDD 的 repo,而 repo 接口在这里定义,使用依赖倒置的原则。
│ │ ├── README.md
│ │ ├── biz.go
│ │ └── greeter.go
│ ├── conf // 内部使用的config的结构定义,使用proto格式生成
│ │ ├── conf.pb.go
│ │ └── conf.proto
│ ├── data // 业务数据访问,包含 cache、db 等封装,实现了 biz 的 repo 接口。我们可能会把 data 与 dao 混淆在一起,data 偏重业务的含义,它所要做的是将领域对象重新拿出来,我们去掉了 DDD 的 infra层。
│ │ ├── README.md
│ │ ├── data.go
│ │ └── greeter.go
│ ├── server // http和grpc实例的创建和配置
│ │ ├── grpc.go
│ │ ├── http.go
│ │ └── server.go
│ └── service // 实现了 api 定义的服务层,类似 DDD 的 application 层,处理 DTO 到 biz 领域实体的转换(DTO -> DO),同时协同各类 biz 交互,但是不应处理复杂逻辑
│ ├── README.md
│ ├── greeter.go
│ └── service.go
└── third_party // api 依赖的第三方proto
├── README.md
├── google
│ └── api
│ ├── annotations.proto
│ ├── http.proto
│ └── httpbody.proto
└── validate
├── README.md
└── validate.proto
使用 go generate 命令生成相应代码
生成 proto 源码、wire 等等
$ go generate ./...
go: downloading github.com/go-kratos/kratos/v2 v2.2.1
go: downloading google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf
go: downloading github.com/go-logr/logr v1.2.1
go: downloading github.com/go-logr/stdr v1.2.0
... ...
测试接口
运行项目
$ kratos run
INFO msg=config loaded: config.yaml format: yaml
INFO msg=[gRPC] server listening on: [::]:9000
INFO msg=[HTTP] server listening on: [::]:8000
Kratos项目结构介绍
Makefile 文件为make命令的一个文件,我们打开有如下命令
make init
init:
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
go install github.com/go-kratos/kratos/cmd/kratos/v2@latest
go install github.com/go-kratos/kratos/cmd/protoc-gen-go-http/v2@latest
go install github.com/google/gnostic/cmd/protoc-gen-openapi@latest
go install github.com/google/wire/cmd/wire@latest
会初始化安装这个框架的一个依赖。
如果之后自己还有一些工具之类的需要安装,可以放到这里。
make config
onfig:
protoc --proto_path=./internal \
--proto_path=./third_party \
--go_out=paths=source_relative:./internal \
$(INTERNAL_PROTO_FILES)
会生成 internal/conf/conf.pb.go 文件,提供对 internal/conf/conf.proto文件的调用方法。
internal/conf/conf.proto 文件对应的配置文件为 configs/config.yaml文件。
make api
api:
protoc --proto_path=./api \
--proto_path=./third_party \
--go_out=paths=source_relative:./api \
--go-http_out=paths=source_relative:./api \
--go-grpc_out=paths=source_relative:./api \
--openapi_out=fq_schema_naming=true,default_response=false:. \
$(API_PROTO_FILES)
主要用来把 api目录里的定义的proto文件生成对应的go文件。
比如示例的api/helloworld/v1/greeter.proto文件生成 greeter.pb.go文件。
make generate
生成wire依赖注入文件
generate:
go mod tidy
go get github.com/google/wire/cmd/wire@latest
go generate ./...
make build
build:
mkdir -p bin/ && go build -ldflags "-X main.Version=$(VERSION)" -o ./bin/ ./...
生成可执行编译文件
我们执行一下,会在 bin目录下生成一个 helloworld可执行文件。
执行:
./bin/helloworld -conf ./configs/config.yaml
其他
上面虽然对代码结构做了文字说明,但是在 internal 里,有 DDD 这个概念,相信很多人看了后,不是很明白。
先来看看 DDD 的分层架构,架构图如下
再来对比看看 internal 目录里的 biz、data、service、server、conf 这 5 个目录。
- biz:文档里说了类似 DDD 的 domain 层,也就是 DDD 架构中的领域层。这里还定义了对业务操作的接口。业务逻辑组装。
- data:对数据库 db,缓存 cache 的封装,并且实现 biz 中定义的接口。它将领域对象重新拿出来,这里去掉了 DDD 的基础层。
- service:实现 api 定义的服务层,类似 DDD 的应用层。处理数据传输对象到 biz(领域实体)的转换。同时协同各类 biz 交互,不应处理复杂逻辑。
- server:http 和 grpc 实例的创建和配置,以及注册对应的 service。
service -> biz -> data