前言

在学习 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. Cannot access child value on Newtonsoft.Json.Linq.JValue

    开发项目框架为.net framework,遇到此问题原因是笔者在做接口转发时接口返回类型直接定义为了object类型,这导致格式化返回结果时出现如标题异常,具体代码如下 try { var resu ...

  2. Kali Linux Web 渗透测试秘籍 中文版

    第一章 配置 Kali Linux 简介 在第一章中,我们会涉及如何准备我们的 Kali 以便能够遵循这本书中的秘籍,并使用虚拟机建立带有存在漏洞的 Web 应用的实验室. 1.1 升级和更新 Kal ...

  3. 【KAWAKO】docker暴力上手

    目录 从docker hub拉取镜像 根据镜像创建容器,同时把本地目录挂载到容器 进入容器 停止容器 删除停止的容器 从docker hub拉取镜像 进入docker hub,搜索自己喜欢的镜像. 复 ...

  4. .Net 6 miniAPI

    启动:1.双击 WebApplication1.exe文件   2.dotnet WebApplication1.dll --urls "http://localhost:5403;http ...

  5. Mybatis 实体类驼峰命名与数据库字段之间映射

    数据库的命名规则和 Java 的命名规则不一致,导致实体类与数据库字段不能完美映射. 一.可以在 mapper.xml 中通过 resultMap 来解决: <resultMap id=&quo ...

  6. AI绘画--tag资源

    tag生成器:https://wolfchen.top/tag/ 资源整合表:https://wolfchen.top/tag/doc.html 魔咒百科词典:https://aitag.top/ N ...

  7. adb server version (36) doesn‘t match this client (41)解决

    问题描述:夜神模拟器,dos窗口下,然后adb devices发现连不上模拟器了,报adb server version (36) doesn't match this client (41); ki ...

  8. VMware-SSH协议的认证方式

    SSH1协议支持非对称密钥认证方式.口令认证,无法保证连接的完整性. SSH2协议支持SSH1协议支持的所有认证方式,增加数据保密性. 基于主机的认证方式[!不安全!] 当本地计算机收到执行远程命令的 ...

  9. NSIS 自定义界面,下载并安装Net.Framework4.8

    以 ScreenToGif 这款软件为例,详细讲解如何在安装的过程中检测并下载net包进行安装. 前言 1.ScreenToGif 是一款开源的截屏软件,依赖于Net.Framework环境 2.本文 ...

  10. VBA 常用知识点

    VBA对象传参 首先主函数中必须定义参数的类型 函数调用语法为 函数名 参数1 参数2 被调用函数中定义传参是否引用(byref)还是重新建立一份数据(byval) 代码示例 Sub auto_cou ...