Go - Zero 快速构建高并发微服务

Go - Zero基本架构图

准备工作

  • 安装 etcd, mysql, redis

    go 
    
    # etcd(这个本人之前装的比较少, 所以下面会贴出安装步骤, 仅供参考, 自行谷歌)
    curl -L https://github.com/coreos/etcd/releases/download/v3.2.1/etcd-v3.2.1-linux-amd64.tar.gz -o etcd-v3.2.1-linux-amd64.tar.gz
    tar xzvf etcd-v3.2.1-linux-amd64.tar.gz
    mv etcd-v3.2.1-linux-amd64 etcd
    cd etcd
    
    $ ./etcd --version
    etcd Version: 3.2.1
    Git SHA: 61fc123
    Go Version: go1.8.3
    Go OS/Arch: linux/amd64
    
    # mysql, redis(这两个比较常见,下面仅贴出启动步骤)
    sudo service mysql start
    sudo service redis-server start
  • 安装 protoc-gen-go

    go get -u github.com/golang/protobuf/protoc-gen-go@v1.3.2
  • 安装 protoc

    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
    sudo cp bin/protoc /usr/local/bin/
    sudo chmod 777 /usr/local/bin/protoc
    
    $ protoc --version                         
    libprotoc 3.14.0
  • 安装 goctl 工具

    GO111MODULE=on GOPROXY=https://goproxy.cn/,direct go get -u github.com/zeromicro/go-zero/tools/goctl@latest
  • 创建工作目录 shorturlshorturl/api

    mkdir -p shorturl/api && cd shorturl && go mod init shorturl
    
    vi go.mod
    module shorturl
    
    go 1.17
    
    require (
      github.com/golang/mock v1.4.3
      github.com/golang/protobuf v1.4.2
      github.com/zeromicro/go-zero v1.3.0
      golang.org/x/net v0.0.0-20200707034311-ab3426394381
      google.golang.org/grpc v1.29.1
    )
    go get github.com/golang/mock@v1.4.3
    go get github.com/golang/protobuf@v1.4.2
    go get github.com/zeromicro/go-zero@v1.3.0
    go get golang.org/x/net@v0.0.0-20200707034311-ab3426394381
    go get google.golang.org/grpc@v1.29.1

编写 API Gateway 代码

  • 通过 goctl 生成 api/shorturl.api

    $ cd api && goctl api -o shorturl.api                                                             
    // shorturl.api
    type (
      expandReq {
        shorten string `form:"shorten"`
      }
    
      expandResp {
        url string `json:"url"`
      }
    )
    
    type (
      shortenReq {
        url string `form:"url"`
      }
    
      shortenResp {
        shorten string `json:"shorten"`
      }
    )
    
    service shorturl-api {
      @server(
        handler: ShortenHandler
      )
      get /shorten(shortenReq) returns(shortenResp)
    
      @server(
        handler: ExpandHandler
      )
      get /expand(expandReq) returns(expandResp)
    }
    
    
    // service shorturl-api { 这一行定义了 service 名字
    // @server 部分用来定义 server 端用到的属性
    // handler 定义了服务端 handler 名字
    // get /shorten(shortenReq) returns(shortenResp) 定义了 get 方法的路由、请求参数、返回参数等
  • 使用 goctl 生成 API Gateway 代码

    goctl api go -api shorturl.api -dir .
    tree
    .
    ├── etc
    │   └── shorturl-api.yaml           // 配置文件
    ├── go.mod
    ├── internal
    │   ├── config
    │   │   └── config.go               // 定义配置
    │   ├── handler
    │   │   ├── expandhandler.go        // 实现 expandHandler
    │   │   ├── routes.go               // 定义路由处理
    │   │   └── shortenhandler.go       // 实现 shortenHandler
    │   ├── logic
    │   │   ├── expandlogic.go          // 实现 ExpandLogic
    │   │   └── shortenlogic.go         // 实现 ShortenLogic
    │   ├── svc
    │   │   └── servicecontext.go       // 定义 ServiceContext
    │   └── types
    │       └── types.go                // 定义请求、返回结构体
    ├── shorturl.api
    └── shorturl.go                     // main 入口定义
  • 启动 API Gateway 服务,默认侦听在 8888 端口

    $ go run shorturl.go -f etc/shorturl-api.yaml
    Starting server at 0.0.0.0:8888...
  • 测试 API Gateway 服务

    $ curl -i "http://localhost:8888/shorten?url=test"                    
    HTTP/1.1 200 OK
    Content-Type: application/json; charset=utf-8
    Traceparent: 00-4ef62e5d271bfe067ff8226f6c88ecd2-c08acfe02ba1abf1-00
    Date: Sun, 13 Oct 2022 09:12:58 GMT
    Content-Length: 4
    
    null

