首页 > 其他分享 >gRPC

gRPC

时间:2023-06-08 20:23:54浏览次数:46  
标签:protobuf gRPC grpc rpc 服务端 客户端

目录

概述

gRPC是由Google开源的一个高性能rpc框架,由内部的Stubby演化而来,2015年正式开源,是云原生时代的rpc标准

核心设计思路

  • 网络通信:自己封装了网络通信的部分,提供多语言的网络通信的封装(c/java(netty),go)
  • 协议:http2,使用二进制传输、支持双向流(全双工)连接的多路复用
  • 序列化:(基于文本如json,基于二进制,如java原生序列化),protobuf,时间和空间效率是json的3-5倍,使用IDL语言定义
  • 代理的创建:让调用者像调用本地方法一样调用远程服务方法,stub

其他rpc框架

  • ThriftRPC,使用专属协议基于tcp,性能高于gRPC,但gRPC在云原生时代与其他组件合作顺利,所以gRPC应用更广泛

gRPC好处:

  • 高效的进程间通信(协议、序列化)
  • 支持多语言,原生支持c/go/java,其他c语言之上的语言也支持c++/c#/nodejs/python/ruby/php...,是c的实现上做适配
  • 支持多平台,linux/macos/windows/android/ios
  • gRPC序列化方式采用protobuf,效率高
  • 使用http2协议
  • 大厂背书(google)

Http2.0协议

1.x协议

  • 1.0:请求响应模式
    • 短连接(无状态),由于早期硬件性能不足,http在请求响应后就断开连接。在技术层面使用HttpSession解决服务端与客户端(cookie)连接问题
    • 文本传输、单工(无法实现服务器推送,只能采用客户端轮询方式实现)
  • 1.1:请求响应模式,实现了有限的长连接(keepalived头),可以升级为websocket协议实现双工
  • 1.x协议共性
    • 文本格式传输数据,可读性好但是效率差
    • 本质上无法实现双工
    • 资源请求,需要发送多次请求,建立多个连接才能完成(css/js),优化方法(动静资源分离,cdn)

2.x协议

  • 二进制协议,效率高于http1.x,可读性差
  • 可以实现双工通信
  • 一个请求,一个连接可以请求多个数据(多路复用)

http2.0的三个概念

  • 数据流,stream,一个连接上可以发送多个流,每个流里面有一个消息,消息里面有帧,包括head数据、body数据
  • 消息,message
  • 帧,frame

其他概念

  • 数据流的优先级,可以为不同的stream设置权重,限制不同流的传输顺序
  • 流控,如client发送数据太快,server处理不过来,可以通知clien暂停发送

Protocol Buffers (protobuf)

  • protobuf是一种与编程语言无关(IDL),与具体的平台无关(OS),定义中间语言,可以方便的在client与server之间传输
  • 有两种版本,proto2,proto3,主流应用使用proto3
  • 需要安装protobuf编译器,将proto的IDL语言转换成某一种开发语言

github地址:https://github.com/protocolbuffers/protobuf protobuf:https://protobuf.dev/

protobuf语法

idea中安装下protobuf插件(idea官方的即可,2021版本自带)

文件格式:.proto

版本声明:

syntax = "proto3"; //有2和3 使用3即可

注释:单行//,多行/* */

与java相关的语法:

option java_multiple_files = false; //生成一个文件还是多个文件
option_java_package = "org.example"; //生成的类放在哪个包下
option java_outer_classname = "HelloService"; //生成的外部类的名字,管理内部类,开发实际使用的是内部类,针对的是message

逻辑包:

package xxx; //protobuf对于文件内容的管理

导入:

import "xxx/Xxx.proto"; //在一个proto文件中导入另外一个定义的文件

基本类型:参考官网,https://protobuf.dev/programming-guides/proto3/#scalar

枚举:

enum Season {
	SPRING = 0; //必须从0开始
	SUMMER = 1;
}

消息message:

message LoginRequest {
	string username = 1; //1表示字段序号,范围1-2^29-1,19000-19999是proto保留,不能使用,不一定连续,唯一即可
	stirng password = 2;
}

//singlular:这个字段的值只能有0个或1个(默认关键字)
//repeated:这个字段返回的数据是多个,等价于java中的list,实际使用时是一个list

//一个proto文件中可以定义多个消息

//消息是可以嵌套的

//oneof关键字,其中一个,表示该字段只能是定义的其中一个
message MyMessage {
	string f1 = 1; //第一个字段
	oneof abc { //第二个字段 是其中一个
		string name = 2;
		int32 age = 3;
	}
}

服务定义:

service HelloService {
	rpc hello(HelloRequest) resturns(HelloResponse) {}
	//可以定义多个方法
}

