jjzjj

RPC和GRPC

陈文小超_自律 2024-01-18 原文

createdtime 20211122

updatedtime 20211124

author venki.chen


一、是什么
1. 定义,是做什么用的?

rpc是什么?

①在分布式计算,远程过程调用(英语:Remote Procedure Call,缩写为 RPC)是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一个地址空间(通常为一个开放网络的一台计算机)的子程序,而程序员就像调用本地程序一样,无需额外地为这个交互作用编程(无需关注细节)。RPC是一种服务器-客户端(Client/Server)模式,经典实现是一个通过发送请求-接受回应进行信息交互的系统。

rpc详解

RPC模式分为三层,①用户和服务器(负责处理业务逻辑,调用本地 Stub);②Stub处理客户端和服务端约定好的语法、语义的封装和解封装;③RPCRuntime负责最底层的网络传输。

rpc解决的三大问题

基于RPC模式,一个 RPC 框架基本需要解决 协议约定、网络传输、服务发现这三个问题。

①协议约定问题(Stub) 指的是怎么规定远程调用的语法,怎么传参数等。用上面的类比,你怎么告诉你的朋友要玩什么游戏?是直接说游戏的名字,王者荣耀,绝地求生,还是说简称,王者,吃鸡,或者用 1 代表王者,2 代表吃鸡,只说 1 或 2。

②传输协议问题(RPCRuntime) 指的是在网络发生错误、重传、丢包或者有性能问题时怎么办?用上面的类比,你打电话时,刚说了打什么游戏,但是还没有收到对方回复,电话信号不好断了,这时候怎么处理?

③服务发现问题(插件比如:etcd) 指的是如何知道服务端有哪些服务可以调用,从哪个端口访问?服务端可能实现多个远程调用,在不同的进程上,随机监听端口,客户端要怎么才能知道这些端口呢?

rpc调用过程

  1. 调用者(客户端Client)以本地调用的方式发起调用;
  2. Client stub(客户端存根)收到调用后,负责将被调用的方法名、参数等打包编码成特定格式的能进行网络传输的消息体;
  3. Client stub将消息体通过网络发送给服务端;
  4. Server stub(服务端存根)收到通过网络接收到消息后按照相应格式进行拆包解码,获取方法名和参数;
  5. Server stub根据方法名和参数进行本地调用;
  6. 被调用者(Server)本地调用执行后将结果返回给server stub;
  7. Server stub将返回值打包编码成消息,并通过网络发送给客户端;
  8. Client stub收到消息后,进行拆包解码,返回给Client;
  9. Client得到本次RPC调用的最终结果。

grpc是什么?

①gRPC 是一款高性能、开源的 RPC 框架,产自 Google,基于 ProtoBuf 序列化协议进行开发,支持多种语言(Golang、Python、Java等),本篇只介绍 Golang 的 gRPC 使用。因为 gRPC 对 HTTP/2 协议的支持使其在 Android、IOS 等客户端后端服务的开发领域具有良好的前景。gRPC 提供了一种简单的方法来定义服务,同时客户端可以充分利用 HTTP/2 stream 的特性,从而有助于节省带宽、降低 TCP 的连接次数、节省CPU的使用等。

rpc和grpc之间的关系是什么?

①rpc是一种协议,grpc是基于rpc协议实现的一种框架。

grpc的解决rpc三大问题

①协议约定。gRPC 的协议是 Protocol Buffers,是一种压缩率极高的序列化协议,Google 在 2008 年开源了 Protocol Buffers,支持多种编程语言,所以 gRPC 支持客户端与服务端可以用不同语言实现。

②传输协议。gRPC 的数据传输用的是 Netty Channel, Netty 是一个高效的基于异步 IO 的网络传输架构。Netty Channel 中,每个 gRPC 请求封装成 HTTP 2.0 的 Stream。

③服务发现。gRPC 本身没有提供服务发现的机制,需要通过其他组件。

2. 我的理解

grpc是一种实现了rpc协议的框架,并且分别通过protocol buffer、netty channel 以及服务发现组件解决rpc的协议约定、传输协议、服务发现三大问题。

二、为什么
解决什么问题,可以带来什么好处?

优点:

  1. grpc
  • Protocol Buffers 压缩性高,速度快。
  • HTTP 2.0 流传输。
  • 支持多语言。

缺点:

  1. grpc
  • 可读性差。
  • 对浏览器支持有限。
  • 外部组件支持较差。
三、怎么用
1. 应用场景
- 实时聊天; - 微服务系统。
2. 具体应用
3. 注意事项
四、思考点
1. 它山之石

