微服务框架 go-zero 快速实战

news2024/11/16 10:43:36

对于咱们快速了解和将 go-zero 使用起来,我们需要具备如下能力

  • 基本的环境安装和看文档的能力
  • Golang 的基本知识
  • Protobuf 的基本知识
  • web,rpc 的基本知识
  • 基本的 mysql 知识

其实这些能力,很基础,不需要多么深入,只需要你有所了解,这样至少对于咱们去看 go-zero 涉及的知识点就不会那么费劲儿

本文分为如下 4 个部分来分别介绍和快速实战微服务框架 go-zero

  • 微服务框架 go-zero 的基本介绍
  • go-zero 的环境搭建
  • go-zero 的快速实战 rpc api ,model 部分

微服务框架 go-zero 的基本介绍

go-zero 是一个集成了各种工程实践的 web 和 rpc 框架。通过弹性设计保障了大并发服务端的稳定性,经受了充分的实战检验。

go-zero 中的 api,rpc,数据库等涉及的代码,都可以给我们一键生成,无需耗费我们什么精力

只需要在生成的代码中填入自己的配置以及逻辑即可,咱们使用 go-zero 可以轻松做到如下效果:

  • 轻松获得支撑千万日活服务的稳定性
  • 内建级联超时控制、限流、自适应熔断、自适应降载等微服务治理能力,无需配置和额外代码
  • 微服务治理中间件可无缝集成到其它现有框架使用
  • 极简的 API 描述,一键生成各端代码
  • 自动校验客户端请求参数合法性
  • 大量微服务治理和并发工具包

对于咱们开发微服务可谓是极大的提高了开发效率和质量,减少了开发者的心智负担

go-zero 官方提供了一张架构图

从架构图我们知道,上述的各种效果离不开架构图中的每一个模块,本文先展示如下功能的应用:

  • HTTP 协议
  • gRPC 协议
  • 日志记录
  • 链路追踪
  • 数据库
  • ETCD 服务发现

看到 go-zero 有这么多好处,架构图也非常清晰,是不是有点迫不及待了呢

go-zero 的环境搭建

不着急,工欲善其事必先利其器,咱们能将 go-zero 玩起来的先决条件是搭建基本的环境,为了接下来的实战做铺垫,咱们需要搭建如下几个工具

  • 有一台基本的云服务器最好,虚拟机也没有问题
  • 安装 etcd,mysql
  • 安装 protoc 工具
  • 安装 goctl 工具

安装 etcd,mysql

etcd

ETCD_VER=v3.5.0

# choose either URL
GOOGLE_URL=https://storage.googleapis.com/etcd
GITHUB_URL=https://github.com/etcd-io/etcd/releases/download
DOWNLOAD_URL=${GOOGLE_URL}

rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
rm -rf /tmp/etcd-download-test && mkdir -p /tmp/etcd-download-test

curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download-test --strip-components=1
rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz

/tmp/etcd-download-test/etcd --version
/tmp/etcd-download-test/etcdctl version
/tmp/etcd-download-test/etcdutl version

安装完毕后,可以使用 etcdctl version 查看工具的版本

如果想了解 etcd 的基本使用,咱们不着急,本次文章使用不多,无需太过关注 etcd 的细节

mysql

Linux(centos) 下 Mysql 环境安装

安装 protoc 工具

go get -u github.com/golang/protobuf/protoc-gen-go@v1.3.2
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.14.0/protoc-3.14.0-linux-x86_64.zip
unzip protoc-3.14.0-linux-x86_64.zip
mv bin/protoc /usr/local/bin/

安装完毕后,可以使用 protoc --version 查看工具的版本

安装 goctl 工具

goctl 读作 go control,不要读成 go C-T-Lgoctl 的意思是不要被代码控制,而是要去控制它。其中的 go 不是指 golang

安装咱们 golang 的时候,直接安装 go 1.16 版本以上的,然后执行如下命令即可

GOPROXY=https://goproxy.cn/,direct go install github.com/zeromicro/go-zero/tools/goctl@latest

安装完毕后,可以使用 goctl --version 查看工具的版本

go-zero 的快速实战

