Go语言grpc和protobuf


Posted in Golang onApril 13, 2022

1. 什么是grpc和protobuf

1.1 grpc

gRPC是一个高性能、开源和通用的RPC框架,面向移动和HTTP/2设计。

目前提供C、Java和Go语言版本,分别是:

grpc,grpc-java,grpc-go.其中C版本支持C,

C++,Node.js,Python,Ruby,Objective-C,PHP和C#支持.

grpc遵循HTTP/2协议,是一个二进制协议

grpc与http一样,底层都是tcp连接,遵循socket套接字

RPC是指远程过程调用,两台服务器A,B。A(客户端)调用B(服务端)上的方法,由于不在同一个内存空间,不能直接调用,需要通过网络调用。

Go语言grpc和protobuf

1.2 protobuf

Protocol Buffer是一种协议。
Protocol Buffer 其实 是 Google出品的一种轻量 & 高效的结构化数据存储格式,性能比Json、XML真的强2-100倍!

protobuf经历了protobuf2和protobuf3,pb3比pb2简化了很多,目前主流的版本是pb3

protobuf优点:

1.性能好:
压缩性能;
序列化和发序列化快,比Json、XML强2-100倍;
传输速度快。

2.便捷性好:
使用简单,自动生成序列化和反序列化代码;
维护成本低,只维护proto文件
向后兼容,不必破坏旧格式
加密性好

3.跨语言,跨平台,支持各种语言

protobuf缺点:

1.通用性差,json可以任何语言都支持,但是protobuf需要专门的解析库

2.自解释性差,只有通过proto文件才能了解数据结构

2.go下grpc

2.1官网下载protobuf工具

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

Go语言grpc和protobuf

2.2 下载go的依赖包

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

2.3 编写proto文件

option go_package = "./;proto";

解释:

./;:生成文件的路径

proto:生成文件的包名

hello.proto

syntax = "proto3";
package services;
option go_package = "./;proto";
service Greeter {
    rpc SayHello (HelloRequest) returns (HelloReply);
}
message HelloRequest {
    string name = 1;
}
message HelloReply {
    string message = 1;
}

2.4 生成hello.pb.proto文件

cd到proto目录下
命令:protoc -I . hello.proto   --go_out=plugins=grpc:.
命令解释:
protoc -I .:在当前路径下寻找hello.proto文件
--go_out=plugins=grpc:.  :生成go语言的proto文件放在当前路径下

Go语言grpc和protobuf

2.5 编写server端代码

Go语言grpc和protobuf

package main
import (
	"context"
	"file_test/grpc_go/proto"
	"net"

	"google.golang.org/grpc"
)
type Server struct {}
// 业务逻辑
func (s *Server) SayHello(ctx context.Context, request *proto.HelloRequest) (*proto.HelloReply, error) {
	res := &proto.HelloReply{
		Message: "hello " + request.Name,
	}
	return res, nil
}
// 启动rpc的server服务
func start() {
	// 1.实例化server
	g := grpc.NewServer()
	// 2.注册逻辑到server中
	proto.RegisterGreeterServer(g,&Server{})
	// 3.启动server
	lis,err:=net.Listen("tcp","127.0.0.1:8081")
	if err !=nil{
		panic("监听错误:"+err.Error())
	}

	err = g.Serve(lis)
	if err !=nil{
		panic("启动错误:"+err.Error())
	}
}
func main() {
	start()
}

2.6 编写client端代码

package main
import (
	"context"
	"file_test/grpc_go/proto"
	"fmt"

	"google.golang.org/grpc"
)
// rpc调用
func clientRpc(body map[string]string) (res *proto.HelloReply, err error) {
	name := body["name"]
	conn, err := grpc.Dial("127.0.0.1:8081", grpc.WithInsecure())
	if err != nil {
		return nil,err
	}
	defer conn.Close()
	rpc := proto.NewGreeterClient(conn)
	response, err := rpc.SayHello(context.Background(), &proto.HelloRequest{Name: name})
	if err != nil {
		return nil,err
	}
	return response,nil
}
// 业务代码
func start() {
	body := make(map[string]string)
	body["name"] = "jeff"
	response,err := clientRpc(body)
	if err!=nil{
		fmt.Println("rpc调用失败:",err)
		return
	}
	fmt.Println(response.Message)
}
func main() {
	start()
}
//结果:
hello jeff

2.7 python和go相互调用实践(跨语言调用)

