百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

go语言gRPC系列(一) - gRPC入门

toyiye 2024-06-21 11:59 10 浏览 0 评论

1. 前言#

之前学习的go的微服务之间还是通过REST API的方式互相调用的,但既然要学习微服务,gRPC肯定是一个绕不过去的需要学习的技术, 所以就开搞吧

2. gRPC与Protobuf简介#

gRPC是一款语言中立平台中立、开源的远程过程调用系统

即:gRPC客户端和服务端可以在多种环境中运行和交互,例如用java写一个服务端,可以用go语言写客户端调用

微服务架构中,由于每个服务对应的代码库是独立运行的,无法直接调用,彼此间的通信就是个大问题.

gRPC可以实现将大的项目拆分为多个小且独立的业务模块,也就是服务。各服务间使用高效的protobuf协议进行RPC调用,gRPC默认使用protocol buffers,这是google开源的一套成熟的结构数据序列化机制

当然也可以使用其他数据格式如JSON

可以用proto files创建gRPC服务,用message类型来定义方法参数和返回类型

3. 安装#

  • 第一步:下载grpc通用编译器

如下图,解压出来因平台而异会是一个protoc或者protoc.exe

https://github.com/protocolbuffers/protobuf/releases

  • 第二步:把下载的二进制文件路径添加到环境变量中(为了能全局访问protoc) 这里以为mac为例子
Copy# 打开存放环境变量的文件
vim ~/.bash_profile

# 添加如下,后面是路径
alias protoc="/Users/emm/others/protoc-3.12.4-osx-x86_64/bin/protoc"

# 刷新环境变量
source ./.bash_profile
  • 第三步: 安装go专用的protoc的生成器

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

安装后会在GOPATH目录下生成可执行文件,protobuf的编译器插件protoc-gen-go,等下执行protoc命令会自动调用这个插件

4. 中间文件演示#

4.1 编写中间文件#

这里新建一个pbfiles文件夹用于存放protoc文件

Copy// 这个就是protobuf的中间文件

// 指定的当前proto语法的版本,有2和3
syntax = "proto3";

// 指定等会文件生成出来的package
package service;

// 定义request
message ProductRequest{
  int32 prod_id = 1; // 1代表顺序
}

// 定义response
message ProductResponse{
  int32 prod_stock = 1; // 1代表顺序
}

4.2 运行protoc命令编译成go中间文件#

然后运行以下的命令来生成.go结尾的文件

  • 下面的命令就是我们刚刚下的protoc包以及protoc-gen-go插件的作用
Copy# 编译Product.proto之后输出到service文件夹
protoc --go_out=../service Product.proto

如下就在service文件夹自动生成了一个go文件,并且它提示我们不要去修改它

5. 创建gRPC服务端#

5.1 新建Product.protoc#

这个protoc文件比上面的多出了一个service的定义和里面的一个方法的定义

Copy// 这个就是protobuf的中间文件

// 指定的当前proto语法的版本,有2和3
syntax = "proto3";

// 指定等会文件生成出来的package
package service;

// 定义request model
message ProductRequest{
  int32 prod_id = 1; // 1代表顺序
}

// 定义response model
message ProductResponse{
  int32 prod_stock = 1; // 1代表顺序
}

// 定义服务主体
service ProdService{
  // 定义方法
  rpc GetProductStock(ProductRequest) returns(ProductResponse);
}

5.2 运行protoc命令#

注意

  • 这里的protoc命令和之前的命令相比有点不一样
Copyprotoc --go_out=plugins=grpc:../service Product.proto

然后还是会在service文件夹下生成一个.go的文件

有两个比较需要注意的

  1. RegisterProdServiceServer

后面需要在server中调用这个来注册

  1. ProdServiceServer的接口定义

我们需要继承这个接口,即实现它所有的方法

5.3 实现RegisterProdServiceServer接口#

上面我们在protoc文件中定义了一个ProdService中包含了一个GetProductStock的方法

这里我们要实现自动生成的go文件中的接口

Copypackage service

import "context"

type ProdService struct {
}

func (ps *ProdService) GetProductStock(ctx context.Context, request *ProductRequest) (*ProductResponse, error) {
	return &ProductResponse{ProdStock: request.ProdId}, nil
}

5.4 准备工作完成,创建main函数将服务端跑起来#

前面的都是准备工作,这里是真正把服务端跑起来的操作

下面是服务端代码:

Copypackage main

import (
	"gomicro-quickstart/grpc_demo/service"
	"google.golang.org/grpc"
	"log"
	"net"
)

func main() {
	// 1. new一个grpc的server
	rpcServer := grpc.NewServer()

	// 2. 将刚刚我们新建的ProdService注册进去
	service.RegisterProdServiceServer(rpcServer, new(service.ProdService))

	// 3. 新建一个listener,以tcp方式监听8082端口
	listener, err := net.Listen("tcp", ":8082")
	if err != nil {
		log.Fatal("服务监听端口失败", err)
	}

	// 4. 运行rpcServer,传入listener
	_ = rpcServer.Serve(listener)
}

排坑

  • 如果遇见类似undefined: grpc.SupportPackageIsVersion6和undefined: grpc.ClientConnInterface的错误,可以修改go.mod将grpc版本改到1.27.0


6. 创建gRPC客户端#

  • 新建一个grpc_client文件夹存放客户端相关的
  • 并在grpc_client文件夹下再新建一个service文件夹

6.1 拷贝Product.pb.go到客户端service文件夹下#

6.2 编写client的main函数#

Copypackage main

import (
	"context"
	"fmt"
	"gomicro-quickstart/grpc_client/service"
	"google.golang.org/grpc"
	"log"
)

func main() {
	// 1. 新建连接,端口是服务端开放的8082端口
	// 并且添加grpc.WithInsecure(),不然没有证书会报错
	conn, err := grpc.Dial(":8082", grpc.WithInsecure())
	if err != nil {
		log.Fatal(err)
	}

	// 退出时关闭链接
	defer conn.Close()

	// 2. 调用Product.pb.go中的NewProdServiceClient方法
	productServiceClient := service.NewProdServiceClient(conn)

	// 3. 直接像调用本地方法一样调用GetProductStock方法
	resp, err := productServiceClient.GetProductStock(context.Background(), &service.ProductRequest{ProdId: 233})
	if err != nil {
		log.Fatal("调用gRPC方法错误: ", err)
	}

	fmt.Println("调用gRPC方法成功,ProdStock = ", resp.ProdStock)
}

6.3 运行并显示结果#

  • 先把服务端运行起来
  • 再把客户端运行起来

然后客户端输出正确的结果,第一个go的gRPC调用运行成功

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码