环境安装完毕之后,我们就可以来进行实战了,刚才有说到 go-zero 是一个集成了各种工程实践的 web 和 rpc 框架,那么我们就可以来设计 web 部分的接口和 rpc 部分的接口

需求

  1. 例如有一个订单场景,我们需要查询某个租户的地址
  1. 另外在租户系统这边,需要添加租户

这个时候,我们知道,对于用户来说,访问的自然是 http 接口,那对于查询具体的租户信息,自然是内部微服务来进行处理

一般来说,HTTP 接口对外, RPC 接口对内

正如这样

先来定义 rpc 接口

  1. 咱们先建立项目目录:
mkdir my_test_demo/mymall -p
cd my_test_demo
go mod init my_test_demo
  1. 创建租户的 rpc 模块
mkdir mymall/tenant/rpc -p
cd mymall/tenant/rpc
  1. 编写 proto 文件

提供两个 rpc 接口

  • getTenant

    • 获取租户信息
  • addTenant

    • 添加租户

tenant.proto

syntax = "proto3";

package tenant;

option go_package = "./tenant";

message TidReq {
    string name = 1;
}
message TenantRsp {
    // 租户名称
    string id = 1;
    // 租户名称
    string name = 2;
    // 用户地址
    string addr = 3;
}

message addTenantReq {
    // 租户名称
    string name = 1;
    // 用户地址
    string addr = 2;
}


message addTenantRsp {
    // 租户 id
    string id = 1;
}

service Tenant {
    rpc getTenant(TidReq) returns(TenantRsp);
    rpc addTenant(addTenantReq) returns(addTenantRsp);
}
  1. 使用 goctl 工具生成 golang 代码
goctl rpc protoc tenant.proto --go_out=./protoc --go-grpc_out=./protoc --zrpc_out=.

可以看到 goctl 工具给我们生成的代码目录是这样的

├── etc
│   └── tenant.yaml
├── internal
│   ├── config
│   │   └── config.go
│   ├── logic
│   │   ├── addtenantlogic.go
│   │   └── gettenantlogic.go
│   ├── server
│   │   └── tenantserver.go
│   └── svc
│       └── servicecontext.go
├── protoc
│   └── tenant
│       ├── tenant_grpc.pb.go
│       └── tenant.pb.go
├── tenant
│   └── tenant.go
├── tenant.go
└── tenant.proto

这个时候,关于 rpc 自动生成的部分就完成了

定义 api 接口

  1. 创建订单的 api 模块
回到项目根目录 my_test_demo
mkdir mymall/order/api -p
cd mymall/order/api
  1. 编写 api

定义一个 Get 方法,url 为 / api /order/get/:name 的 http 接口

order.api

type (
        OrderReq {
                Name string `path:"name"`
        }

        OrderReply {
                Id   string `json:"id"`
                Name string `json:"name"`
                Addr string `json:"addr"`
        }
)
service order {
        @handler getOrder
        get /api/order/get/:name (OrderReq) returns (OrderReply)
}
  1. 使用 goctl 工具生成代码
goctl api go -api order.api  -dir .

这个时候,我们可以看到,goctl 工具给我们生成的目录结构和代码是这个样子的

├── etc
│   └── order.yaml
├── internal
│   ├── config
│   │   └── config.go
│   ├── handler
│   │   ├── getorderhandler.go
│   │   └── routes.go
│   ├── logic
│   │   └── getorderlogic.go
│   ├── svc
│   │   └── servicecontext.go
│   └── types
│       └── types.go
├── order.api
└── order.go

同样的, web 部分自动生成的部分就完成了

数据库

  1. 创建 model 目录
回到项目根目录  my_test_demo
mkdir mymall/tenant/rpc/protoc/model -p
cd mymall/tenant/rpc/protoc/model
  1. 编写 sql
  • 先在 linux 里面进入 mysql,创建一个数据库 test_demo
  • 再创建一张表,表的字段如下面 sql 文件所述

tenant.sql