//可以定义多个service

//有4个服务方式

gRPC开发

项目结构

xxx-api模块 //定义protobuf IDL语言(message、service),并且通过命令创建具体的代码,其他client、service引入使用

xxx-server模块 //实现api中定义的接口,发布rpc服务(创建服务端程序)

xxx-client模块 //创建服务stub(代理),基于代理进行rpc调用

一些开发经验:

  • proto文件一般放在main下的proto目录下
  • 一个proto对应一个文件,关闭多文件生成
  • 外部类名称一般与proto对应,如HelloProto对应Hello.proto,实际使用的是HelloProto的内部类

maven插件:https://github.com/grpc/grpc-java ,直接在工程中编译proto

服务端:

  • 服务端实现定义的服务Grpc基类,实现实际的service实现
    • 调用onNext方法回传响应
    • 调用onCompleted方法标记响应结束(服务端)
  • 构建server,并注册服务
  • 启动server

客户端:

  • 通过代理对象完成rpc调用
  • java中grpc是用netty实现的,需要获取channel
  • 通过channel获取stub(代理)
  • 准备调用参数
  • 通过stub完成rpc调用
  • 关闭channel

gRPC的四种通信方式

  • 简单rpc,一元rpc(Unary RPC)
  • 服务端流式rpc(Server Streaming RPC)
  • 客户端流式rpc(Client Streaming RPC)
  • 双向流rpc(Bi-directional Stream RPC)

一元RPC

当client发起调用后,提交数据,等待服务端响应。也即是传统的服务端客户端通信方式

服务端流式RPC

客户端发送一个请求对象,服务端返回多个结果对象。服务端可以在不同的时刻,返回结果

  • 客户端的响应结果为一个迭代器用于获取服务端的多个结果(同步情况)
  • 客户端异步情况下,参数中多了一个处理响应的异步观察者,用于处理服务端返回的结果(客户端可以控制参数,所以处理结果的异步逻辑在参数中)

在定义service时,需要在返回值前加stream

应用场景:如请求股票信息,只请求一次,后续返回多个结果

客户端流式RPC

客户端发送多个请求对象,服务端只返回一个结果

  • 服务端在返回值中返回一个异步处理客户端请求的逻辑(客户端request的观察者,服务端可以控制返回值,所以处理客户端请求的逻辑在返回值中,跟同步相比,request的处理放在了返回值中)
  • 客户端在rpc调用时返回值是一个request的观察者,与服务端的返回值对应,服务端返回客户端流的处理逻辑,客户端拿着服务端返回的客户端流进行发送数据,服务端和客户端用同一个Observer

在定义service时,需要在请求参数前加stream

应用场景:iot设备给服务端发送数据

双向流RPC

客户端可以发送多个消息给服务端,服务端也可以发送多个消息给客户端。

  • 与客户端流rpc结构相同(是因为不管是服务端流rpc还是客户端流rpc,服务端处理响应都是StreamObserver)

应用场景:聊天室

gRPC的代理方式

  • BlockingStub,阻塞
  • Stub,异步,通过监听处理
  • FutureStub,可以同步,也可以异步,类似NettyFuture,只能用于一元RPC
    • 同步就使用get获取结果
    • 异步可以通过addListener,这个无法获取返回值
    • 异步可以使用工具类Futures.addCallback,可以获取返回值

gRPC与SpringBoot整合

整合思想:

  • grpc-server
  • grpc-client
  • api层不管是不是用框架都要使用proto文件生成

SpringBoot与grpc整合过程中,对于服务端做了什么封装

  • 原生的grpc
    • 实现服务接口
    • 创建服务端,发布grpc功能
  • 如何封装
    • 实现服务接口与具体业务相关,无法封装
    • 服务端创建功能可以封装,但需要额外配置(端口 -- 配置,具体的服务实现 -- 注解)

注意:

  • 使用的grpc-spring-boot-starter版本内部的grpc版本与外部的要一致,否则依赖冲突
  • protoc-gen-grpc-java的版本要与使用的grpc的版本一致,protoc的版本要使用protobuf的版本,且要与grpc内部引用的protbobuf版本一致,否则编译的类报错

SpringBoot与grpc整合过程总,对客户单做了什么封装

  • 原生grpc
    • 通过channel设置服务端ip和port
    • 获取stub,即远程服务代理,进行调用
  • 如何封装
    • 连接服务端,通过配置封装
    • stub代理,通过spring容器封装

