初识go-kratos

article/2025/10/5 14:17:28

推荐看一下 Kratos 官方文档 更加流畅观看此文章,本机器这里已经安装好了 kratos、proto、wire、make 等所需的命令工具

1.先下载beer-shop模板

git clone https://github.com/go-kratos/beer-shop.git

 2.删除api和app下的全部文件

3.修改go.mod文件

把module github.com/go-kratos/beer-shop 改成beer-shop,执行go mod vendor命令

4.生成proto相关文件
 api下新建test目录,执行kratos proto add api/test/service/v1/test.proto命令

修改test.proto文件,如下代码
 

syntax = "proto3";package api.test.service.v1;import "google/api/annotations.proto";option go_package = "github.com/go-kratos/beer-shop/api/test/service/v1;v1";service Test {rpc CreateTest (CreateTestRequest) returns (CreateTestReply){option (google.api.http) = {get: "/test/create/{name}"};};rpc UpdateTest (UpdateTestRequest) returns (UpdateTestReply);rpc DeleteTest (DeleteTestRequest) returns (DeleteTestReply);rpc GetTest (GetTestRequest) returns (GetTestReply);rpc ListTest (ListTestRequest) returns (ListTestReply);
}message CreateTestRequest {string name = 1;
}
message CreateTestReply {string message = 1;
}message UpdateTestRequest {int64 id = 1;string name = 2;
}
message UpdateTestReply {string message = 1;
}message DeleteTestRequest {}
message DeleteTestReply {}message GetTestRequest {int64 id = 1;
}
message GetTestReply {string message = 1;
}message ListTestRequest {}
message ListTestReply {}

5.然后生成proto代码

kratos proto client api/test/service/v1/test.proto

6.app下新增test/service文件夹

7.在service下,新增cmd/server文件夹

在servser下新增main.go文件

package mainimport ("flag""os""beer-shop/app/test/service/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/registry""github.com/go-kratos/kratos/v2/transport/grpc""github.com/go-kratos/kratos/v2/transport/http""go.opentelemetry.io/otel/exporters/jaeger""go.opentelemetry.io/otel/sdk/resource"tracesdk "go.opentelemetry.io/otel/sdk/trace"semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
)// go build -ldflags "-X main.Version=x.y.z"
var (// Name is the name of the compiled software.Name = "beer.test.service"// Version is the version of the compiled software.Version string// flagconf is the config flag.flagconf string
)func init() {flag.StringVar(&flagconf, "conf", "../../configs", "config path, eg: -conf config.yaml")
}func newApp(logger log.Logger, gs *grpc.Server, rr registry.Registrar, hs *http.Server) *kratos.App {return kratos.New(kratos.Name(Name),kratos.Version(Version),kratos.Metadata(map[string]string{}),kratos.Logger(logger),kratos.Server(gs,hs,),kratos.Registrar(rr),)
}func main() {flag.Parse()logger := log.With(log.NewStdLogger(os.Stdout),"service.name", Name,"service.version", Version,"ts", log.DefaultTimestamp,"caller", log.DefaultCaller,)c := config.New(config.WithSource(file.NewSource(flagconf),),)if err := c.Load(); err != nil {panic(err)}var bc conf.Bootstrapif err := c.Scan(&bc); err != nil {panic(err)}var rc conf.Registryif err := c.Scan(&rc); err != nil {panic(err)}exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(bc.Trace.Endpoint)))if err != nil {panic(err)}tp := tracesdk.NewTracerProvider(tracesdk.WithBatcher(exp),tracesdk.WithResource(resource.NewSchemaless(semconv.ServiceNameKey.String(Name),)),)app, cleanup, err := initApp(bc.Server, &rc, bc.Data, logger, tp)if err != nil {panic(err)}defer cleanup()// start and wait for stop signalif err := app.Run(); err != nil {panic(err)}
}

8.servsr新增wire.go文件

