知道网站是wp程序做的如何仿站,网站建设平台怎么样,各大电商平台对比,上传wordpress到文章目录 1.Kratos 简介2.传输协议3.日志4.错误处理5.配置管理6.wire 1.Kratos 简介
Kratos并不绑定于特定的基础设施#xff0c;不限定于某种注册中心#xff0c;或数据库ORM等#xff0c;所以您可以十分轻松地将任意库集成进项目里#xff0c;与Kratos共同运作。 API -不限定于某种注册中心或数据库ORM等所以您可以十分轻松地将任意库集成进项目里与Kratos共同运作。 API - Service(wire) - DB
可以看到kratos将整个服务大体分为了3层API / Service / DB。左侧标注了在 Service和DB层使用依赖注入DI进行实现工具名称为Wire。可以看到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-statuscode: 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 mainimport (kratos-demo03/internal/bizkratos-demo03/internal/confkratos-demo03/internal/datakratos-demo03/internal/serverkratos-demo03/internal/servicegithub.com/go-kratos/kratos/v2github.com/go-kratos/kratos/v2/loggithub.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 mainimport (flagoskratos-demo03/internal/confgithub.com/go-kratos/kratos/v2github.com/go-kratos/kratos/v2/configgithub.com/go-kratos/kratos/v2/config/filegithub.com/go-kratos/kratos/v2/loggithub.com/go-kratos/kratos/v2/middleware/tracinggithub.com/go-kratos/kratos/v2/transport/grpcgithub.com/go-kratos/kratos/v2/transport/http_ go.uber.org/automaxprocs
)// go build -ldflags -X main.Versionx.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 stringid, _ 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.Bootstrapif 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 signalif err : app.Run(); err ! nil {panic(err)}
}在每个模块中只需要一个 ProviderSet 提供者集合就可以在 wire 中进行依赖注入。
有一个数据库连接对象service需要操作数据库依赖数据库连接对象。这时候我们可以声明数据库连接对象在ProviderSet集合然后在service对象处声明我需要一个数据库连接对象。 然后我们使用wire工具就可以自动帮我们生成依赖注入的代码。
这里的依赖注入让代码间的依赖关系一目了然。只需要查看wire_gen.go代码就可以了解依赖关系。