使用go-zero快速构建微服务

这篇具有很好参考价值的文章主要介绍了使用go-zero快速构建微服务。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文是对 使用go-zero快速构建微服务[1]的亲手实践


编写API Gateway代码


mkdir bookstore && cd bookstore
go mod init bookstore

mkdir api && goctl api -o api/bookstore.api

syntax = "v1"

info(
    title: "xx使用go-zero"
    desc: "xx用来上手go-zero"
    author: "xxxx"
    email: "xxxx@gmail.com"
)

type (
    addReq struct {
        book string `form:"book"`
        price int64 `form:"price"`
    }

    addResp struct {
        ok bool `json:"ok"`
    }
)

type (
    checkReq struct {
        book string `form:"book"`
    }

    checkResp struct {
        found bool `json:"found"`
        price int64 `json:"price"`
    }
)


service bookstore-api {
    @handler AddHandler
    get /add (addReq) returns (addResp)

    @handler CheckHandler
    get /check (checkReq) returns (checkResp)
}

cd api && goctl api go -api bookstore.api -dir .

使用go-zero快速构建微服务,后端
api
├── bookstore.api                  // api定义
├── bookstore.go                   // main入口定义
├── etc
│   └── bookstore-api.yaml         // 配置文件
└── internal
    ├── config
    │   └── config.go              // 定义配置
    ├── handler
    │   ├── addhandler.go          // 实现addHandler
    │   ├── checkhandler.go        // 实现checkHandler
    │   └── routes.go              // 定义路由处理
    ├── logic
    │   ├── addlogic.go            // 实现AddLogic
    │   └── checklogic.go          // 实现CheckLogic
    ├── svc
    │   └── servicecontext.go      // 定义ServiceContext
    └── types
        └── types.go               // 定义请求、返回结构体


go run bookstore.go -f etc/bookstore-api.yaml

启动API Gateway服务,默认侦听在8888端口

因为默认生成的api/etc/bookstore-api.yml为:

Name: bookstore-api
Host: 0.0.0.0
Port: 8888
使用go-zero快速构建微服务,后端

按提示下载,再次运行:

使用go-zero快速构建微服务,后端
使用go-zero快速构建微服务,后端
{"@timestamp":"2023-02-16T16:31:09.658+08:00","caller":"stat/usage.go:61","content":"CPU: 0m, MEMORY: Alloc=2.5Mi, TotalAlloc=2.5Mi, Sys=14.5Mi, NumGC=0","level":"stat"}
{"@timestamp":"2023-02-16T16:31:09.662+08:00","caller":"load/sheddingstat.go:61","content":"(api) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0","level":"stat"}
{"@timestamp":"2023-02-16T16:31:15.044+08:00","caller":"stat/metrics.go:210","content":"(bookstore-api) - qps: 0.0/s, drops: 0, avg time: 0.0ms, med: 0.0ms, 90th: 0.0ms, 99th: 0.0ms, 99.9th: 0.0ms","level":"stat"}

会定时(默认一分钟)输出cpu,内存等的统计信息,可以通过 logx.DisableStat()禁用 (可以做到自定义模板.tpl里)

使用go-zero快速构建微服务,后端

返回的是null,并不是预期的{"found":false,"price":0}

这是因为:

使用go-zero快速构建微服务,后端

resp是一个指针,这样直接return会是nil,需要如下显式声明

使用go-zero快速构建微服务,后端

重启服务,再次发起请求,这样的response就符合预期了~

使用go-zero快速构建微服务,后端

目前只返回了个空值,接下来会在rpc服务里实现业务逻辑

可以修改internal/svc/servicecontext.go来传递服务依赖(如果需要,比如Config,Auth,后续用到的RPC等)

实现逻辑可以修改internal/logic下的对应文件(如果接口较多,可以在.api里定义不同的group,使用goctl生成代码时,会自动在logic下根据group名称创建不同的文件夹)

可以通过goctl生成各种客户端语言的api调用代码(供客户端同学使用;支持多种语言)


编写RPC代码


编写add rpc服务

切到bookstore目录下

mkdir -p rpc/add && cd rpc/add