// +build wireinject// The build tag makes sure the stub is not built in the final build.package mainimport ("beer-shop/app/test/service/internal/biz""beer-shop/app/test/service/internal/conf""beer-shop/app/test/service/internal/data""beer-shop/app/test/service/internal/server""beer-shop/app/test/service/internal/service""github.com/go-kratos/kratos/v2""github.com/go-kratos/kratos/v2/log""github.com/google/wire"tracesdk "go.opentelemetry.io/otel/sdk/trace"
)// initApp init kratos application.
func initApp(*conf.Server, *conf.Registry, *conf.Data, log.Logger, *tracesdk.TracerProvider) (*kratos.App, func(), error) {panic(wire.Build(server.ProviderSet, data.ProviderSet, biz.ProviderSet, service.ProviderSet, newApp))
}

9.在service下,新增configs文件夹

configs下新增config.yaml文件(数据库根据自己配置修改)

trace:endpoint: http://127.0.0.1:14268/api/traces
server:http:addr: 0.0.0.0:8000timeout: 1sgrpc:addr: 0.0.0.0:9000timeout: 1s
data:database:driver: mysqlsource: root:root@tcp(127.0.0.1:3306)/test?parseTime=trueredis:addr: 127.0.0.1:6379read_timeout: 0.2swrite_timeout: 0.2s

configs下新增registry.yaml文件

consul:address: 127.0.0.1:8500scheme: http

11.app/test/service下新增internal/biz文件夹

biz文件下新增test.go

package bizimport ("context""github.com/go-kratos/kratos/v2/log"
)type Test struct {Id     int64Name   string
}type TestRepo interface {CreateTest(ctx context.Context, c *Test) (*Test, error)GetTest(ctx context.Context, id int64) (*Test, error)UpdateTest(ctx context.Context, c *Test) (*Test, error)ListTest(ctx context.Context, pageNum, pageSize int64) ([]*Test, error)
}type TestUseCase struct {repo TestRepolog  *log.Helper
}func NewTestUseCase(repo TestRepo, logger log.Logger) *TestUseCase {return &TestUseCase{repo: repo, log: log.NewHelper(log.With(logger, "module", "usecase/test"))}
}func (uc *TestUseCase) Create(ctx context.Context, u *Test) (*Test, error) {return uc.repo.CreateTest(ctx, u)
}func (uc *TestUseCase) Get(ctx context.Context, id int64) (*Test, error) {return uc.repo.GetTest(ctx, id)
}func (uc *TestUseCase) Update(ctx context.Context, u *Test) (*Test, error) {return uc.repo.UpdateTest(ctx, u)
}func (uc *TestUseCase) List(ctx context.Context, pageNum, pageSize int64) ([]*Test, error) {return uc.repo.ListTest(ctx, pageNum, pageSize)
}

biz文件下新增biz.go

package bizimport "github.com/google/wire"// ProviderSet is biz providers.
var ProviderSet = wire.NewSet(NewTestUseCase)

12.app/test/service下新增internal/conf文件夹

在conf下新增conf.proto

syntax = "proto3";
package kratos.api;option go_package = "app/test/service/internal/conf;conf";import "google/protobuf/duration.proto";message Bootstrap {Trace trace = 1;Server server = 2;Data data = 3;
}message Trace {string endpoint = 1;
}message Server {message HTTP {string network = 1;string addr = 2;google.protobuf.Duration timeout = 3;}message GRPC {string network = 1;string addr = 2;google.protobuf.Duration timeout = 3;}HTTP http = 1;GRPC grpc = 2;
}message Data {message Database {string driver = 1;string source = 2;}message Redis {string network = 1;string addr = 2;google.protobuf.Duration read_timeout = 3;google.protobuf.Duration write_timeout = 4;}Database database = 1;
}message Registry {message Consul {string address = 1;string scheme = 2;}Consul consul = 1;
}

在conf目录下执行以下命令,生成对应的conf.pb.go

protoc --go_out=paths=source_relative:. conf.proto

13.app/test/service下新增internal/data文件夹

在data下新增test.go

