• 【从零单排Golang】第六话:基于wire的kratos示例项目


    《从零单排Golang》系列,又重新开张了。后续会不定期更新自己学习Golang的笔记跟心得。

    这次的话,就介绍一款名为奎爷kratos的微服务框架,以及讲述一下基础的使用机理。

    kratos是B站开源的微服务框架,不仅提供了grpchttp协议支持,而且有较为完善的层级架构、微服务中间件以及第三方组件的编写约定,可以说是非常方便上手跟扩展。

    要上手kratos,我们可以从两个地方入手:

    通过kratosquickstart文档,我们可以创建一个名为kratostest的项目。项目的目录结构遵循kratos-layout,具体如下:

    • api:接口定义,主要是proto文件
      • 需要生成go文件给到internal或者service模块做请求处理实现的编写
    • cmdmain.gowire.go
    • configs:配置yaml
    • internal
      • biz:业务逻辑
        • 若相较于controllerhandler,则类似于service的概念
        • service不是指kratosservice
      • conf:配置
      • data:数据访问
      • server:对外服务
      • service:类似于controllerhandler
    • third_party:第三方内容

    kratostest项目在启动之前,除了需要go-protobuf环境把proto文件编译成go文件之外,默认还需要通过wire模块自动初始化对象实例。wire是一种在golang里实现依赖注入的解决方案,可以参考以下文档,了解wire的作用:

    从使用角度上来说,实际上经过了如下的步骤:

    • 解析各个Provider接口出入参的实现
    • 根据不同Provider出入参的依赖关系,生成实际的初始化代码,填充入参,实现注入的效果

    http-server的基础greeter接口为例,存在着这样的调用层次:

    • NewHTTPServer:在internal/server/http.go,生成HTTPServer实例
      • 入参有conf.Server实例,是服务器启动的配置,可以通过internal/conf/conf.proto生成
        • configs/config.yaml实际配置这些内容
      • 入参*service.GreeterService,该实例需要实现GreeterHTTPServer的接口定义
      • GreeterHTTPServer的接口定义实际是由greeter.proto定义之后自动生成的
    • NewGreeterService:在internal/service/greeter.go,生成GreeterService实例
      • 在这里需要实现GreeterHTTPServer的接口定义
      • 需要定义biz层成员*biz.GreeterUsecase,在接口实现会调用这个成员方法执行实际业务
    • NewGreeterUsecase:在internal/biz/greeter.go,生成GreeterUsecase实例
      • 需要定义GreeterRepo类型成员,用来做数据的CRUD
    • NewGreeterRepo:在internal/data/greeter.go,生成GreeterRepo实例
      • 需要定义*Data类型成员,用来做实际对接数据库的访问操作
    • NewData:在internal/data/data.go,生成*Data实例
      • 入参有conf.Data实例,是数据库的配置,可以通过internal/conf/conf.proto生成
      • 这些方法可以打包成wireProviderSet,然后一并Build起来
    // cmd/kratostest/main.go
    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,
            ),
        )
    }
    
    // cmd/kratostest/wire.go
    func wireApp(*conf.Server, *conf.Data, log.Logger) (*kratos.App, func(), error) {
        panic(wire.Build(server.ProviderSet, data.ProviderSet, biz.ProviderSet, service.ProviderSet, newApp))
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    cmd/kratostest执行了wire之后,就会把这些依赖注入,代码重新组装起来,最后生成wire_gen.go文件。

    func wireApp(confServer *conf.Server, confData *conf.Data, logger log.Logger) (*kratos.App, func(), error) {
        dataData, cleanup, err := data.NewData(confData, logger)
        if err != nil {
            return nil, nil, err
        }
        greeterRepo := data.NewGreeterRepo(dataData, logger)
        greeterUsecase := biz.NewGreeterUsecase(greeterRepo, logger)
        greeterService := service.NewGreeterService(greeterUsecase)
        grpcServer := server.NewGRPCServer(confServer, greeterService, logger)
        httpServer := server.NewHTTPServer(confServer, greeterService, logger)
        app := newApp(logger, grpcServer, httpServer)
        return app, func() {
            cleanup()
        }, nil
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    wire_gen.gowireApp,最终会在main.go里实际执行,从而真正启动整个kratostest服务和各层的对象实例。

    func main() {
        // 忽略上面
        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)
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    这样,整个kratos服务的基础逻辑结构就顺起来了。

  • 相关阅读:
    小程序的入门
    RediSearch CentOS7编译安装
    如何远程操控桌面实现远程管理运维?
    元数据介绍
    基于JAVA双峰县在线房屋租售网站计算机毕业设计源码+数据库+lw文档+系统+部署
    C++ 资源、框架大全,推荐收藏 | 干货
    java计算机毕业设计食用菌菌棒溯源系统的开发与设计源程序+mysql+系统+lw文档+远程调试
    【虹科干货】设计微服务架构的原则
    LCR 052.递增顺序搜索树
    机器学习笔记之线性回归——从概率密度函数角度认识最小二乘法
  • 原文地址:https://blog.csdn.net/u013842501/article/details/128161738