一.什么是RPC

1.简介:

RPC:Remote Procedure Call,远程过程调用。简单来说就是两个进程之间的数据交互。

正常服务端的接口服务是提供给用户端(在Web开发中就是浏览器)或者自身调用的,也就是本地过程调用。

和本地过程调用相对的就是:假如两个服务端不在一个进程内怎么进行数据交互?使用RPC。

尤其是现在微服务的大量实践,服务与服务之间的调用不可避免,RPC更显得尤为重要。

2.原理:

计算机的世界中不管使用哪种技术,核心都是对数据的操作。RPC不过是将数据的操作垮了一个维度而已。

解决的问题本质上只是数据在不同进程间的传输。我们所说的RPC一般是指在传输层使用TCP协议进行的数据交互,

也有很多基于HTTP的成熟框架。

gRPC调用如下图所示:

上图描述了一个RPC的完整调用流程:

:client向client stub发起方法调用请求。

:client stub接收到请求后,将方法名,请求参数等信息进行编码序列化。

:client stub通过配置的ip和端口使用socket通过网络向远程服务器server发起请求。

:远程服务器server接收到请求,解码反序列化请求信息。

:server将请求信息交给server stub,server stub找到对应的本地真实方法实现。

:本地方法处理调用请求并将返回的数据交给server stub。

:server stub 将数据编码序列化交给操作系统内核,使用socket将数据返回。

:client端socket接收到远程服务器的返回信息。

:client stub将信息进行解码反序列化。

:client收到远程服务器返回的信息。

上图中有一个stub(存根)的概念。

stub负责接收本地方法调用,并将它们委托给各自的具体实现对象。

server端stub又被称为skeleton(骨架)。可以理解为代理类。而实际上基于Java的RPC框架stub基本上也都是使用动态代理。

我们所说的client端和server端在RPC中一般也都是相对的概念。

而所谓的RPC框架也就是封装了上述流程中2-9的过程,让开发者调用远程方法就像调用本地方法一样。

二.常用的RPC框架选型

  • Dubbo:

    阿里开源的基于TCP的RPC框架,基本上是国内生产环境应用最广的开发框架了。使用zookeeper做服务的注册与发现,使用Netty做网络通信。遗憾的是不能跨语言,目前只支持Java。

  • Thrift:

    Facebook开源的跨语言的RPC框架,通过IDL来定义RPC的接口和数据类型,使用thrift编译器生成不同语言的实现。据说是目前性能最好的RPC框架,只是暂没使用过。

  • gRPC:

    这个是我们今天要聊的重点。gRPC是Google的开源产品,是跨语言的通用型RPC框架,使用Go语言编写。 Java语言的应用同样使用了Netty做网络通信,Go采用了Goroutine做网络通信。序列化方式采用了Google自己开源的Protobuf。请求的调用和返回使用HTTP2的Stream。

  • SpringCloud:

    SpringCloud并不能算一个RPC框架,它是Spring家族中一个微服务治理的解决方案,是一系列框架的集合。但在这个方案中,微服务之间的通信使用基于HTTP的Restful API,使用Eureka或Consul做服务注册与发现,使用声明式客户端Feign做服务的远程调用。这一系列的功能整合起来构成了一套完整的远程服务调用。

如何选择

如果公司项目使用Java并不牵扯到跨语言,且规模并没有大到难以治理,我推荐Dubbo。如果项目规模大,服务调用错综复杂,我推荐SpringCloud。

如果牵扯到跨语言,我推荐gRPC,这也是目前我司的选择。即使Thrift性能是gRPC的2倍,但没办法,它有个好爹,现在我们的开发环境考虑最多的还是生态,不得不向Google爸爸臣服。

三.gRPC原理

一个RPC框架必须有两个基础的组成部分:数据的序列化和进程数据通信的交互方式。

对于序列化gRPC采用了自家公司开源的Protobuf。什么是Protobuf?先看一句网络上 大部分的解释:

Google Protocol Buffer(简称 Protobuf)是一种轻便高效的结构化数据存储格式,平台无关、语言无关、可扩展,可用于通讯协议和数据存储等领域。

上句有几个关键点:它是一种数据存储格式,跨语言,跨平台,用于通讯协议和数据存储。

这么看和我们熟悉的JSON类似,但其实着重点有些本质的区别:

JSON主要是用于数据的传输,因为它轻量级,可读性好,解析简单。

Protobuf主要是用于跨语言的IDL,它除了和JSON、XML一样能定义结构体之外,还可以使用自描述格式定于出接口的特性,

并可以使用针对不同语言的protocol编译器产生不同语言的stub类。所以天然的适用于跨语言的RPC框架中。

而关于进程间的通讯,无疑是Socket。Java方面gRPC同样使用了成熟的开源框架Netty。使用Netty Channel作为数据通道。传输协议使用了HTTP2。

通过以上的分析,我们可以将一个完整的gRPC流程总结为以下几步:

  • 通过.proto文件定义传输的接口和消息体。
  • 通过protocol编译器生成server端和client端的stub程序。
  • 将请求封装成HTTP2的Stream。
  • 通过Channel作为数据通信通道使用Socket进行数据传输。

四.gRPC的简单实现

项目需求:

go调用java传递请求参数,并接收java返回的数据。(项目中本人采用http方式建立go&java连接

为了体现gRPC跨语言的特性,我们使用两种语言:Go实现server端,Java作为client端来实现

1。安装Protocol Buffers,定义.proto文件

Step1:登录Google的 github下载对应Protocol Buffers版本 (本人下载all)

Step2:安装Protocol Buffer

参考博文:手把手教你如何安装Protocol Buffer

// Step1:安装 Protocol Buffer 依赖
// 注:Protocol Buffer 依赖于 autoconf、automake、libtool、curl
brew install autoconf automake libtool curl // Step2:进入 Protocol Buffer安装包 解压后的文件夹(我的解压文件放在桌面)
cd Desktop/protobuf-3.6. // Step3:运行 autogen.sh 脚本
./autogen.sh // Step4:运行 configure.sh 脚本
./configure // Step5:编译未编译的依赖包
make // Step6:检查依赖包是否完整
make check // Step7:开始安装Protocol Buffer
make install

Step3:检查Protocol Buffer是否安装成功

// 在 终端 下输入
protoc - - version

执行protoc命令如果返回如下信息说明安装成功

未完待绪。。。。

参考文章:gRPC基于golang和java的简单实现

Go语言入门篇-gRPC基于golang & java简单实现的更多相关文章

  1. Java入门篇(三)——Java流程控制

    前两篇已经了解了Java语言基础,本篇开始Java的流程控制.流程控制对任何一门编程语言都是至关重要的,它提供了控制程序步骤的基本手段. 一.复合语句 Java语言的复合语句是以整个块区为单位的语句, ...

  2. Java入门篇(二)——Java语言基础(下)

    上篇说到Java中的变量与常量,接下来就是简单的计算了,首先需要了解一下Java中的运算符. 六.运算符 1. 赋值运算符 赋值运算符即"=",是一个二元运算符(即对两个操作数进行 ...

  3. Go语言入门篇-Golang之文本编码处理

    Golang之文本编码处理

  4. Java入门篇(五)——Java的字符串/String类

    前面在举例时有出现过String的例子,当时肯定有一部分朋友不知道这个是做什么用的.其实String类是Java中一个比较特殊的类,字符串即String类,它不是Java的基本数据类型之一,但可以像基 ...

  5. RabbitMQ消息队列入门篇(环境配置+Java实例+基础概念)

    一.消息队列使用场景或者其好处 消息队列一般是在项目中,将一些无需即时返回且耗时的操作提取出来,进行了异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量. 在项目启 ...

  6. Go语言入门篇-JSON&http调用

    一.Decoder /(一)Decoder func DecoderExample(){ const jsonStream = ` { "Name" : "Ed" ...

  7. Go语言入门篇-环境准备

    一.GO语言特点 静态类型:首先要明确变量类型,如上所示. 编译型:指GO语言要被编译成机器能识别机器代码. GO语言开源. 编程范式:支持“函数式”和“面向对象” GO语言原生的支持并发编程:即GO ...

  8. 优雅的go语言--入门篇

    1.特点 1.静态类型,编译型的开源语言 2.脚本华的语法,支持多种编程范式(函数式&面向对象) 3.原生,给力的并发编程的支持 2.优势 1.脚本化的语法 2.静态类型+编译型,程序运行速度 ...

  9. Go语言入门篇-网络经验

    Go语言学习手册 golang*看云  golang圣经 wuYinIO 1.go语言开发中的坑 go新手容易犯的三个致命错误   Golang 需要避免踩的 50 个坑 2.go语言数据类型 map ...

随机推荐

  1. 一款超好用的第三方评论插件--Gittalk

    使用GITALK的背景: 1. 最近在做一个基于Java的个人博客系统,已经基本完工了,突然发现怎么没有评论的操作,如果再从头开始从数据库开始写的话,花费的代价有点大,于是乎我就在网上寻找一款适合我的 ...

  2. js快速将字符串数组转化为数字数组(互换)

    1.数字数组转化为字符串数组 var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]; arr.map(String); //结果: ['1', '2', '3', '4', '5 ...

  3. WebGL的shader

    WebGL的shader(着色器)有2种:vertexShader(定点着色器)和 fragmentShader(片段着色器) 顶点着色器:定义点的位置.大小 片元着色器:定义画出来的物体的材质(颜色 ...

  4. OpenPyXl的使用

    OpenPyXl的使用 开始在内存中使用 创建一个workbook 在刚开始使用openpyxl的时候,不需要直接在文件系统中创建一个文件,仅仅需要导入Workbook类并开始使用它: >> ...

  5. Wondershare Video Converter Ultimate 注册码 License

    这个软件可以直接将DVD iso转换成mp4播放,可以破解,还不错,特地记录 官网下载最新版: https://videoconverter.wondershare.com/gl/video-conv ...

  6. 从TCP到Socket,彻底理解网络编程是怎么回事

    进行程序开发的同学,无论Web前端开发.Web后端开发,还是搜索引擎和大数据,几乎所有的开发领域都会涉及到网络编程.比如我们进行Web服务端开发,除了Web协议本身依赖网络外,通常还需要连接数据库,而 ...

  7. Linux命令行提交更新冲突

    1.在harry目录下的hello文件第五行加一些内容 2.将修改后文件执行提交操作 提交成功,文件版本升为5 3.在sally目录下同样修改hello文件第五行 4.sally进行提交操作 发现提交 ...

  8. 对@repository,@Service, @Compent,@Controller注解的理解

    注解是没什么本质区别,都是声明作用,取不同的名字只是为了更好区分各自的功能. @Repository 用于标注数据访问组件,即DAO组件 @Service 用于标注业务层组件 @Controller ...

  9. ASP.NET的MVC设计模式

    当开发者听到“设计模式”这个词时,他们通常联想到两个场景.一组开发者正在讨论许多创造性意见,正在开会,但是却没有进行编码.另外一组人能制定出正确的计划,保证系统能够开发成功,代码可以重用. 而现实一般 ...

  10. oracle 常用工具类及函数

    j_param json; jl_keys json_list; -- 创建json对象j_param j_param := json(p_in_str); -- 校验param域是否缺少必填参数 j ...