goZero微服务开发小结

 更新时间:2026年04月03日 10:16:18   作者:水痕01  
本文主要介绍了使用go-zero搭建微服务环境的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

一、go-zero微服务环境安装

1、go-zero脚手架的安装

go install github.com/zeromicro/go-zero/tools/goctl@latest

2、etcd的安装根据自己电脑操作系统下载对应的版本,具体的使用自己查阅文章

二、创建一个user-rpc服务

1、定义user.proto文件

syntax = "proto3";

package user;
option go_package="./user";


service User {
  rpc FindById(FindByIdReq) returns (FindByIdResp);
}

message FindByIdReq{
  int64 id = 1;
}

message FindByIdResp {
  int64 id = 1;
  string username = 2;
}

2、使用命令生成对应的项目文件

goctl rpc protoc ./user.proto --go_out=. --go-grpc_out=. --zrpc_out=./
goctl rpc protoc ./user.proto --go_out=./types --go-grpc_out=./types --zrpc_out=. --style goZero -m

3、安装对应的依赖包

go mod tidy

4、运行user服务

go run user.go

5、在etcd中查看服务是否已经注册成功

etcdctl get --prefix user.rpc

6、模拟业务代码返回数据

func (l *FindByIdLogic) FindById(in *user.FindByIdReq) (*user.FindByIdResp, error) {
	return &user.FindByIdResp{
		Id:       in.Id,
		Username: "哈哈哈",
	}, nil
}

7、使用apifox可以直接调用rpc的服务,引入文件

三、在提供restful api接口端调用rpc服务返回数据给前端

1、创建一个user-api的项目

2、创建描述文件

syntax = "v1"

type GetUserReq {
    Id int64 `path:"id"` // 主键id
}

type GetUserResp {
    Id int64 `json:"id"`              // 用户id
    Username string `json:"username"` // 用户名
}
@server(
    prefix: api/v1/user
    group: user
)
service user-api {
    @doc "根据用户id获取用户新"
    @handler GetUserByIdApi
    get /:id (GetUserReq) returns (GetUserResp)
}

3、使用脚本生成对应的项目文件

goctl api go -api *.api -dir . --style=gozero

4、在user-api的配置文件中引入rpc服务的配置

Name: user-api
Host: 0.0.0.0
Port: 8888
UserRpc:
  Etcd:
    Hosts:
      - 127.0.0.1:2379
    Key: user.rpc

5、在apps/user-api/internal/config/config.go创建服务的配置

type Config struct {
	rest.RestConf
	UserRpc zrpc.RpcClientConf
}

6、在apps/user-api/internal/svc/servicecontext.go依赖注入rpc服务

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)),
	}
}

7、模拟实现业务代码

func (l *GetUserByIdApiLogic) GetUserByIdApi(req *types.GetUserReq) (resp *types.GetUserResp, err error) {
	// 模拟业务开发
	findByIdResp, err := l.svcCtx.UserRpc.FindById(l.ctx, &user.FindByIdReq{
		Id: req.Id,
	})
	if err != nil {
		return &types.GetUserResp{}, errors.New("查询失败")
	}
	return &types.GetUserResp{
		Id:       findByIdResp.Id,
		Username: findByIdResp.Username,
	}, nil
}

8、直接浏览模拟请求http://localhost:8888/api/v1/user/1

四、实际项目中可能是多个微服务的引入

1、在go-zero项目的svc文件夹下创建一个rpcClient.go的文件

type RpcClient struct {
	config      config.Config
  // 服务1
	systemRpc   zrpc.Client
	systemMutex sync.Mutex
	// 服务2
	usersMutex sync.Mutex
	usersRpc   zrpc.Client
}
func NewRpcClient(c config.Config) *RpcClient {
	return &RpcClient{
		config: c,
	}
}
func (r *RpcClient) GetSystemRpc() system.ConfigServiceClient {
	r.systemMutex.Lock()
	defer r.systemMutex.Unlock()
	if r.systemRpc == nil {
		systemRpc, err := zrpc.NewClient(r.config.SystemRpc)
		if err != nil {
			logx.Errorf("new system rpc failed: %+v", err)
			return nil
		}
		r.systemRpc = systemRpc
	}
	return system.NewConfigServiceClient(r.systemRpc.Conn())
}
func (r *RpcClient) GetUsersRpc() users.UsersClient {
	r.usersMutex.Lock()
	defer r.usersMutex.Unlock()
	if r.usersRpc == nil {
		usersRpc, err := zrpc.NewClient(r.config.UsersRpc)
		if err != nil {
			logx.Errorf("new user rpc failed: %+v", err)
			return nil
		}
		r.usersRpc = usersRpc
	}
	return users.NewUsersClient(r.usersRpc.Conn())
}

