前言

在学习 gRPC 之前,先学习 protobufu 协议,简单的来理解,我们可以使用他来定义 消息服务。然后你只需要实现服务即可,剩下的东西,gRPC 会帮你自动完成。

protobufu 协议

protobuf 协议,可以适用于十几种开发语言,并且允许你使用同一种框架,每秒支持百万级以上的 RPC 调用

mac 中安装 gRPC 需要的环境

方法和 linux 中安装 gRPC 基本一样

cd ~/software/protobuf            #创建一个 software 文件,当时你也可以按照自己的习惯,放到 usr 文件夹中。

wget https://github.com/protocolbuffers/protobuf/releases/download/v3.12.0/protoc-3.12.0-osx-x86_64.zip   # 在下载 grpc 的安装包
unzip protoc-3.12.0-osx-x86_64.zip # 解压安装包 mv bin/protoc /usr/local/protoc # 通过将 bin 文件放到 protoc 中的方法,将 protoc 命令添加到 path 中

查看 protoc 的版本信息

protoc --version

# 输出 libprotoc 3.7.1

上面安装步骤完成以后,只是安装了 protobuf 的基础功能包。我们想要使用 go 语言中的 gprc 功能,还需要安装 grpc的包。

在任意的有mod 的文件下,执行如下命令

go get google.golang.org/grpc

如果想对此包做更多理解,可以查询 gPRC 的中文官方文档: http://doc.oschina.net/grpc?t=60133

编辑器

我一直比较喜欢使用 vscore。使用 vscore 编写 protobuf 文件,需要安装两个插件支持,用于格式化 protobuf 文件

  1. vscode-proto3

  1. Clang-Format

一个小 demo

通过 grpc 协议,定义一个客户端,实现以下两个功能,并使用 grpc 的 client 端来调用

  1. 添加产品

  2. 根据产品 id 来查询产品信息

定义一个能添加产品和查询产品的 protobuf 文件

syntax = "proto3";

package ecommerce;

option go_package="./econFileName"; // 文件名和包名,此两个文件保持一致

service ProductInfo {
rpc addProduct(Product) returns (ProductID);
rpc getProduct(ProductID) returns (Product);
} message Product {
string id = 1;
string name = 2;
string description = 3;
float price = 4;
} message ProductID {
string value = 1;
}

在声明 protobuf 的文件夹下,执行如下命令,会自动生成对应的 go 文件,切记,此文件只能查看,不可更改

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

服务端

1. 找到自动生成的 go 文件中 grpc 服务端的接口

打开自动生成的 go 文件,可以看到 server 接口。注意和客户端的接口区分,此处是 Server 结尾的

2. 重载此接口

根据 go 语言非入侵的接口实现方式,声明一个结构体,只要实现了某接口的所有方法,那么他就实现了这个接口

type server struct {
products []*pb.Product
} func (s *server) AddProduct(ctx context.Context, product *pb.Product) (*pb.ProductID, error) {
product.Id = uuid.New().String()
s.products = append(s.products, product)
return &pb.ProductID{
Value: product.Id,
}, status.New(codes.OK, "").Err()
}
func (s *server) GetProduct(ctx context.Context, proId *pb.ProductID) (*pb.Product, error) {
for _, prod := range s.products {
if prod.Id == proId.Value {
return prod, status.New(codes.OK, "").Err()
}
}
return nil, status.Errorf(codes.NotFound, "product not exist", proId.Value)
}

3.启动服务,监听 5001 端口

package main

import (
"context"
"fmt"
"net"
pb "zhao/grpc/pb/econFileName" "github.com/google/uuid"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
) const (
port = ":5001"
) type server struct {
products []*pb.Product
} func (s *server) AddProduct(ctx context.Context, product *pb.Product) (*pb.ProductID, error) {
product.Id = uuid.New().String()
s.products = append(s.products, product)
return &pb.ProductID{
Value: product.Id,
}, status.New(codes.OK, "").Err()
}
func (s *server) GetProduct(ctx context.Context, proId *pb.ProductID) (*pb.Product, error) {
for _, prod := range s.products {
if prod.Id == proId.Value {
return prod, status.New(codes.OK, "").Err()
}
}
return nil, status.Errorf(codes.NotFound, "product not exist", proId.Value)
} func main() {
lis, err := net.Listen("tcp", port)
if err != nil {
panic(err)
}
fmt.Printf("net service is starting at :%s\n", port)
s := grpc.NewServer()
pb.RegisterProductInfoServer(s, &server{})
if err = s.Serve(lis); err != nil {
panic(fmt.Sprintf("tpc web service port:【%s】 launch fail %v", port, err))
}
}
  1. 注意,grpc 方法的传入和传出,都是结构体,即使是 productId 这种简单的 string 类型的形参,也应该使用自动生成的 proto.go 文件中定义好的结构体

  2. grpc 的方法调用中,也会有状态码,使用 google.golang.org/grpc/codes 包引用

