[Go 微服务] Kratos 使用的简单总结

[Go 微服务] Kratos 使用的简单总结Kratos 使用的简单总结 kratos

大家好,欢迎来到IT知识分享网。

1.Kratos 简介

Kratos并不绑定于特定的基础设施,不限定于某种注册中心,或数据库ORM等,所以您可以十分轻松地将任意库集成进项目里,与Kratos共同运作。

在这里插入图片描述
API -> Service(wire) -> DB

  1. 可以看到kratos将整个服务大体分为了3层,API / Service / DB。
  2. 左侧标注了在 Service和DB层,使用依赖注入(DI)进行实现,工具名称为Wire。
  3. 可以看到Wire这个工具几乎贯穿Kratos架构始终,是一个大角色。

2.传输协议

支持http + grpc两种调用方式,通过编写proto文件来实现。

一般,http开放给外部调用,可以使用restful风格定义。grpc面向内部微服务之间进行调用。

在这里插入图片描述

​ 在项目中,会以这样的结构出现,并且可以对不同协议进来的请求进行处理,添加处理的中间件,如权限校验、熔断限流等等。

3.日志

在kratos中,可以自定义日志框架选型,设置日志格式和输出内容,然后将logger对象以依赖注入的方式,分配给server中的grpc server和http server,这样就可以实现每次收到请求后的日志打印。

将logger对象以依赖注入的方式,注入到业务层,就可以在业务层中统一使用logger进行输出。

4.错误处理

在grpc中,比较通用的一种错误处理方式就是直接通过 proto 预定义定义错误码,然后通过 proto-gen-go 生成帮助代码,直接返回 error。

{ 
    // 错误码,跟 http-status 一致,并且在 grpc 中可以转换成 grpc-status "code": 500, // 错误原因,定义为业务判定错误码 "reason": "USER_NOT_FOUND", // 错误信息,为用户可读的信息,可作为用户提示内容 "message": "invalid argument error", // 错误元信息,为错误添加附加可扩展信息 "metadata": { 
    "foo": "bar" } } 

这里可以发现,为了兼容grpc,在http的返回结果中,code也无法自定义,只能跟随httpcode。所以这里客户端或者第三方去处理错误时,需要判断reason字段。

5.配置管理

使用proto文件定义配置和生成struct,然后将yaml中的内容读取到对应struct 字段中进行使用。

在这里我们可以注意到,在kratos中,除了传输格式使用了proto进行定义之外,错误处理和配置管理,也使用了proto来进行。可以说,一切皆proto。

6.wire

Wire 是一个灵活的依赖注入工具(需要安装),通过自动生成代码的方式在编译期完成依赖注入。通过 Wire 进行初始化代码,可以很好地解决组件之间的耦合,以及提高代码维护性。

打开Kratos的示例项目,从main入口看,有一处调用了wireApp方法,这里就是一切的源头(万恶之源)。

这个方法调用的是main同目录的wire文件中的wireApp方法,同目录的wire_gen.go实现了此方法。

wire_gen中去实例化不同service和组建的对象,用于调用。关系图如下:

在这里插入图片描述

在这里插入图片描述

server -> service -> biz -> data

main.go -> wire.go(wire_gen.go)

在这里插入图片描述

wire.go 中有用到ProviderSet

package main import ( "kratos-demo03/internal/biz" "kratos-demo03/internal/conf" "kratos-demo03/internal/data" "kratos-demo03/internal/server" "kratos-demo03/internal/service" "github.com/go-kratos/kratos/v2" "github.com/go-kratos/kratos/v2/log" "github.com/google/wire" ) // 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)) } 

main.go 有用到App和Config

package main import ( "flag" "os" "kratos-demo03/internal/conf" "github.com/go-kratos/kratos/v2" "github.com/go-kratos/kratos/v2/config" "github.com/go-kratos/kratos/v2/config/file" "github.com/go-kratos/kratos/v2/log" "github.com/go-kratos/kratos/v2/middleware/tracing" "github.com/go-kratos/kratos/v2/transport/grpc" "github.com/go-kratos/kratos/v2/transport/http" _ "go.uber.org/automaxprocs" ) // go build -ldflags "-X main.Version=x.y.z" var ( // Name is the name of the compiled software. Name string // Version is the version of the compiled software. Version string // flagconf is the config flag. flagconf string id, _ = os.Hostname() ) func init() { 
    flag.StringVar(&flagconf, "conf", "../../configs", "config path, eg: -conf config.yaml") } func newApp(logger log.Logger, gs *grpc.Server, hs *http.Server) *kratos.App { 
    return kratos.New( kratos.ID(id), kratos.Name(Name), kratos.Version(Version), kratos.Metadata(map[string]string{ 
   }), kratos.Logger(logger), kratos.Server( gs, hs, ), ) } func main() { 
    flag.Parse() logger := log.With(log.NewStdLogger(os.Stdout), "ts", log.DefaultTimestamp, "caller", log.DefaultCaller, "service.id", id, "service.name", Name, "service.version", Version, "trace.id", tracing.TraceID(), "span.id", tracing.SpanID(), ) c := config.New( config.WithSource( file.NewSource(flagconf), ), ) defer c.Close() if err := c.Load(); err != nil { 
    panic(err) } var bc conf.Bootstrap if err := c.Scan(&bc); err != nil { 
    panic(err) } app, cleanup, err := wireApp(bc.Server, bc.Data, logger) if err != nil { 
    panic(err) } defer cleanup() // start and wait for stop signal if err := app.Run(); err != nil { 
    panic(err) } } 

在每个模块中,只需要一个 ProviderSet 提供者集合,就可以在 wire 中进行依赖注入。

有一个数据库连接对象,service需要操作数据库,依赖数据库连接对象。这时候我们可以声明数据库连接对象在ProviderSet集合,然后在service对象处声明,我需要一个数据库连接对象。 然后我们使用wire工具,就可以自动帮我们生成依赖注入的代码。

这里的依赖注入让代码间的依赖关系一目了然。只需要查看wire_gen.go代码就可以了解依赖关系。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/135476.html

(0)
上一篇 2025-07-04 16:33
下一篇 2025-07-04 17:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信