package dataimport ("context""time""gorm.io/gorm""beer-shop/pkg/util/pagination""github.com/go-kratos/kratos/v2/log""beer-shop/app/test/service/internal/biz"
)var _ biz.TestRepo = (*testRepo)(nil)type testRepo struct {data *Datalog  *log.Helper
}type Test struct {gorm.ModelId        int64Name      stringCreatedAt time.TimeUpdatedAt time.Time
}func NewTestRepo(data *Data, logger log.Logger) biz.TestRepo {return &testRepo{data: data,log:  log.NewHelper(log.With(logger, "module", "data/test")),}
}func (r *testRepo) CreateTest(ctx context.Context, b *biz.Test) (*biz.Test, error) {o := Test{Id: b.Id, Name: b.Name}result := r.data.db.WithContext(ctx).Create(&o)return &biz.Test{Id: o.Id,Name: o.Name,}, result.Error
}func (r *testRepo) GetTest(ctx context.Context, id int64) (*biz.Test, error) {o := Test{}result := r.data.db.WithContext(ctx).First(&o, id)return &biz.Test{Id: o.Id,}, result.Error
}func (r *testRepo) UpdateTest(ctx context.Context, b *biz.Test) (*biz.Test, error) {o := Test{}result := r.data.db.WithContext(ctx).First(&o, b.Id)if result.Error != nil {return nil, result.Error}o.Name = b.Nameresult = r.data.db.WithContext(ctx).Save(&o)if result.Error != nil {return nil, result.Error}return &biz.Test{Id: o.Id,}, nil
}func (r *testRepo) ListTest(ctx context.Context, pageNum, pageSize int64) ([]*biz.Test, error) {var os []Testresult := r.data.db.WithContext(ctx).Limit(int(pageSize)).Offset(int(pagination.GetPageOffset(pageNum, pageSize))).Find(&os)if result.Error != nil {return nil, result.Error}rv := make([]*biz.Test, 0)for _, o := range os {rv = append(rv, &biz.Test{Id: o.Id,})}return rv, nil
}

在data下新增data.go

package dataimport ("github.com/go-kratos/kratos/v2/log""github.com/google/wire""gorm.io/driver/mysql""gorm.io/gorm""beer-shop/app/test/service/internal/conf"// init mysql driver_ "github.com/go-sql-driver/mysql"
)// ProviderSet is data providers.
var ProviderSet = wire.NewSet(NewData, NewDB, NewTestRepo)// Data .
type Data struct {db  *gorm.DBlog *log.Helper
}func NewDB(conf *conf.Data, logger log.Logger) *gorm.DB {log := log.NewHelper(log.With(logger, "module", "test-service/data/gorm"))db, err := gorm.Open(mysql.Open(conf.Database.Source), &gorm.Config{})if err != nil {log.Fatalf("failed opening connection to mysql: %v", err)}if err := db.AutoMigrate(&Test{}); err != nil {log.Fatal(err)}return db
}// NewData .
func NewData(db *gorm.DB, logger log.Logger) (*Data, func(), error) {log := log.NewHelper(log.With(logger, "module", "test-service/data"))d := &Data{db:  db,log: log,}return d, func() {}, nil
}

14.app/test/service下新增internal/server文件夹

在server下新增grpc.go

package serverimport ("beer-shop/api/test/service/v1""beer-shop/app/test/service/internal/conf""beer-shop/app/test/service/internal/service""github.com/go-kratos/kratos/v2/log"tracesdk "go.opentelemetry.io/otel/sdk/trace""github.com/go-kratos/kratos/v2/middleware/logging""github.com/go-kratos/kratos/v2/middleware/recovery""github.com/go-kratos/kratos/v2/middleware/tracing""github.com/go-kratos/kratos/v2/transport/grpc"
)// NewGRPCServer new a gRPC server.
func NewGRPCServer(c *conf.Server, logger log.Logger, tp *tracesdk.TracerProvider, s *service.TestService) *grpc.Server {var opts = []grpc.ServerOption{grpc.Middleware(recovery.Recovery(),tracing.Server(tracing.WithTracerProvider(tp)),logging.Server(logger),),}if c.Grpc.Network != "" {opts = append(opts, grpc.Network(c.Grpc.Network))}if c.Grpc.Addr != "" {opts = append(opts, grpc.Address(c.Grpc.Addr))}if c.Grpc.Timeout != nil {opts = append(opts, grpc.Timeout(c.Grpc.Timeout.AsDuration()))}srv := grpc.NewServer(opts...)v1.RegisterTestServer(srv, s)return srv
}

