网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
4.3 方式 1
- 先下载
goctl
go install github.com/zeromicro/go-zero/tools/goctl@latest
查看goctl版本:goctl -v
PS E:\SoftwareData\Aliyun> goctl -v
goctl version 1.4.3 windows/amd64
- goctl一键安装
protoc
、protoc-gen-go
、protoc-gen-go-grpc
goctl env check -i -f --verbose
4.4 方式 2
4.4.1 Protobuf下载安装
需要先下载protoc执行器
- 到 https://github.com/protocolbuffers/protobuf/releases 分别下载Windows和Linux环境的执行器
- 选择最新版本的protoc下载
- 将下载的文件解压,将解压后的bin目录加入到环境变量的path下。
- 查看安装是否成功:
protoc --version
Protobuf下Go、GRPC插件的安装
protoc-gen-go:Go专用的protoc的编译器插件,安装后会在GOPATH的bin目录下生成一个protoc-gen-go.exe
protoc-gen-go-grp:Go调用grpc的插件,安装后会在GOPATH的bin目录下生成一个protoc-gen-go-grpc.exe
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.26
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1
至此使用Protobuf的准备工作就做完了。
4.4.2 goctl 安装
go install github.com/zeromicro/go-zero/tools/goctl@latest
5 简单入门
快速生成api
服务,api
服务就是网关服务,如果不与Service
端【RPC端
】交互,则可以独立成一个单独的服务使用。
goctl api new greet
cd greet
go mod init
go mod tidy
go run greet.go -f etc/greet-api.yaml
默认侦听在 8888 端口(可以在配置文件里修改):
curl -i http://localhost:8888/from/you
返回如下:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Traceparent: 00-45fa9e7a7c505bad3a53a024e425ace9-eb5787234cf3e308-00
Date: Thu, 22 Oct 2020 14:03:18 GMT
Content-Length: 14
null
※6 配置介绍
6.1 api配置
参考:api配置
6.2 rpc配置
参考:rpc配置
7 单体服务
参考:单体服务
8 微服务
8.1 代码
代码:https://gitee.com/XiMuQi/go-zero-micro/tree/v1.0.0【暂不对外开发】
8.2 注意事项
go-zero微服务的注册中心默认使用的是Etcd。
本小节将以一个订单服务
调用用户服务
来简单演示一下,其实订单服务
是api
服务,用户服务
是rpc
服务。
这里的创建步骤和官方文档的不一致,做了部分优化,前提是已经了解了go-zero
微服务调用及配置流程。初学者还是推荐按照官方文档操作。
8.3 服务划分及创建
- 创建
go-zero-micro
文件夹 - 在
go-zero-micro
文件夹分别创建api
、rpc
文件夹 - 在
api
下创建order
文件夹 - 在
rpc
下创建user
文件夹
整个服务结构
8.4 完善用户服务【user】
8.4.1 .proto生成user服务各部分代码
- 在
user
服务下添加user.proto
文件,增加getUser
方法
syntax = "proto3";
package user;
// protoc-gen-go 版本大于1.4.0, proto文件需要加上go\_package,否则无法生成
option go_package = "./user";
message IdRequest {
string id = 1;
}
message UserResponse {
// 用户id
string id = 1;
// 用户名称
string name = 2;
// 用户性别
string gender = 3;
}
service User {
rpc getUser(IdRequest) returns(UserResponse);
}
- 执行生成命令
在go-zero-micro\rpc\user>
下执行
goctl rpc protoc user.proto --go_out=./ --go-grpc_out=./ --zrpc_out=.
生成user服务
代码结构:
附:官方文档给出的命令:
goctl rpc protoc user.proto --go_out=./types --go-grpc_out=./types --zrpc_out=.
生成的代码结构:
两个命令的主要区别是官方文档给出的命令指定了.pb.go
和_grpc.pb.go
所在位置,这个不影响代码逻辑。
8.4.2 完善代码逻辑
user服务的代码逻辑主要是在 internal/logic/xxxlogic.go
里填写,xxxlogic.go
的xxx
指的是在.proto
中定义的方法名的小写。
例如:
user.proto
rpc getUser(IdRequest) returns(UserResponse);
对应 internal/logic/getuserlogic.go
,一个rpc
方法对应一个logic.go
。在logic.go
中可以进一步处理请求,比如操作数据库,Redis等。
package logic
import (
"context"
"go-zero-micro/rpc/user/internal/svc"
"go-zero-micro/rpc/user/user"
"github.com/zeromicro/go-zero/core/logx"
)
type GetUserLogic struct {
ctx context.Context
svcCtx \*svc.ServiceContext
logx.Logger
}
func NewGetUserLogic(ctx context.Context, svcCtx \*svc.ServiceContext) \*GetUserLogic {
return &GetUserLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
func (l \*GetUserLogic) GetUser(in \*user.IdRequest) (\*user.UserResponse, error) {
// todo: add your logic here and delete this line
userRes :=&user.UserResponse{
Id: in.Id,
Gender: "男",
}
if in.Id == "1" {
userRes.Name = "admin"
}else {
userRes.Name = "test"
}
return userRes, nil
}
8.5 完善订单服务【order】
8.5.1 .api生成order服务各部分代码
- 在
order
服务下添加order.api
文件,增加getUser
方法
syntax = "v1"
info(
title: "type title here"
desc: "type desc here"
author: "type author here"
email: "type email here"
version: "type version here"
)
type(
OrderReq {
Id string `path:"id"`
}
OrderReply {
Id string `json:"id"`
Name string `json:"name"`
}
)
service order {
@handler getOrder
get /api/order/get/:id (OrderReq) returns (OrderReply)
}
- 执行生成
order
服务的命令
在go-zero-micro\api\order>
下执行
goctl api go -api order.api -dir .
生成order服务代码结构:
8.5.2 order服务添加调用user服务的配置
order服务
调用user服务
需要改动3个地方。
1 etc/order.yaml
2 internal/config/config.go
3 internal/svc/servicecontext.go
- etc/order.yaml
主要是配置user服务
的Etcd
服务发现。注意要和user服务
的user.yaml
的Etcd
地址一致。
# order.yaml
Name: order
Host: 0.0.0.0
Port: 8888
UserRpc:
Etcd:
Hosts:
- 192.168.13.3:2379
Key: user.rpc
user.yaml
:
# user.yaml
Name: user.rpc
ListenOn: 0.0.0.0:8080
Etcd:
Hosts:
- 192.168.13.3:2379
Key: user.rpc
- internal/config/config.go
主要是加入user服务
的RPC。
package config
import (
"github.com/zeromicro/go-zero/rest"
"github.com/zeromicro/go-zero/zrpc"
)
type Config struct {
rest.RestConf
UserRpc zrpc.RpcClientConf
}
- internal/svc/servicecontext.go
主要是将 2 配置的user服务
接口加入到order服务
的ServiceContext
中。
package svc
import (
"github.com/zeromicro/go-zero/zrpc"
"go-zero-micro/api/order/internal/config"
"go-zero-micro/rpc/user/userclient"
)
type ServiceContext struct {
Config config.Config
UserRpc userclient.User
}
func NewServiceContext(c config.Config) \*ServiceContext {
return &ServiceContext{
Config: c,
UserRpc: userclient.NewUser(zrpc.MustNewClient(c.UserRpc)),
}
}
8.6 完善order服务调用user服务的逻辑
order服务
修改 getorderlogic.go
:
package logic
import (
"context"
"errors"
"go-zero-micro/api/order/internal/svc"
"go-zero-micro/api/order/internal/types"
"go-zero-micro/rpc/user/user"
"strconv"
"github.com/zeromicro/go-zero/core/logx"
)
type GetOrderLogic struct {
logx.Logger
ctx context.Context
svcCtx \*svc.ServiceContext
}
func NewGetOrderLogic(ctx context.Context, svcCtx \*svc.ServiceContext) \*GetOrderLogic {
return &GetOrderLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l \*GetOrderLogic) GetOrder(req \*types.OrderReq) (resp \*types.OrderReply, err error) {
// todo: add your logic here and delete this line
Id,err := strconv.Atoi(req.Id)
if err != nil {
return nil, err
}
if Id < 1{
return nil, errors.New("用户不存在")
![img](https://img-blog.csdnimg.cn/img_convert/592103a0ce15803603abf2bf77d23868.png)
![img](https://img-blog.csdnimg.cn/img_convert/7e142c67ec1b4dc73d8c854acecb807f.png)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618658159)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
error) {
// todo: add your logic here and delete this line
Id,err := strconv.Atoi(req.Id)
if err != nil {
return nil, err
}
if Id < 1{
return nil, errors.New("用户不存在")
[外链图片转存中...(img-qKJNClgi-1715835753144)]
[外链图片转存中...(img-yiTz3oEL-1715835753144)]
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618658159)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**