扫码订阅《 Go语言微服务框架学习实践》或入驻星球,即可阅读文章!

GOLANG ROADMAP · 知识星球

阅读模式

  • 沉浸
  • 自动
  • 日常
首页
Go路线图
  • 👶 初级要求:负责一个模块

    • 📗 薪资·10-15k 技能梳理
  • 🧑 中高级要求:负责一个方向

    • 📘 薪资·15-25k 技能梳理
  • 🧔 资深要求:负责一个领域

    • 📒 薪资·25-40k 技能梳理
  • 🧙 专家要求:负责多个领域

    • 📕 薪资·40k以上 技能梳理
Go学院
  • Go小课
  • Go小考
  • Go宝典
Go资源
  • 推荐资源

    • 优质课程
    • 推荐图书
    • 开源项目
  • 资源下载

    • 视频资源
    • 文档资源
    • 帮找资源
Go求职
  • 求职刷题

    • 企业题库
    • 面试宝典
    • 求职面经
  • 求职服务

    • 内推互助
    • 求职助力
    • 内推公司
推广返佣
  • 返佣排行
  • 返佣规则
  • 推广学院
更多
  • 用户中心

    • 我的信息
    • 我的消息
    • 我的返佣
author-avatar

GOLANG ROADMAP


首页
Go路线图
  • 👶 初级要求:负责一个模块

    • 📗 薪资·10-15k 技能梳理
  • 🧑 中高级要求:负责一个方向

    • 📘 薪资·15-25k 技能梳理
  • 🧔 资深要求:负责一个领域

    • 📒 薪资·25-40k 技能梳理
  • 🧙 专家要求:负责多个领域

    • 📕 薪资·40k以上 技能梳理
Go学院
  • Go小课
  • Go小考
  • Go宝典
Go资源
  • 推荐资源

    • 优质课程
    • 推荐图书
    • 开源项目
  • 资源下载

    • 视频资源
    • 文档资源
    • 帮找资源
Go求职
  • 求职刷题

    • 企业题库
    • 面试宝典
    • 求职面经
  • 求职服务

    • 内推互助
    • 求职助力
    • 内推公司
推广返佣
  • 返佣排行
  • 返佣规则
  • 推广学院
更多
  • 用户中心

    • 我的信息
    • 我的消息
    • 我的返佣
  • 《Go语言微服务框架学习实践》

    • 课程介绍
  • RPC远程调用机制

  • gRPC微服务框架

    • 第1节:gRPC介绍和安装
    • 第2节:gRPC框架使用
    • 第3节:gRPC调用
    • 第4节:TLS验证和Token认证
    • 第5节:拦截器的使用
  • go-micro微服务框架

扫码订阅《 Go语言微服务框架学习实践》或入驻星球,即可阅读文章!

第2节:gRPC框架使用


GOLANG ROADMAP

上节课已经学习了gRPC基本知识,对gRPC有了初步的认识。本节课通过编程实现gRPC编程。

# 定义服务

我们想要实现的是通过gRPC框架进行远程服务调用,首先第一步应该是要有服务。利用之前所掌握的内容,gRPC框架支持对服务的定义和生成。 gRPC框架默认使用protocol buffers作为接口定义语言,用于描述网络传输消息结构。除此之外,还可以使用protobuf定义服务接口。

syntax = "proto3";
package message;

//订单请求参数
message OrderRequest {
    string orderId = 1;
    int64 timeStamp = 2;
}

//订单信息
message OrderInfo {
    string OrderId = 1;
    string OrderName = 2;
    string OrderStatus = 3;
}