在server下新增http.go

package serverimport ("beer-shop/api/test/service/v1""beer-shop/app/test/service/internal/conf""beer-shop/app/test/service/internal/service""github.com/go-kratos/kratos/v2/log""github.com/go-kratos/kratos/v2/transport/http"tracesdk "go.opentelemetry.io/otel/sdk/trace""github.com/go-kratos/kratos/v2/middleware/logging""github.com/go-kratos/kratos/v2/middleware/recovery""github.com/go-kratos/kratos/v2/middleware/tracing"
)// NewGRPCServer new a gRPC server.
func NewHTTPServer(c *conf.Server, logger log.Logger, tp *tracesdk.TracerProvider, s *service.TestService) *http.Server {var opts = []http.ServerOption{http.Middleware(recovery.Recovery(),tracing.Server(tracing.WithTracerProvider(tp)),logging.Server(logger),),}if c.Http.Network != "" {opts = append(opts, http.Network(c.Http.Network))}if c.Http.Addr != "" {opts = append(opts, http.Address(c.Http.Addr))}if c.Http.Timeout != nil {opts = append(opts, http.Timeout(c.Http.Timeout.AsDuration()))}srv := http.NewServer(opts...)v1.RegisterTestHTTPServer(srv, s)return srv
}

在server下新增server.go

package serverimport ("beer-shop/app/test/service/internal/conf""github.com/go-kratos/kratos/v2/registry""github.com/google/wire"consul "github.com/go-kratos/kratos/contrib/registry/consul/v2"consulAPI "github.com/hashicorp/consul/api"
)// ProviderSet is server providers.
var ProviderSet = wire.NewSet(NewGRPCServer,NewHTTPServer, NewRegistrar)func NewRegistrar(conf *conf.Registry) registry.Registrar {c := consulAPI.DefaultConfig()c.Address = conf.Consul.Addressc.Scheme = conf.Consul.Schemecli, err := consulAPI.NewClient(c)if err != nil {panic(err)}r := consul.New(cli, consul.WithHealthCheck(false))return r
}

15.app/test/service下新增internal/service文件夹

在service下新增test.go文件

package serviceimport ("context"v1 "beer-shop/api/test/service/v1""beer-shop/app/test/service/internal/biz"
)func (s *TestService) CreateTest(ctx context.Context, req *v1.CreateTestRequest) (*v1.CreateTestReply, error) {x, err := s.oc.Create(ctx, &biz.Test{Name: req.Name})if err != nil {return nil, err}return &v1.CreateTestReply{Message: x.Name,}, nil
}func (s *TestService) GetTest(ctx context.Context, req *v1.GetTestRequest) (*v1.GetTestReply, error) {x, err := s.oc.Get(ctx, req.Id)if err != nil {return nil, err}return &v1.GetTestReply{Message: x.Name,}, nil
}func (s *TestService) UpdateTest(ctx context.Context, req *v1.UpdateTestRequest) (*v1.UpdateTestReply, error) {x, err := s.oc.Update(ctx, &biz.Test{})if err != nil {return nil, err}return &v1.UpdateTestReply{Message: x.Name,}, nil
}func (s *TestService) ListTest(ctx context.Context, req *v1.ListTestRequest) (*v1.ListTestReply, error) {return &v1.ListTestReply{}, nil
}

在service下新增service.go文件