rpc和传统的http接口的区别

  1. 与 HTTP 采用浏览器 —— 服务器工作模式(B/S)不同,RPC 采用客户端 —— 服务器(C/S)工作模式,请求程序是一个客户端(Client),而远程服务提供程序是一个服务器(Server)。当执行一个 RPC 调用时,客户端程序首先会发送一个带有参数的请求到服务端,然后等待服务端响应;在服务端,服务进程保持监听状态,当客户端请求到达时,服务端通过解析请求参数计算出结果,并向客户端发送响应信息,然后继续等待下一个客户端请求。客户端接收到来自服务端的响应信息后,可以执行相应的业务逻辑,也可以继续进行其它 RPC 调用。
    主要来阐述HTTP和RPC的异同,让大家更容易根据自己的实际情况选择更适合的方案。

  2. 传输协议

  • RPC:可以基于TCP协议,也可以基于HTTP协议。
  • HTTP:基于HTTP协议。
  1. 传输效率
  • RPC:使用自定义的TCP协议,可以让请求报文体积更小,或者使用HTTP2协议,也可以很好的减少报文的体积,提高传输效率。
  • HTTP:如果是基于HTTP1.1的协议,请求中会包含很多无用的内容,如果是基于HTTP2.0,那么简单的封装以下是可以作为一个RPC来使用的,这时标准RPC框架更多的是服务治理。
  1. 性能消耗
  • RPC:可以基于thrift实现高效的二进制传输。
  • HTTP:大部分是通过json来实现的,字节大小和序列化耗时都比thrift要更消耗性能。
  • 长链接,不必每次通信都要像http一样去3次握手什么的,减少了网络开销;其次就是RPC框架一般都有注册中心,有丰富的监控管理;发布、下线接口、动态扩展等,对调用方来说是无感知、统一化的操作。
  1. 负载均衡
  • RPC:基本都自带了负载均衡策略。
  • HTTP:需要配置Nginx,HAProxy来实现。
  1. 服务治理
  • RPC:能做到自动通知,不影响上游。
  • HTTP:需要事先通知,修改Nginx/HAProxy配置。
  1. 总结
  • RPC主要用于公司内部的服务调用,性能消耗低,传输效率高,服务治理方便。HTTP主要用于对外的异构环境,浏览器接口调用,APP接口调用,第三方接口调用等。

Go 语言中的 RPC 编程

一个 RPC 服务端可以注册多个不同类型的对象,但不允许注册同一类型的多个对象。此外,一个对象只有满足以下这些条件的方法,才能被 RPC 服务端设置为可提供远程访问:

  • 必须是在对象外部可公开调用的方法(首字母大写);
  • 必须有两个参数,且参数的类型都必须是包外部可以访问的类型或者是 Go 内建支持的类型;
  • 第二个参数必须是一个指针;
  • 方法必须返回一个 error 类型的值。

以上 4 个条件,可以简单地用如下这行代码表示:

func (t *T) MethodName(argType T1, replyType *T2) error

其中,类型 T、T1 和 T2 分别对应服务对象所属类型、请求类型和响应类型,它们默认都会使用 Go 语言内置的 encoding/gob 包进行编码解码。

该方法(MethodName)的第一个参数表示由 RPC 客户端传入的请求参数,第二个参数表示要返回给 RPC 客户端的响应结果,最后返回的是一个 error 类型的值表示错误信息。

2. 可以攻玉
  1. 通过以上所述就可以将,rpc、grpc、protocol-buffer、protoc、protoc-gen-go串联在一起,理解通了。
  2. 接下来就要思考下etcd、micro、go-micro、protoc-gen-micro之间的关联关系。
五、参考链接
  1. Golang RPC 之 gRPC
  2. RPC与Protobuf
  3. RPC与restful,以及简单引入gRPC
  4. 浅谈 RPC 和 REST: SOAP, gRPC, REST
  5. 【维基百科-读书笔记】远程过程调用RPC
  6. rpc和http的区别是什么 各自的优缺点有哪些