proto文件共用。

1.开启python的server端,go的client端测试。

2.开启go的server端,python的clinet端测试。

以上就是golang下grpc框架的使用编写示例的详细内容!

Golang 相关文章推荐
go:垃圾回收GC触发条件详解
Apr 24 Golang
golang DNS服务器的简单实现操作
Apr 30 Golang
解决golang post文件时Content-Type出现的问题
May 02 Golang
浅谈golang package中init方法的多处定义及运行顺序问题
May 06 Golang
Golang全局变量加锁的问题解决
May 08 Golang
Go遍历struct,map,slice的实现
Jun 13 Golang
Go 语言结构实例分析
Jul 04 Golang
使用GO语言实现Mysql数据库CURD的简单示例
Aug 07 Golang
Go语言基础函数基本用法及示例详解
Nov 17 Golang
Golang使用Panic与Recover进行错误捕获
Mar 22 Golang
Golang 并发编程 SingleFlight模式
Apr 26 Golang
Go语言编译原理之变量捕获
Aug 05 Golang
Golang流模式之grpc的四种数据流
Apr 13 #Golang
Golang数据类型和相互转换
Apr 12 #Golang
Go语言的协程上下文的几个方法和用法
Apr 11 #Golang
Golang 1.18 多模块Multi-Module工作区模式的新特性
Apr 11 #Golang
golang三种设计模式之简单工厂、方法工厂和抽象工厂
Golang原生rpc(rpc服务端源码解读)
Apr 07 #Golang
Go并发4种方法简明讲解
You might like
PHP 检查扩展库或函数是否可用的代码
2010/04/06 PHP
php模块memcache和memcached区别分析
2011/06/14 PHP
php读取mysql中文数据出现乱码的解决方法
2013/08/16 PHP
PHP中overload与override的区别
2017/02/13 PHP
PHP利用递归函数实现无限级分类的方法
2019/03/22 PHP
Laravel Validator 实现两个或多个字段联合索引唯一
2019/05/08 PHP
javascript 关闭IE6、IE7
2009/06/01 Javascript
jQuery中绑定事件的命名空间详解
2011/04/05 Javascript
js使用for循环及if语句判断多个一样的name
2014/09/09 Javascript
javascript中使用正则表达式清理table样式的代码
2020/04/01 Javascript
详解JavaScript数组和字符串中去除重复值的方法
2016/03/07 Javascript
JavaScript预解析及相关技巧分析
2016/04/21 Javascript
JavaScript中点击事件的写法
2016/06/28 Javascript
浅谈React前后端同构防止重复渲染
2018/01/05 Javascript
vue中使用cookies和crypto-js实现记住密码和加密的方法
2018/10/18 Javascript
30分钟用Node.js构建一个API服务器的步骤详解
2019/05/24 Javascript
JQuery常用简单动画操作方法回顾与总结
2019/12/07 jQuery
vue 自定指令生成uuid滚动监听达到tab表格吸顶效果的代码
2020/09/16 Javascript
[01:08:29]DOTA2-DPC中国联赛定级赛 RNG vs Aster BO3第一场 1月9日
2021/03/11 DOTA
Python实现PS图像调整颜色梯度效果示例
2018/01/25 Python
python中的插值 scipy-interp的实现代码
2018/07/23 Python
Django基础知识 URL路由系统详解
2019/07/18 Python
python 字典 setdefault()和get()方法比较详解
2019/08/07 Python
python 伯努利分布详解
2020/02/25 Python
python实现最速下降法
2020/03/24 Python
解决python图像处理图像赋值后变为白色的问题
2020/06/04 Python
20行代码教你用python给证件照换底色的方法示例
2021/02/05 Python
在css3中background-clip属性与background-origin属性的用法介绍
2012/11/13 HTML / CSS
Elemis美国官网:英国的第一豪华护肤品牌
2018/03/15 全球购物
expedia比利时:预订航班+酒店并省钱
2018/07/13 全球购物
英国儿童鞋和靴子:Start-Rite
2019/05/06 全球购物
网络编程中设计并发服务器,使用多进程与多线程,请问有什么区别?
2016/03/27 面试题
函授毕业自我鉴定
2014/02/04 职场文书
会议接待欢迎词范文
2015/01/26 职场文书
Python如何把不同类型数据的json序列化
2021/04/30 Python
进阶篇之linux环境下安装MySQL数据库
2022/04/09 MySQL