//订单服务service定义
service OrderService{
    rpc GetOrderInfo(OrderRequest) returns (OrderInfo);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

我们通过proto文件定义了数据结构的同时,还定义了要实现的服务接口,GetOrderInfo即是具体服务接口的定义,在GetOrderInfo接口定义中,OrderRequest表示是请求传递的参数,OrderInfo表示处理结果返回数据参数。

# 编译.proto文件

# 环境准备

定义的proto文件需要通过编译,生成go语言代码文件,供客户端程序和服务端程序使用。可以安装go语言环境中的关于proto的插件。

go get -a github.com/golang/protobuf/protoc-gen-go
1

-a 参数标示下载好后直接做 go install

# 编译.proto文件

# 基本用法

可以通过基本编译命令完成对.proto文件的编译.基础编译命令如下:

protoc --go_out=. *.proto
1

# gRPC编译支持

如果定义的.proto文件,如本案例中所示,定义中包含了服务接口的定义,而我们想要使用gRPC框架实现RPC调用。开发者可以采用protocol-gen-go库提供的插件编译功能,生成兼容gRPC框架的golang语言代码。只需要在基本编译命令的基础上,指定插件的参数,告知protoc编译器即可。具体的编译生成兼容gRPC框架的服务代码的命令如下:

protoc --go_out=plugins=grpc:. *.proto
1

# gRPC实现RPC编程

# 服务接口实现

在.proto定义好服务接口并生成对应的go语言文件后,需要对服务接口做具体的实现。定义服务接口具体由OrderServiceImpl进行实现,并实现GetOrderInfo详细内容,服务实现逻辑与前文所述内容相同。不同点是服务接口参数的变化。详细代码实现如下:

type OrderServiceImpl struct {
}

//具体的方法实现
func (os *OrderServiceImpl) GetOrderInfo(ctx context.Context, request *message.OrderRequest) (*message.OrderInfo, error) {
    orderMap := map[string]message.OrderInfo{
        "201907300001": message.OrderInfo{OrderId: "201907300001", OrderName: "衣服", OrderStatus: "已付款"},
        "201907310001": message.OrderInfo{OrderId: "201907310001", OrderName: "零食", OrderStatus: "已付款"},
        "201907310002": message.OrderInfo{OrderId: "201907310002", OrderName: "食品", OrderStatus: "未付款"},
    }

    var response *message.OrderInfo
    current := time.Now().Unix()
    if (request.TimeStamp > current) {
        *response = message.OrderInfo{OrderId: "0", OrderName: "", OrderStatus: "订单信息异常"}
    } else {
        result := orderMap[request.OrderId]
        if result.OrderId != "" {
            fmt.Println(result)
            return &result, nil
        } else {
            return nil, errors.New("server error")
        }
    }
    return response, nil
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# gRPC实现服务端

使用gRPC框架,首先实现服务端的程序。既然使用gRPC框架来实现,就需要调用gRPC进行服务方法的注册以及监听的处理。服务注册和监听处理实现如下:

func main() {

    server := grpc.NewServer()

    message.RegisterOrderServiceServer(server, new(OrderServiceImpl))

    lis, err := net.Listen("tcp", ":8090")
    if err != nil {
        panic(err.Error())
    }
    server.Serve(lis)
}
1
2
3
4
5
6
7
8
9
10
11
12

# gRPC实现客户端

实现完服务端以后,实现客户端程序。和服务端程序关系对应,调用gRPC框架的方法获取相应的客户端程序,并实现服务的调用,具体编程实现如下:

func main() {

    //1、Dail连接
    conn, err := grpc.Dial("localhost:8090", grpc.WithInsecure())
    if err != nil {
        panic(err.Error())
    }
    defer conn.Close()

    orderServiceClient := message.NewOrderServiceClient(conn)

    orderRequest := &message.OrderRequest{OrderId: "201907300001", TimeStamp: time.Now().Unix()}
    orderInfo, err := orderServiceClient.GetOrderInfo(context.Background(), orderRequest)
    if orderInfo != nil {
        fmt.Println(orderInfo.GetOrderId())
        fmt.Println(orderInfo.GetOrderName())
        fmt.Println(orderInfo.GetOrderStatus())
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 运行程序

经过上述步骤后,程序及逻辑全部开发完成。程序运行,打印如下结果:

201907300001
衣服
已付款
1
2
3
  • 定义服务
  • 编译.proto文件
  • 环境准备
  • 编译.proto文件
  • gRPC实现RPC编程
  • 运行程序