有关RPC和GRPC的更多相关文章

  1. javascript - 通过 HTTP 进行实时双向 JSON-RPC 通信 - 2

    我正在构建一个接受HTTP请求的JSON-RPC服务器。我想支持双向通信(客户端和服务器都可以发送请求),具体用例是发布/订阅架构,其中客户端发送subscribe(X)请求并接收changed(X)请求(几乎)实时。据我所知,有几种方法可以用HTTP实现:长轮询WebSockets使用基于cookie的session模型轮询调用流式传输(保持HTTP连接打开)上述一些的组合我正在寻找的是一种基于公认的互联网标准(如果可能)的解决方案,可从网络浏览器使用并且易于在客户端使用。到目前为止,我更喜欢流媒体(Twitter、CouchDB就是这样做的),但我不确定浏览器和JSON-RPC库对

  2. docker - 使用 gRPC Docker 容器构建 Go 时出错 - 2

    我正在尝试将我的golanggrpc应用程序转换为docker容器,但是在尝试构建时我总是遇到错误。错误是messagepb/stickynote.pb.go:16:8:cannotfindpackage"github.com/golang/protobuf/proto"inanyof:/usr/local/go/src/github.com/golang/protobuf/proto(from$GOROOT)/go/src/github.com/golang/protobuf/proto(from$GOPATH)sticky.go:6:2:cannotfindpackage"gith

  3. go - 如何约束Go的grpc go例程个数 - 2

    有什么办法可以限制grpc客户端中的goroutines数量吗?我有一个使用grpc客户端的go应用程序,我发现有相当多的go例程正在创建并不断增长。感谢您的帮助。 最佳答案 如果你的问题是如何限制grpcgoroutines,没有办法,但我怀疑限制goroutine数量有什么意义。如果你达到了你的限制并且另一个请求来了怎么办?您可以在处理程序的开头使用类似信号量的模式,这样您就可以限制N个并发请求。额外的请求将等待其他请求完成后才开始处理(但是有N个goroutine,只有N个在工作)。Here是使用channel的信号量实现。

  4. go - gRPC 实现性能 - java v/s goLang - 2

    gRPC支持多种语言的rpc服务端和客户端实现。我需要知道在goLangv/sJava中实现gRPC服务器和客户端是否有任何显着的性能差异。如果我们正在寻找高性能和可扩展性,go还是java哪个实现更好谢谢吉里什TS 最佳答案 看看publicgrpcbenchmarks.multi-languageperformancedashboard@master显示Go和Java并驾齐驱。一般来说,Java的性能和延迟稍好一些,但Go在某些情况下表现更好,例如流式乒乓的延迟。由于它们非常相似,因此最好根据其他因素来决定您要使用哪种语言。

  5. Golang grpc : how scalable is it? - 2

    GRPConGo的可扩展性如何?我可以为每个连接到我的服务器应用程序的物联网设备运行一个GRPC服务器吗?IE。每个进程有10-20k个GRPC服务器? 最佳答案 你的意思是每个服务一个新的grpc监听TCP端口?Go无法修复它的可扩展性;大量的TCP监听器在操作系统范围内存在可扩展性问题。如果你的意思是一个TCP监听器对数千个其他设备进行反向代理,那么Go非常适合。Go擅长的是廉价的“线程”,因为它们不必分配完整的线程堆栈。在Go中,产生一个“goroutine”的成本约为4k,而不是与真实线程相比至少1MB的损失。grpc旨在通

  6. go - 使用 Golang 获取 GRPC 请求和响应 header - 2

    尝试使用golang语言提取GRPC请求和响应header。有没有办法提取标题。 最佳答案 您可以使用元数据客户端一元:varheader,trailermetadata.MD//variabletostoreheaderandtrailerr,err:=client.SomeRPC(ctx,someRequest,grpc.Header(&header),//willretrieveheadergrpc.Trailer(&trailer),//willretrievetrailer)//dosomethingwithheadera

  7. ssl - 为什么 grpc 服务器示例使用 net.Listen 而不是 tls.Listen - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭5年前。Improvethisquestion我正在设置一个将使用TLS进行客户端授权/身份验证的golanggrpc服务器。我见过的所有服务器设置示例都使用net.Listen()而不是tls.Listen()。这是为什么?import("crypto/tls""github.com/pkg/errors""google.golang.org/grpc""google.golang.org/grpc/credentials""net

  8. java - golang jsonrpc调用java json rpc - 2

    我试图通过jsonrpc将golang程序与java程序连接起来,但遇到了一些麻烦。我使用golang本地包中的“net/rpc/jsonrpc”包,以及java的“jsonrpc4j”。我在java中使用stream方式创建了一个server,因为golang的jsonrpc只是支持tcpinvoke。但是在golang客户端还是得到错误响应:err:invaliderrormap[code:-32602message:Invalidmethodparameters]同时java服务器也遇到了错误:com.fasterxml.jackson.databind.JsonMappingE

  9. amazon-web-services - 如何解决这个 gRPC 安装问题? - 2

    我按照以下步骤在我新启动的AWSEC2实例上安装gRPC:https://jitpaul.blog/2018/04/18/grpc-on-aws/当我尝试执行这一行时:sudoyuminstalllibgflags-devlibgtest-dev我收到这个错误:我不想搞砸任何事情,请帮忙。 最佳答案 改为尝试:sudoyuminstallgflags-devsudoyuminstallgtest-dev那应该安装libgflags-dev和libgtest-dev。 关于amazon-w

  10. go - 在一个 Go 应用程序中提供 gRPC 和 Restful 服务 - 2

    我有一个用Go编写的restful应用程序,现在我必须让这个应用程序也充当gRPC服务器(我已经创建了所需的文件)。我在端口8000上运行了restful端点,现在我有下一个问题:我可以在同一个实例中同时使用grpc和restful应用程序吗?我应该分配一个不同的端口来为gRPC服务吗?在这种情况下推荐的方法是什么?因为grpcstub将只是被我们的一些微服务消耗,但其余的将被被一些应用程序的前端消耗如果我可以为两者提供服务,我应该如何初始化服务器? 最佳答案 是的!如果您想将gRPC作为RESTful服务来提供服务,可以使用gRP

随机推荐