gRPC高级应用

  • 拦截器 (一元拦截器)
  • Stream Tracer (监听流,流拦截器)
  • Retry Policy (客户端重试)
  • NameResolver (配置中心)
  • 负载均衡 (pick-first,轮询)
  • grpc与微服务整合
    • 序列化(protobuf)与dubbo整合
    • grpc与dubbo整合,使用grpc通信
    • grpc与GateWay整合
    • grpc与JWT整合,做认证
    • grpc与Nacos2.0整合,自定义配置中心
    • grpc可以替换OpenFeign
    • k8s可以与grpc无缝对接(k8s就是使用的grpc)

标签:protobuf,gRPC,grpc,rpc,服务端,客户端
From: https://www.cnblogs.com/bingmous/p/17455282.html

相关文章

  • go语言使用GRPC流处理模式
    go语言使用GRPC流处理模式标签(空格分隔):go,grpcproto文件syntax="proto3";packagefour_kinds_method.v1;optiongo_package="go-example/grpc/four_kinds_method/proto;four_kinds_method_pb";//gRPC允许您定义四种服务方法//1.一元RPC,其中客户端向服务器发送单......
  • gRPC 简介
    gRPC简介标签(空格分隔):go,grpc概述在gRPC中,客户端应用程序可以直接调用不同计算机上的服务器应用程序上的方法,就像它是本地对象一样,从而使您更轻松地创建分布式应用程序和服务。与许多RPC系统一样,gRPC基于定义服务的思想,指定可以使用其参数和返回类型远程调用的方法。在......
  • GRPC核心概念、架构和生命周期
    GRPC核心概念、架构和生命周期标签(空格分隔):go,grpc官网地址:https://grpc.io/docs/what-is-grpc/core-concepts/概述与许多RPC系统一样,gRPC基于定义服务的思想,指定可以使用其参数和返回类型远程调用的方法。默认情况下,gRPC使用协议缓冲区作为接口定义语言(IDL)来描述服务......
  • grpc 与http比较,具有哪些优势
    更高的性能:gRPC使用ProtocolBuffers作为默认的数据序列化工具,相比于JSON等文本格式,它的编码和解码速度更快,传输的数据量更小,因此可以更快地处理大量的请求和响应。更小的带宽占用:由于使用二进制数据格式,gRPC的数据传输量比HTTP更小,因此可以降低网络传输的带宽占用。支持......
  • 写给go开发者的gRPC教程-通信安全
    使用TLS安全传输数据什么是SSL/TLSSSL包含记录层(RecordLayer)和传输层[1],记录层协议确定传输层数据的封装格式。传输层安全协议使用X.509[2]认证,之后利用非对称加密演算来对通信方做身份认证,之后交换对称密匙作为会话密匙(Sessionkey[3])。这个会谈密匙是用来将通信两方交换......
  • 这一次,带你玩转gRPC框架
    前言大家好,先做一下自我介绍我叫BarryYan,目前是一名互联网公司的研发工程师,同时也是后端技术领域的狂热爱好者和技术博主,在GitHub、CSDN社区、51CTO博客社区、阿里云技术社区、掘金技术社区和InfoQ写作社区等都有自己的博客,原创200余篇。虽然刚刚大学本科毕业不到一年,但是算上实......
  • HTTP、WebSocket、gRPC 或 WebRTC:哪种通信协议最适合您的应用程序?
    在为您的应用程序选择通信协议时,有很多不同的选择。在本文中,我们将了解四种流行的解决方案:HTTP、WebSocket、gRPC和WebRTC。我们将通过调查其背后的技术、它的最佳用途及其优缺点来探索每个协议。我们的通信方式在不断改进:变得更快、更方便、更可靠。我们的通信方式已经从使用信鸽......
  • gnmi 基于grpc 的网络管理接口
    网络自动化是这几年对于网络管理比较重要的话题,openconfig就是一个开放组织,gnmi是基于grpc提供的网络管理接口,对于需要开发网络自动化的应用是值得参考使用的参考资料https://github.com/openconfig/gnmihttp://www.openconfig.net/......
  • golang 学习之 etcd protobuffer grpc gorm 服务注册发现 go-micro
    1.etcd使用步骤1)下载:https://github.com/etcd-io/etcd/releases/2)配置环境变量3)编辑local-cluster-profile文件:(利用goreman启动方式,生产环境参考官方文档)etcd1:etcd--nameinfra1--listen-client-urlshttp://127.0.0.1:2379--advertise-client-urlshttp://127.0.0.1......
  • go语言中protobuf以及grpc的使用
    首先定义数据结构,保存为.proto文件syntax="proto3";packagetutorial;//Theprotocolcompilergeneratesaclassfromthefollowing.protofilewith//methodsforwritingandreadingthemessagefields.Theclassiscalled//"Person"andisin......