package serviceimport (v1 "beer-shop/api/test/service/v1""beer-shop/app/test/service/internal/biz""github.com/go-kratos/kratos/v2/log""github.com/google/wire"
)// ProviderSet is service providers.
var ProviderSet = wire.NewSet(NewTestService)type TestService struct {v1.UnimplementedTestServeroc  *biz.TestUseCaselog *log.Helper
}func NewTestService(oc *biz.TestUseCase, logger log.Logger) *TestService {return &TestService{oc:  oc,log: log.NewHelper(log.With(logger, "module", "service/test"))}
}

15.重新执行命令

kratos proto client api/test/service/v1/test.proto
go mod vendor

在app\test\service\cmd\server下执行wire命令

wire

windows下启动consul服务

consul agent -dev

16.执行kratos runm命令运行项目

在游览器访问 http://localhost:8000/test/create/123

17.最后附上目录截图

 


http://chatgpt.dhexx.cn/article/bml866tJ.shtml

相关文章

kratos mysql_kratos微服务框架学习笔记一(kratos-demo)

本文将为您描述kratos微服务框架学习笔记一(kratos-demo),教程操作步骤: 目录 kratos微服务框架学习笔记一(kratos-demo) kratos本体 demo kratos微服务框架学习笔记一(kratos-demo) 今年大部分时间飘过去了,没怎么更博和github,现在开发任务也差不多完成…

Kratos日志

一.如何在kratos框架中使用 参考官方文档中描述,为了方便业务自适配不同的 log 接入使用,Logger 只包含了最简单的 Log 接口。当业务需要在 Kratos 框架内部使用自定义的 log的时候,只需要简单实现方法即可。日志库较为公用建议放在kit基础库…

kratos框架学习,在Linux 下面使用kratos 创建demo 项目然后跑起来。使用 kratos new kratos-demo 一键创建项目,脚手架非常方便。但是依赖grpc没有起来

目录 前言1,关于kratos2,使用 kratos new kratos-demo 一键创建项目3,解决gRPC 编译问题4,只创建HTTP服务 前言 本文的原文连接是: https://blog.csdn.net/freewebsys/article/details/109139648 未经博主允许不得转载。 博主地址…

砥砺前行 | Kratos 框架 v2 版本架构演进之路

Kratos 是一套轻量级 Go 微服务框架,包含大量微服务相关功能及工具。名字来源于游戏《战神》,该游戏以希腊神话为背景,讲述了奎托斯(Kratos)由凡人成为战神并展开弑神屠杀的冒险历程。 写在前面 从 2021 年 2 月份&…

【kratos入门实战教程】1-kratos项目搭建和开发环境配置

1、系列目录 【kratos入门实战教程】0-商城项目介绍【kratos入门实战教程】1-kratos项目搭建和开发环境配置【kratos入门实战教程】2-实现注册登陆业务 2、概览 经过上一篇的说明,本篇教程正式开始搭建项目。深入解析工程项目的目录结构和介绍一些开发需要使用的工…

go微服务框架Kratos简单使用总结

Kratos是B站开源的一款go的微服务框架,最近PS5上的 战神诸神黄昏比较火,主角就是奎托斯。这个框架的名字就取自他。 在进行框架选型时,对比了目前主流的很多go微服务框架,如Zero,最后对比之下,选择了Krato…

c语言代码后return0表示什么意思,C语言中return 0 表示什么

满意答案 强计划止步不.. 2013.01.03 采纳率:44% 等级:12 已帮助:7948人 return表示函数结束, 也就是说CPU执行到return后, 就会跳转(如果要好理解的话, 是"回到")到调用它的地方, 然后继续执行. 而0, 是一个整型, 一般来说retu…

c语言代码后return0表示什么意思,return 0是什么意思 ?

return 0 代表告诉调用者程序是正常退出的。return是C预定义的语句,它提供了终止函数执行的一种方式。当return语句提供了一个值时,这个值就成为函数的返回值。 这个return语句结束main()函数的执行,把0返还给操作系统。从main()函数返回0表…

接口性能测试方案