编写 transform rpc 服务(实现业务逻辑)

# 创建transform.proto文件
mkdir -p rpc/transform && cd rpc/transform && goctl rpc template -o transform.proto
// transform.proto
syntax = "proto3";

package transform;

option go_package = "./transform";

message expandReq{
  string shorten = 1;
}

message expandResp{
  string url = 1;
}

message shortenReq{
  string url = 1;
}

message shortenResp{
  string shorten = 1;
}

service  transformer{
  rpc expand(expandReq) returns(expandResp);
  rpc shorten(shortenReq) returns(shortenResp);
}
# 用 goctl 生成 rpc 代码,在 rpc/transform 目录下执行命令
goctl rpc protoc transform.proto --go_out=. --go-grpc_out=. --zrpc_out=.
# rpc目录结构
transform
├── etc
│   └── transform.yaml              // 配置文件
├── internal
│   ├── config
│   │   └── config.go               // 配置定义
│   ├── logic
│   │   ├── expandlogic.go          // expand 业务逻辑在这里实现
│   │   └── shortenlogic.go         // shorten 业务逻辑在这里实现
│   ├── server
│   │   └── transformerserver.go    // 调用入口, 不需要修改
│   └── svc
│       └── servicecontext.go       // 定义 ServiceContext,传递依赖
├── transform
│   ├── transform_grpc.pb.go
│   └── transform.pb.go
├── transformer
│   └── transformer.go              // 提供了外部调用方法,无需修改
├── transform.go                    // rpc 服务 main 函数
└── transform.proto
# 直接运行
$ go run transform.go -f etc/transform.yaml

不知名公司IT从业者一枚

19 声望
1 粉丝
0 条评论
推荐阅读
Nginx - 上手到精通(持续更新中)
简介 {代码...} 架构由内核 和 一系列模块组成内核 {代码...} 模块 {代码...} 安装 {代码...} 守护进程 {代码...} 优化主要通过设置/etc/nginx/nginx.conf来实现顶层配置 {代码...} events配置 {代码...} http配...

BewaterMyfriends阅读 412

前端如何入门 Go 语言
类比法是一种学习方法,它是通过将新知识与已知知识进行比较,从而加深对新知识的理解。在学习 Go 语言的过程中,我发现,通过类比已有的前端知识,可以更好地理解 Go 语言的特性。

robin23阅读 3.3k评论 6

封面图
Golang 中 []byte 与 string 转换
string 类型和 []byte 类型是我们编程时最常使用到的数据结构。本文将探讨两者之间的转换方式,通过分析它们之间的内在联系来拨开迷雾。

机器铃砍菜刀24阅读 58.3k评论 2

年度最佳【golang】map详解
这篇文章主要讲 map 的赋值、删除、查询、扩容的具体执行过程,仍然是从底层的角度展开。结合源码,看完本文一定会彻底明白 map 底层原理。

去去100216阅读 11.6k评论 2

年度最佳【golang】GMP调度详解
Golang最大的特色可以说是协程(goroutine)了, 协程让本来很复杂的异步编程变得简单, 让程序员不再需要面对回调地狱, 虽然现在引入了协程的语言越来越多, 但go中的协程仍然是实现的是最彻底的. 这篇文章将通过分析...

去去100215阅读 12k评论 4

万字详解,吃透 MongoDB!
MongoDB 是一个基于 分布式文件存储 的开源 NoSQL 数据库系统,由 C++ 编写的。MongoDB 提供了 面向文档 的存储方式,操作起来比较简单和容易,支持“无模式”的数据建模,可以存储比较复杂的数据类型,是一款非常...

JavaGuide8阅读 1.7k

封面图
数据结构与算法:二分查找
一、常见数据结构简单数据结构(必须理解和掌握)有序数据结构:栈、队列、链表。有序数据结构省空间(储存空间小)无序数据结构:集合、字典、散列表,无序数据结构省时间(读取时间快)复杂数据结构树、 堆图二...

白鲸鱼9阅读 5.3k

不知名公司IT从业者一枚

19 声望
1 粉丝
宣传栏