CREATE TABLE `tenant_info`
(
  `id` varchar(255) NOT NULL COMMENT 'tenant id',
  `name` varchar(255) NOT NULL COMMENT 'tenant name',
  `addr` varchar(255) NOT NULL COMMENT 'tenant addr',
  PRIMARY KEY(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  1. 向 数据表中插入一条数据,为后续做准备
insert into tenant_info values("ceshiid", "约等于公司", "修罗道哦");
  1. 使用 goctl 工具生成 model 部分的代码
goctl model mysql ddl -src tenant.sql -dir .

可以看到 goctl 给我们生成的 model 代码是这个样子的

├── tenantinfomodel_gen.go
├── tenantinfomodel.go
├── tenant.sql
└── vars.go

填充逻辑层和配置

  1. Api 部分
  • 修改 mymall/order/api/etc/order.yaml , 加上 etcd 的配置,咱们配置的 rpc 的 key 是 tenant.rpc
Name: order
Host: 0.0.0.0
Port: 9998
TenantRpc:
  Etcd:
    Hosts:
      - 127.0.0.1:2379
    Key: tenant.rpc
  • 修改 ymall/order/api/internal/config/config.go ,Config struct 中加上 rpc 的配置

    • TenantRpc zrpc.RpcClientConf

  • 修改 mymall/order/api/internal/svc/servicecontext.go ,加上 rpc 的上下文

    • TenantRpc tenant.Tenant
    • TenantRpc:tenant.NewTenant(zrpc.MustNewClient(c.TenantRpc)),

  • 修改 mymall/order/api/internal/logic/getorderlogic.go ,对逻辑层加上咱们自定义的逻辑,调用 rpc 的接口获取租户信息
func (l *GetOrderLogic) GetOrder(req *types.OrderReq) (resp *types.OrderReply, err error) {
   // todo: add your logic here and delete this line
rsp , err:=l.svcCtx.TenantRpc.GetTenant(l.ctx, &tenant.TidReq{Name: req.Name})
   if err != nil{
      return nil,err
   }
   return &types.OrderReply{
      Id: rsp.Id,
      Name: rsp.Name,
      Addr: rsp.Addr,
   },nil

}

  • 修改 mymall/order/api/internal/handler/getorderhandler.go ,去掉多导入的包

  1. Rpc 部分
  • 修改 mymall/tenant/rpc/etc/tenant.yaml ,加上数据源和数据表的配置
Name: tenant.rpc
ListenOn: 127.0.0.1:8080
Etcd:
  Hosts:
  - 127.0.0.1:2379
  Key: tenant.rpc

DataSource: root:123456@tcp(localhost:3306)/test_demo
Table: tenant_info
  • 修改 mymall/tenant/rpc/internal/config/config.go

    • DataSource string
    • Table string

  • 修改 mymall/tenant/rpc/internal/svc/servicecontext.go ,添加关于 mysql 的上下文

    • Model model.TenantInfoModel
    • Model:model.NewTenantInfoModel(sqlx.NewMysql(c.DataSource)),
  • 修改 mymall/tenant/rpc/protoc/model/tenantinfomodel_gen.go ,新增一个数据库的方法 FindOneByName (这个是根据业务自身来选择是否要加)

    • FindOneByName(ctx context.Context, name string) (*TenantInfo, error)

func (m *defaultTenantInfoModel) FindOneByName(ctx context.Context, name string) (*TenantInfo, error) {
   query := fmt.Sprintf("select %s from %s where `name` = ? limit 1", tenantInfoRows, m.table)
   var resp TenantInfo
   err := m.conn.QueryRowCtx(ctx, &resp, query, name)
   switch err {
   case nil:
      return &resp, nil
   case sqlc.ErrNotFound:
      return nil, ErrNotFound
   default:
      return nil, err
   }
}

  • 修改 mymall/tenant/rpc/internal/logic/gettenantlogic.go 填充 GetTenant 的逻辑

效果验证

  1. 打开终端 1 操作 rpc
cd mymall/tenant/rpc
go mod tidy
go run tenant.go
  1. 打开终端 2 操作 api
cd mymall/order/api
go run order.go
  1. 打开终端 3 操作 curl

我们可以先使用 etcdctl 查看一下 tenant.rpc 是否存在

etcdctl get tenant.rpc --prefix

再使用 curl 来请求 api 的接口

curl -i "http://localhost:9998/api/order/get/约等于公司"

Api 的日志为

Rpc 的日志

通过上述日志我们知道,对于 api 的请求日志,mysql 的日志,rpc 的日志,咱们都能看到 trace 这个字段,实际上就是通过这个字段来进行链路跟踪的,细心的朋友就可以看到,从 api,到 rpc,到 mysql 这个 trace 字段的值都是同一个, 说明这是同一条调用链上的

其他的细节,咱们后续再聊

总结

至此,我们了解了 go-zero 微服务框架,快速实战了一个简单的 demo,这里我们实际可以体验到,关于 api,rpc ,或者是 model 层,绝大部分的代码都是 goctl 生成的,我们需要的就如下几件事

  1. 基本 api ,proto ,sql 的定义
  1. 修改 xml 配置 , 和 config.go 的配置
  1. 修改 svc 下面的关联上下线文
  1. 修改 logic 层,填上自己的逻辑
  1. 如果对于数据库生成默认的方法,不够满足业务场景,我们也可以依葫芦画瓢实现自己的方法,进行使用即可

另外,我们看到咱们定义的 proto 还有一个 addTenant 方法,实际上我们去实现的话,可以在 mymall/tenant 下添加 api 目录,按照上述 api 的添加方式来进行处理即可,感兴趣的朋友可以来尝试一波哦

如果想看源码的,欢迎访问地址:https://github.com/qingconglaixueit/my_test_Demo

感谢阅读,欢迎交流,点个赞,关注一波 再走吧

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~
可以进入地址进行体验和学习:https://xxetb.xet.tech/s/3lucCI

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/929435.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MAE 论文精读 | 在CV领域自监督的Bert思想

1. 背景 之前我们了解了VIT和transformer MAE 是基于VIT的,不过像BERT探索了自监督学习在NLP领域的transformer架构的应用,MAE探索了自监督学习在CV的transformer的应用 论文标题中的Auto就是说标号来自于图片本身,暗示了这种无监督的学习 …

15 html简介

文章目录 html 概述和基本结构html概述html的基本结构HTML 文档类型xhtml 1.0 (html4)html5 两种文档的区别html 注释 html标签介绍html 标题标签html 段落标签、换行标签与字符实体html 段落标签html 换行标签html 字符实体 html 块标签、含样式的标签h…

28- .sync修饰符:父子双向绑定

作用: 可以实现 子组件 与 父组件数据 的 双向绑定,简化代码 特点: prop属性名,可以自定义,非固定为 value 场景: 封装弹框类的基础组件,visible属性 true显示 false隐藏 本质: 就是 :属性名 和 update:属性名 合写

打开软件提示msvcp140.dll丢失的解决方法,msvcp140主要丢失原因

今天,我将为大家介绍一种非常常见的问题——msvcp140.dll丢失。这个问题可能会导致许多应用程序无法正常运行,甚至崩溃。但是,请不要担心,我会为大家提供5种解决方法,帮助大家轻松解决问题。 首先,我们来看…

Android 13 - Media框架(8)- MediaExtractor

上一篇我们了解了 GenericSource 需要依赖 IMediaExtractor 完成 demux 工作,这一篇我们就来学习 android media 框架中的第二个服务 media.extractor,看看 IMediaExtractor 是如何创建与工作的。 1、MediaExtractorService media.extractor 和 media.p…

【ArcGIS微课1000例】0071:普通最小二乘法 (OLS)回归分析案例

严重声明:本文来自专栏《ArcGIS微课1000例:从点滴到精通》,为CSDN博客专家刘一哥GIS原创,原文及专栏地址为:(https://blog.csdn.net/lucky51222/category_11121281.html),谢绝转载或爬取!!! 文章目录 一、空间自回归模型二、ArcGIS普通最小二乘法回归(OLS)一、空间自…

企业ADManager Plus软件的使用案例

引言: 在当今数字化时代,企业的活动主要依赖于信息技术和计算机系统。作为关键的IT基础架构组件之一,Active Directory(AD)在维护和管理用户、计算机和资源方面发挥着关键作用。AD的高效管理对于确保企业的平稳运行至…

HDFS 集群读写压测

文章目录 虚拟机设置HDFS 写数据测试HDFS 读数据测试删除压测产生的数据 虚拟机设置 如果你是在虚拟机中使用集群,那你你需要先对每台服务器进行网络设置,模拟真实网络传输速率。 如下所示: 将其设置为百兆网,每台服务器都要进行…

基于Android的课程教学互动系统 微信小程序uniapp

教学互动是学校针对学生必不可少的一个部分。在学校发展的整个过程中,教学互动担负着最重要的角色。为满足如今日益复杂的管理需求,各类教学互动程序也在不断改进。本课题所设计的springboot基于Android的教学互动系统,使用SpringBoot框架&am…

云计算存储类型

一、共享存储模式 NAS: ①一种专门用于存储和共享文件的设备,它通过网络连接到计算机或其他设备, 提供了一个中心化的存储解决方案 ②存储网络使用IP网络 ,数据存储共享基于文件 ③本质上为:NFS和CIFS文件共享服务器 ④提供的不是一个磁盘块…

uniapp结合Canvas+renderjs根据经纬度绘制轨迹(二)

uniapp结合Canvasrenderjs根据经纬度绘制轨迹 文章目录 uniapp结合Canvasrenderjs根据经纬度绘制轨迹效果图templaterenderjsjs数据结构 ​ 根据官方建议要想在 app-vue 流畅使用 Canvas 动画,需要使用 renderjs 技术,把操作canvas的js逻辑放到视图层运…

优化物料编码规则,提升物料管理效率

导 读 ( 文/ 2358 ) 物料是生产过程的必需品。对物料进行身份的唯一标识,可以更好的管理物料库存、库位,更方便的对物料进行追溯。通过编码规则的设计,可以对物料按照不同的属性、类别或特征进行分类,从而更好地进行库存分析、计划…

win10 maven 安装环境变量设置不成功

maven 按照正常步骤设置环境变量 输入命令总是不能正常现实mvn的版本 解决方案: 1.删除掉设置的用户环境变量 2.将maven的完整目录写入系统变量path中 3.将该路径放到所有变量的最前面 4.点击确定,重新打开cmd 输入 mvn -v 正常了

C语言刷题指南(四)

📙作者简介: 清水加冰,目前大二在读,正在学习C/C、Python、操作系统、数据库等。 📘相关专栏:C语言初阶、C语言进阶、C语言刷题训练营、数据结构刷题训练营、有感兴趣的可以看一看。 欢迎点赞 &#x1f44d…

摆动序列【贪心算法】

摆动序列 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。 class Solution {public int wiggleMaxLength(int…

Windows下 MySql通过拷贝data目录迁移数据库的方法

MySQL数据库的文件目录下图所示, 现举例说明通过COPY文件夹data下数据库文件,进行数据拷贝的步骤;源数据库运行在A服务器上,拷贝到B服务器,假定B服务器上MySQL数据库已经安装完成,为空数据库。 首先进入A服…

Java 程序打印 OpenCV 的版本

我们可以使用 Java 程序来使用 OpenCV。 OpenCV 的使用需要动态库的加载才可以。 加载动态库 到 OpenCV 的官方网站上下载最新的发布版本。 Windows 下载的是一个可执行文件,没关系,这个可执行文件是一个自解压程序。 当你运行以后会提示你进行解压。…

百度“AI智障”到AI智能体验之旅

目录 前言一、百度PLATO1.抬杠第一名2.听Ta瞎扯淡3.TA当场去世了4.智障与网友的高光时刻 二、文心一言1.设计测试用例2.随意发问3.手机端约会神器 三、体验总结:四、千帆大模型 前言 最近收到了文心一言3.5大模型的内测资格,正巧之前也体验过它的前身&q…

分析系统 - 使用Python爬虫

在竞争激烈的市场环境中,了解和分析竞争对手的销售策略和市场表现对于企业的成功至关重要。本文将介绍如何利用Python爬虫建立低成本的销售竞争对手分析系统,探索其方法、工具和好处,并同时解决可能出现的问题。 销售竞争对手分析的目标是获取…

PyTorch 模型性能分析和优化 - 第 2 部分

动动发财的小手,点个赞吧! 这是有关分析和优化在 GPU 上运行的 PyTorch 模型主题的系列文章的第二部分。在第一篇文章中,我们演示了使用 PyTorch Profiler 和 TensorBoard 迭代分析和优化 PyTorch 模型的过程以及巨大潜力。在这篇文章中&…