完整代码如下

package main

import (
"context"
"fmt"
"time"
pb "zhao/grpc/pb/econFileName" "google.golang.org/grpc"
) const (
address = "localhost:5001"
) func main() {
conn, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil {
fmt.Printf("connect grpc service fail at %s", address)
}
defer conn.Close()
client := pb.NewProductInfoClient(conn) // 要添加的产品
product1 := pb.Product{
Name: "Apple iPhone 11",
Description: "Meet Apple iPhone 11. All-new dual-camera system with Ultra Wide and Night mode.",
Price: float32(699.00),
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel() // 添加产品
id, err := client.AddProduct(ctx, &product1)
if err != nil {
fmt.Printf("client productid [%s] add product fail err: %v\n", product1.Id, err)
}
fmt.Printf("grpc req response product id [%s]\n", id.Value) // 查询产品
req_id := pb.ProductID{Value: id.Value}
res, err := client.GetProduct(ctx, &req_id)
if err != nil {
fmt.Printf("client get product fail id is %s\n", req_id.Value)
}
fmt.Printf("get product successful %s\n", res.String())
}

客户端

1. 声明连接使用的字符串

conn, err := grpc.Dial("localhost:5001", grpc.WithInsecure())

2.使用自动生成的 go 文件中的方法,创建 productInfo 对应的是实例

client := pb.NewProductInfoClient(conn)

3. 此时,你就可以拿着这个客户端实例,像本地方法调用一样使用远端方法了

res, err := client.GetProduct(ctx, &req_id)

完整代码如下

package main

import (
"context"
"fmt"
"time"
pb "zhao/grpc/pb/econFileName" "google.golang.org/grpc"
) const (
address = "localhost:5001"
) func main() {
conn, err := grpc.Dial("localhost:5001", grpc.WithInsecure())
if err != nil {
fmt.Printf("connect grpc service fail at %s", address)
}
defer conn.Close()
client := pb.NewProductInfoClient(conn)
product1 := pb.Product{
Name: "Apple iPhone 11",
Description: "Meet Apple iPhone 11. All-new dual-camera system with Ultra Wide and Night mode.",
Price: float32(699.00),
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel() // 添加产品
id, err := client.AddProduct(ctx, &product1)
if err != nil {
fmt.Printf("client productid [%s] add product fail err: %v\n", product1.Id, err)
}
fmt.Printf("grpc req response product id [%s]\n", id.Value) // 查询产品
req_id := pb.ProductID{Value: id.Value}
res, err := client.GetProduct(ctx, &req_id)
if err != nil {
fmt.Printf("client get product fail id is %s\n", req_id.Value)
}
fmt.Printf("get product successful %s\n", res.String())
}

源码地址 https://github.com/rushPeng/grpc_product_demo

gRPC 入门(一)的更多相关文章

  1. grpc入门(三)

    grpc入门(三) 一.介绍 本文是关于grpc的第三篇博文,是对前两篇博文的具体代码实现,秉着个人一贯的风格,没有太多抒情和总结,直接就上代码. 文章代码参考:https://github.com/ ...

  2. Go 中的 gRPC 入门详解

    目录 Go GRPC 入门 1,安装包 2,gRPC 服务端 3,gRPC 客户端 4,编译运行 5,其它 GRPC Protobuf buffer 字段类型 字段规则 Protobuf gRPC 四 ...

  3. 微服务架构攀登之路(三)之gRPC入门

    一.gRPC入门 1. gRPC 简介 gRPC 由 google 开发,是一款语言中立.平台中立.开源的远程过程调用系统 gRPC 客户端和服务端可以在多种环境中运行和交互,例如用 java 写一个 ...

  4. ASP.NET Core gRPC 入门全家桶

    一. 说明 本全家桶现在只包含了入门级别的资料,实战资料更新中. 二.官方文档 gRPC in Asp.Net Core :官方文档 gRPC 官网:点我跳转 三.入门全家桶 正片: ASP.NET ...

  5. Go GRPC 入门(一)

    前言 微服务相关 使用 GRPC 通讯的 Golang 微服务入门 举例写一个微服务,接收网址发送请求获取返回结果返回 正文 安装工具 安装 protobuf 这是 proto 文件的编译器 点我下载 ...

  6. 跟我一起学Go系列:gRPC 入门必备

    RPC 的定义这里就不再说,看文章的同学都是成熟的开发.gRPC 是 Google 开源的高性能跨语言的 RPC 方案,该框架的作者 Louis Ryan 阐述了设计这款框架的动机,有兴趣的同学可以看 ...

  7. gRPC入门—golang实现

    1.RPC 1.1 什么是RPC RPC(Remote Procedure Call),即远程过程调用,过程就是方法,简单来说,它就是一种能够像调用本地方法一样调用远程计算机进程中的方法的技术,在这种 ...

  8. grpc 入门(一)--hello world

    一,从rpc接口的定义说起,下面给一个最简单的grpc示例--hello world 在这个rpc横行的世界里,实现一个rpc很重要的一件事就是定义一个好接口,一个好的接口定义会让你省去很多麻烦.熟悉 ...

  9. grpc 入门(二)-- 服务接口类型

    本节是继上一章节Hello world的进一步深入挖掘; 一.grpc服务接口类型 在godoc的网站上对grpc的端口类型进行了简单的介绍,总共有下面4种类型[1]: gRPC lets you d ...

  10. window下golang使用gRPC入门案例&net core客户端

    gRPC是google开源高性能分布式RPC框架,支持http/2 双向数据流传输及Protobuff,可以在任何环境下运行. 它可以有效地将数据中心内和跨数据中心的服务与可插拔支持进行负载均衡,跟踪 ...

随机推荐

  1. C++并发-同步并发

    1.等待事件 std::mutex m; void wait() { std::unique_lock<std::mutex> lk(m); lk.unlock(); std::this_ ...

  2. 大规模 IoT 边缘容器集群管理的几种架构-0-边缘容器及架构简介

    ️Reference: IoT 边缘计算系列文章 什么是边缘容器? 边缘容器的概念 边缘容器是分散的计算资源,尽可能靠近最终用户或设备,以减少延迟.节省带宽并增强整体数字体验. 可以访问互联网的设备数 ...

  3. Mybatis 区别-开发

    三.MyBatis 主流的ORM 支持java .NET Ruby三种语言,MyBatis是对JDBC的封装 ORM框架Hibernate 区别: 1)sql 优化方面 Hibernate 使用 HQ ...

  4. vue3 语法糖setup 兄弟组件传值

    使用 mitt // 全局引入 npm install mitt 或者 cnpm install mitt 在main文件中挂载 import { createApp } from 'vue' imp ...

  5. 如何通过Java 代码设置 Word 文档页边距

    页边距是指页面的边线到文字的距离.通常可在页边距内部的可打印区域中插入文字和图形,也可以将某些项目放置在页边距区域中(如页眉.页脚和页码等).在我们用的Word文档中,都会设置页边距统一标准格式,页边 ...

  6. Powershell删除文本指定内容所在行以下内容

    需求:批量获取文本指定内容所在行以下内容(含当前行) 解决方案:使用Powershell脚本处理 案例: 获取当前文件夹下所有txt文件 含文本"4"所在行以下内容(含当前行) 如 ...

  7. 解决ssh连接远程主机出现“REMOTE HOST IDENTIFICATION HAS CHANGED”问题

    Win通过ssh连接远程主机 命令提示符方式 ssh username@ip 此后输入你的密码 通过VSCode Remote-SSH 在VSCode拓展中搜索"Remote-SSH&quo ...

  8. C#泛型接口请求封装类

    using HttpUtil; using Newtonsoft.Json; using System; using System.Collections.Generic; using System. ...

  9. 从NLP视角看电视剧《狂飙》,会有什么发现?

    目录 1.背景 2.数据获取 3.文本分析与可视化 3.1 短评数据预处理 3.2 词云图可视化 3.3 top关键词共现矩阵网络 3.4 <狂飙>演职员图谱构建 4.短评相关数据分析与可 ...

  10. BackTrader 简单BTC的SMA15回测DEMO

    import time import requests import json import csv from requests.packages.urllib3 import disable_war ...