goctl rpc template -o add.proto

修改后文件内容如下:

syntax = "proto3";

package add;

option go_package = "./pb";

message addReq {
  string book = 1;
  int64 price = 2;
}

message addResp {
  bool ok = 1;
}

service adder {
  rpc add(addReq) returns(addResp);
}

goctl rpc protoc add.proto --go_out=./pb --go-grpc_out=./pb --zrpc_out=.

使用go-zero快速构建微服务,后端
rpc/add
├── add.go                      // rpc服务main函数
├── add.proto                   // rpc接口定义
├── adder
   ├── adder.go                // 提供了外部调用方法,无需修改
   ├── adder_mock.go           // mock方法,测试用
   └── types.go                // request/response结构体定义
├── etc
   └── add.yaml                // 配置文件
├── internal
   ├── config
      └── config.go           // 配置定义
   ├── logic
      └── addlogic.go         // add业务逻辑在这里实现
   ├── server
      └── adderserver.go      // 调用入口, 不需要修改
   └── svc
       └── servicecontext.go   // 定义ServiceContext,传递依赖
└── pb
    └── add.pb.go

go run add.go -f etc/add.yaml 可运行该服务

默认每隔一分钟输出cpu和内存信息

{"@timestamp":"2023-02-16T20:02:10.640+08:00","caller":"stat/usage.go:61","content":"CPU: 0m, MEMORY: Alloc=3.3Mi, TotalAlloc=6.2Mi, Sys=15.9Mi, NumGC=3","level":"stat"}
{"@timestamp":"2023-02-16T20:02:10.656+08:00","caller":"load/sheddingstat.go:61","content":"(rpc) shedding_stat [1m], cpu: 0, total: 0, pass: 0, drop: 0","level":"stat"}
编写check rpc服务

切到bookstore目录下

mkdir -p rpc/check && cd rpc/check

goctl rpc template -o check.proto

修改后文件内容如下:

syntax = "proto3";

package check;

option go_package = "./pb";

message checkReq {
  string book = 1;
}

message checkResp {
  bool found = 1;
  int64 price = 2;
}

service checker {
  rpc check(checkReq) returns(checkResp);
}

goctl rpc protoc check.proto --go_out=./pb --go-grpc_out=./pb --zrpc_out=.

使用go-zero快速构建微服务,后端
rpc/check
├── check.go                    // rpc服务main函数
├── check.proto                 // rpc接口定义
├── checker
   ├── checker.go              // 提供了外部调用方法,无需修改
   ├── checker_mock.go         // mock方法,测试用
   └── types.go                // request/response结构体定义
├── etc
   └── check.yaml              // 配置文件
├── internal
   ├── config
      └── config.go           // 配置定义
   ├── logic
      └── checklogic.go       // check业务逻辑在这里实现
   ├── server
      └── checkerserver.go    // 调用入口, 不需要修改
   └── svc
       └── servicecontext.go   // 定义ServiceContext,传递依赖
└── pb
    └── check.pb.go

go run check.go -f etc/check.yaml 可运行该服务

修改etc/check.yaml的端口为8081(因为8080已经被add服务使用了)


再回去修改API Gateway代码,调用add/check rpc服务


api/etc/bookstore-api.yaml,增加如下内容

Add:
  Etcd:
    Hosts:
      - localhost:2379
    Key: add.rpc
Check:
  Etcd:
    Hosts:
      - localhost:2379
    Key: check.rpc

通过etcd自动去发现可用的add和check服务

使用go-zero快速构建微服务,后端

修改api/internal/config/config.go如下,增加add&check服务依赖

使用go-zero快速构建微服务,后端

修改api/internal/svc/servicecontext.go,如下:

使用go-zero快速构建微服务,后端

通过ServiceContext在不同业务逻辑之间传递依赖

(问:怎么解决依赖注入问题)


修改api/internal/logic/addlogic.go里的Add方法,如下:

使用go-zero快速构建微服务,后端使用go-zero快速构建微服务,后端

通过调用adder的Add方法实现添加图书到bookstore系统


修改api/internal/logic/checklogic.go里的Check方法,如下:

使用go-zero快速构建微服务,后端