一、 性能测试术语解释 1. 响应时间 响应时间即从应用系统发出请求开始,到客户端接收到最后一个字节数据为止所消耗的时间。响应时间按软件的特点再可以细分,如对于一个 C/S 软件(B/S一样)的响应时间可以细分为网络传输时间、应…

软件性能测试方案-性能测试准备

性能测试目的 1、性能调优 开发人员对系统调优后,需要测试人员配合去做性能测试,验证这次优化是否有效果。如果性能指标相比较之前的性能指标更好了,说明系统优化的有效果。反之说明调优不理想 2、新业务、新接口上线 系统从无到上线&…

参考文档一:性能测试---测试方案

性能测试详细测试方案 前言 平台XX项目系统已经成功发布,依据项目的规划,未来势必会出现业务系统中信息大量增长的态势。 随着业务系统在生产状态下日趋稳定、成熟,系统的性能问题也逐步成为了我们关注的焦点:每天大数据量的“…

【性能测试】性能测试方案设计

性能测试方案设计 1. 性能测试流程 系统架构调研 业务模型分析调研 测试需求分析设计测试方案测试环境搭建测试数据准备测试工具开发测试场景设置执行场景测试测试结果分析提交测试报告 2. 性能测试需求分析和范围确定 收集性能需求信息分析应用程序 系统设计和架构信息网…

接口性能测试方案 白皮书 V1.0

一、 性能测试术语解释 1. 响应时间 响应时间即从应用系统发出请求开始,到客户端接收到最后一个字节数据为止所消耗的时间。响应时间按软件的特点再可以细分,如对于一个 C/S 软件的响应时间可以细分为网络传输时间、应用服务器处理时间、数据库服务器处…

性能测试案例

做性能测试之前需要对Linux内核参数优化 Linux内核参数优化 Linux服务器默认支持1024个TCP链接,在性能测试时,无论压力机还是项目服务器,都需要对tcp参数进行一些优化 ulimit -n:查看当前Linux系统最大的连接数 修改Linux系统允许…

性能测试(一)

一)谈谈你对于性能测试的理解: 1)性能测试的概念 测试目的与功能测试的区别性能测试的指标 2)性能测试需要借助工具来进行测试,可以说说自己是用了哪些工具以及如何使用工具来进行性能测试 3)为了避免面试官在性能测试方面进行深究,主动说性能测试难就难…

最全面性能测试方案模板

性能测试方案书 1 简介 1.1目的 编写本文档的目的在于描述测试项目的测试范围,定义测试条件和目标,测试策略和要求,分析可能的风险,提供相应的规避措施或应急对策,并确定测试整体进度的计划和人力资源安排等。 测试目…

性能测试介绍

转载来源 公众号《测试开发技术》 1.性能测试要开专栏了 提起性能测试,可能很多互联网从业人员会感觉比较混淆(不仅仅只是测试人员会弄混淆,很多开发人员、管理人员对性能测试也都是一知半解)。性能测试,它是属于测试…

性能测试流程-性能测试2

性能测试流程 1. 性能测试需求分析 2. 性能测试计划及方案 3. 性能测试用例 4. 搭建测试环境 5. 测试数据准备 6. 测试脚本编写 7. 执行测试脚本 8. 性能测试监控 9. 性能分析和调优 10. 性能测试回归 11. 性能测试报告总结 1、性能测试需求分析 熟悉被测系统 熟…

【测试方案】性能方案设计

什么是性能测试? 压力测试:强调极端暴力 稳定性测试:在一定压力下,长时间运行的情况 基准测试:在特定条件下的性能测试 负载测试:不同负载下的表现 容量测试:最优容量 性能测试方案设计流程 需…

性能测试—性能测试方案设计思路总结

一、需求分析 1.测试目的 为什么测?目的在于测试系统相关性能能否满足业务需求。通常分以下两种情况: 1)新项目上线 2)老项目优化 如果是老项目优化,可考虑是否存有历史测试方案,如果有可以参考&#…