2、在serviceContext.go文件中注入上面的rpcClient.go

type ServiceContext struct {
	Config    config.Config
	RpcClient *RpcClient
}
func NewServiceContext(c config.Config) *ServiceContext {
	rpcClient := NewRpcClient(c)
	if rpcClient == nil {
		logx.Errorf("new rpc client failed")
		panic(0)
	}
	return &ServiceContext{
		Config:    c,
		RpcClient: rpcClient,
	}
}

3、正常使用user服务的方法

到此这篇关于goZero微服务开发小结的文章就介绍到这了,更多相关goZero微服务内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Golang中多个线程和多个协程的使用区别小结

    Golang中多个线程和多个协程的使用区别小结

    本文主要介绍了Golang中多个线程和多个协程的使用区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-06-06
  • Go语言中包导入下划线的作用详细解析

    Go语言中包导入下划线的作用详细解析

    这篇文章主要介绍了Go语言中包导入下划线作用的相关资料,下划线导入可以帮助我们更好地管理初始化逻辑,减少代码的冗余,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-04-04
  • go语言实现依赖注入的示例代码

    go语言实现依赖注入的示例代码

    依赖注入和控制反转恰恰相反,它是一种具体的编码技巧,我们不通过 new 的方式在类内部创建依赖类的对象,而是将依赖的类对象在外部创建好之后,通过构造函数、函数参数等方式传递给类来使用,本文将给大家介绍go语言实现依赖注入,需要的朋友可以参考下
    2024-01-01
  • 基于HLS创建Golang视频流服务器的优缺点

    基于HLS创建Golang视频流服务器的优缺点

    HLS 是 HTTP Live Streaming 的缩写,是苹果开发的一种基于 HTTP 的自适应比特率流媒体传输协议。这篇文章主要介绍了基于 HLS 创建 Golang 视频流服务器,需要的朋友可以参考下
    2021-08-08
  • go实现for range迭代时修改值的操作

    go实现for range迭代时修改值的操作

    这篇文章主要介绍了go实现for range迭代时修改值的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • Go1.18 新特性之多模块Multi-Module工作区模式

    Go1.18 新特性之多模块Multi-Module工作区模式

    这篇文章主要介绍了Go1.18 新特性之多模块Multi-Module工作区模式,在 Go 1.18之前,建议使用依赖模块中的 replace 指令来处理这个问题,从 Go 1.18开始引入了一种同时处理多个模块的新方法,通过案例给大家详细介绍,感兴趣的朋友一起看看吧
    2022-04-04
  • Golang中 import cycle not allowed 问题的解决方法

    Golang中 import cycle not allowed 问题

    这篇文章主要介绍了Golang中 import cycle not allowed 问题的解决方法,问题从描述到解决都非常详细,需要的小伙伴可以参考一下
    2022-03-03
  • 重学Go语言之基础数据类型详解

    重学Go语言之基础数据类型详解

    Go语言有非常强大的数据类型系统,其支持的数据类型大体上可分为四类:基础数据类型、引用数据类型、接口类型、复合类型。本文就来讲讲它们各自的用法吧
    2023-02-02
  • golang常用加密解密算法总结(AES、DES、RSA、Sha1、MD5)

    golang常用加密解密算法总结(AES、DES、RSA、Sha1、MD5)

    在项目开发过程中,当操作一些用户的隐私信息,本文主要主要介绍了golang常用加密解密算法总结(AES、DES、RSA、Sha1MD5),文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • 基于Go语言轻松构建定时任务调度器的示例代码

    基于Go语言轻松构建定时任务调度器的示例代码

    Go 标准库 time 包提供了非常强大且简洁的支持,配合协程可轻松构建定时任务调度器,下面就跟随小编一起来了解下如何使用Go语言实现任务调度器可以定时执行任务吧
    2025-08-08

最新评论