通过调用checker的Check方法实现从bookstore系统中查询图书的价格


定义数据库表结构,并生成CRUD+cache代码


bookstore下创建rpc/model目录

mkdir -p rpc/model (不过一般习惯把这个model文件夹抽出来,和api,rpc在一层)

在rpc/model目录下编写创建book表的sql文件book.sql,如下:

CREATE TABLE `book`
(
  `book` varchar(255NOT NULL COMMENT 'book name',
  `price` int NOT NULL COMMENT 'book price',
  PRIMARY KEY(`book`)
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

进入mysql命令行,创建DB和table

create database gozero;
source book.sql;

在rpc/model目录下执行如下命令生成CRUD+cache代码,-c表示使用redis cache

goctl model mysql ddl -c -src book.sql -dir .

使用go-zero快速构建微服务,后端

修改add rpc和check rpc,调用crud+cache代码


修改rpc/add/etc/add.yaml和rpc/check/etc/check.yaml,均增加如下内容:

DataSource: root:123456@@tcp(xxx.xxx.xx.xx:3306)/gozero
#DataSource: root:123456@@tcp(localhost:3306)/gozero?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai #可以这样指定一些其他信息
Table: book
Cache:
  - Host: localhost:6379

使用go-zero快速构建微服务,后端

可以使用多个redis作为cache,支持redis单点或者redis集群


修改rpc/add/internal/config.go和rpc/check/internal/config.go,如下:

使用go-zero快速构建微服务,后端
使用go-zero快速构建微服务,后端

修改rpc/add/internal/svc/servicecontext.go和rpc/check/internal/svc/servicecontext.go,如下:

使用go-zero快速构建微服务,后端
使用go-zero快速构建微服务,后端

修改rpc/add/internal/logic/addlogic.go,如下

使用go-zero快速构建微服务,后端
使用go-zero快速构建微服务,后端

修改rpc/check/internal/logic/checklogic.go,如下:

使用go-zero快速构建微服务,后端

项目使用


需要先全部启动api服务所依赖的rpc服务。如果先启动api,则会报错:

error: context deadline exceeded, make sure rpc service "add.rpc" is already started

全部启动:

使用go-zero快速构建微服务,后端
使用go-zero快速构建微服务,后端
使用go-zero快速构建微服务,后端

(后面可以 -f指定不同环境的xxx.yaml)

调用add api,新增图书

curl -i "http://localhost:8888/add?book=Bible&price=10"

使用go-zero快速构建微服务,后端

此时看数据库,book表里新增了一行数据


调用check api,检查某本图书的价格

curl -i "http://localhost:8888/check?book=Bible"

使用go-zero快速构建微服务,后端
使用go-zero快速构建微服务,后端

重启check rpc,再次执行curl -i "http://localhost:8888/check?book=Bible"

使用go-zero快速构建微服务,后端

完整项目代码[2]

参考资料

[1]

使用go-zero快速构建微服务: http://www.jikejiaocheng.com/c/gozero-microservices.html

[2]

完整项目代码: https://github.com/cuishuang/bookstore

本文由 mdnice 多平台发布文章来源地址https://www.toymoban.com/news/detail-640421.html

到了这里,关于使用go-zero快速构建微服务的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【go-zero】docker镜像直接部署go-zero的API与RPC服务 如何实现注册发现?docker network 实现 go-zero 注册发现

    使用docker直接部署go-zero微服务会发现API无法找到RPC服务 用docker直接部署 我们会发现API无法注册发现RPC服务 原因是我们缺少了docker的network网桥 RPC服务运行正常 API服务启动,通过docker logs 查看日志还是未发现RPC API的yaml配置 RPC服务的IP是 127.0.0.1 与对应的端口 下图为改成了定

    2024年02月13日
    浏览(37)
  • go-zero的服务发现源码阅读

    服务发现原理与grpc源码解析_wangxiaoangg的博客-CSDN博客   go-zero rpc demo官方文档:rpc编写与调用 | go-zero 目录 一 服务注册 1. 创建rpc服务 2. 启动rpc服务 3. registerEtcd做了什么 4. discov.NewPublisher 服务发布者 二 服务发现 1.定义注册resolver 2.解析etcd地址创建链接 3.update方法 在看rp

    2024年02月06日
    浏览(46)
  • go-zero学习 第三章 微服务

    1.1 API服务模块 goctl 使用 api 文件生成 api服务 命令: 1.2 RPC服务模块 goctl 使用 protoc 文件生成 rpc服务 命令: 注意: --go_out 、 --go-grpc_out 、 --zrpc_out 三者配置的路径需要完全一致,否则会报下列错误。 基础代码:已生成基本的API服务、RPC服务。 这里以API服务调用RPC服务的登

    2024年02月16日
    浏览(60)
  • go-zero的rpc服务案例解析

    go-zero的远程调用服务是基于gRpc的gRPC教程与应用。 zero使用使用gRpc需要安装 protoc 插件,因为gRpc基于protoc插件使用protocol buffers文件生成rpc服务器和api的代码的。 gRPC 的代码生成还依赖 protoc-gen-go,protoc-gen-go-grpc 插件来配合生成 Go 语言的 gRPC 代码。 也可以使用go get命令安装

    2024年02月13日
    浏览(64)
  • 【go-zero】go-zero阿里云oss 前端上传文件到go-zero API服务 并在k8s pod中创建文件 并推送到阿里云oss 最佳实践

    问题:在本地通过上传文件,然后将文件推送到aliyun的oss中,是没问题的 但是部署到了k8s中,则出现了问题,一直报错没有创建的权限 思路:开始认为应该将该文件挂载到configmap中,然后通过这种方式修改了deployment和dockerfile。最终发现应该是go的创建文件路径方式搞错了,

    2024年02月13日
    浏览(38)
  • 微服务框架 go-zero logx 日志组件剖析

    上一篇我们说到咱们还剩下 addTenant 功能还未实现,不知道有没有兄弟感兴趣去实验一波的,本篇文章进行简要补充 根据上一篇文章分析,其实我们只需要执行如下几步即可: 编写 tenant.api,提供外部 addTenant 的 http 接口 编写 tenant.api 提供一个 POST http 的接口 / api /tenant/addt

    2024年02月11日
    浏览(39)
  • 微服务架构|go-zero 的自适应熔断器

    原文链接: go-zero 的自适应熔断器 上篇文章我们介绍了微服务的限流,详细分析了计数器限流和令牌桶限流算法,这篇文章来说说熔断。 熔断和限流还不太一样,限流是控制请求速率,只要还能承受,那么都会处理,但熔断不是。 在一条调用链上,如果发现某个服务异常,

    2024年02月10日
    浏览(41)
  • go-zero/grpc的rpc服务间传递额外数据

    go-zero/grpc的rpc服务间传递额外数据 2024/02/18 客户端: 初始化 md 也可如下方式: 追加新的如下: 也可使用 md 的 Set 和 Append 方法追加: 服务端: 注意 key 都会被转为小写,即使客户端为大写: 而且 key 只能由 数字、字母和三个特殊字符“-_.”组成,大写字母会自动被转为小写

    2024年02月19日
    浏览(50)
  • GoZero微服务个人探究之路(二)Go-Zero官方api demo示例探究

    api demo 代码生成 | go-zero Documentation 编辑 demo-api.yaml 编辑 服务名称:demo-api HOST地址:0.0.0.0监听所有可用网络接口 Port地址:服务运行在8888端口 config/config.go 编辑 存储config信息,这里rest.RestConf是RESTful API的结构体,此外还可以添加数据库,缓存配置信息 handler/demohandler.go 编辑

    2024年01月18日
    浏览(38)
  • GoZero微服务个人探索之路(三)Go-Zero官方rpc demo示例探究

    两个文件均为protoc-gen-go-grpc自动生成 构成一个完整的 gRPC 服务的定义和实现 demo.go goctl生成的客户端代码 Request 和 Response 别名: 定义了 Request 和 Response 两个别名,实际上是从 demo 包中导入的对应的消息类型。 Demo 接口: 定义了一个 Demo 接口,其中包含了调用 gRPC 服务中 P

    2024年01月18日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包