目录
[TOC]
前言
gRPC
是由Google
主导开发的RPC
框架, 使用HTTP/2
协议并用ProtoBuf
作为序列化工具.
在gRPC
里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得用户能够更容易地创建分布式应用和服务. grpc官网
RPC
什么是RPC?
RPC: Remote Procedure Call远程过程调用.它是一种通过网络从远程计算机程序上请求服务, 而不需要了解底层网络技术的协议.简单的理解就是:从一台机器(客户端)上通过参数传递的方式调用另一台机器(服务器)上的一个函数或方法(可以统称为服务)并得到返回的结果
有如下特点:1
2
31. RPC 会隐藏底层的通讯细节(不需要直接处理Socket通讯或Http通讯)
2. RPC 是一个请求响应模型。客户端发起请求,服务器返回响应(类似于Http的工作方式)
3. RPC 在使用形式上像调用本地函数(或方法)一样去调用远程的函数(或方法)。
下面这张图展示了RPC的原理:
RPC的发展路程
1 | 1. ONC RPC (开放网络计算的远程过程调用),OSF RPC(开放软件基金会的远程过程调用) |
我们现在用的非常广泛的restful web service
也可以理解为RPC
的实现
thrift
thrift
是一个RPC
的实现, thrift
最初由facebook
研发, 现已成为apache
下面的开源项目.
IDL
thrift
有自己的一套接口定义语言: IDL(Thrift interface description language), 这里就忽略IDL
的语法
helloword
我们拿java
和python
进行测试, 现在有两个程序分别由java
和python
编写, 现模拟它们之间的通信1
2
3
4
5namespace java com.test
service HelloWorldService {
string sayHello(1:string username)
}
thrift的优点
1 | 1. 支持的语言广泛 |
thrift的缺点
1 | 1. 基本没有官方文档 |
gRPC
gRPC
客户端和服务端可以在多种环境中运行和交互 - 从google
内部的服务器到你自己的笔记本,并且可以用任何 RPC
持的语言来编写。所以,你可以很容易地用Java
创建一个gRPC
服务端,用Go、Python、Ruby
来创建客户端. 可以在github
上找到各种语言的实现grpc
protocal buffers
gRPC
默认使用protocal buffers
, 这是google
开源的一套成熟的结构数据序列化机制.1
2
3
41. 定义一种message的格式(.proto文件)
2. 使用编译器对message进行编译, 转化为对应语言的代码(转化为一个类)
3. 提供对应语言的API来操作这些message
4. 对旧的数据格式进行兼容
Powerful IDL
Define your service using Protocol Buffers, a powerful binary serialization toolset and language.
示例: PersonMsg.proto
文件1
2
3
4
5
6
7
8
9
10
11
12
13message Person {
// ID(必需)
required int32 id = 1;
// 姓名(必需)
required string name = 2;
// email(可选)
optional string email = 3;
// 朋友(集合)
repeated string friends = 4;
}
上面的1、2、3、4是unique numbered tag
,是一个唯一标识
编译成java文件
有了.proto
文件, 接下来生成类(java
代码)1
c:\protoc.exe --java_out=E:\god\ProtocTest PersonMsg.proto
生成了一个PersonMsg.java
使用API
编写代码对message
进行序列化和反序列化1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;
public class Test {
public static void main(String[] args) throws IOException {
// 按照定义的数据结构,创建一个Person
PersonMsg.Person.Builder personBuilder = PersonMsg.Person.newBuilder();
personBuilder.setId(1);
personBuilder.setName("马强");
personBuilder.setEmail("xxg@wahley.com");
personBuilder.addFriends("Friend A");
personBuilder.addFriends("Friend B");
PersonMsg.Person xxg = personBuilder.build();
// 将数据写到输出流,如网络输出流,这里就用ByteArrayOutputStream来代替
ByteArrayOutputStream output = new ByteArrayOutputStream();
xxg.writeTo(output);
// -------------- 分割线:上面是发送方,将数据序列化后发送 ---------------
byte[] byteArray = output.toByteArray();
// -------------- 分割线:下面是接收方,将数据接收后反序列化 ---------------
// 接收到流并读取,如网络输入流,这里用ByteArrayInputStream来代替
ByteArrayInputStream input = new ByteArrayInputStream(byteArray);
// 反序列化
PersonMsg.Person xxg2 = PersonMsg.Person.parseFrom(input);
System.out.println("ID:" + xxg2.getId());
System.out.println("name:" + xxg2.getName());
System.out.println("email:" + xxg2.getEmail());
System.out.println("friend:");
List<String> friends = xxg2.getFriendsList();
for (String friend : friends) {
System.out.println(friend);
}
}
}
HTTP/2
Building on the HTTP/2 standard brings many capabilities such as bidirectional streaming, flow control, header compression, multiplexing requests over a single TCP connection and more.
These features save battery life and data usage on mobile devices while speeding up services and web applications running in the cloud.
gRPC
是基于HTTP/2
标准设计, 带来了诸如双向流,流控,头部压缩, 单TCP
连接上的多路复用等等, 这些特性使得它在移动设备上表现更好, 更省电和节省空间占用(节省带宽、降低TCP
链接次数、节省CPU
使用和延长电池寿命)
使用gRPC
想使用gRPC
, 可以在github
上搜索grpc
, 比如java版本的grpc-java
gRPC和thrift比较
该选择gRPC还是thrift?
什么时候选择gRPC?
1 | 1. 需要良好的文档、示例 |
什么时候选择thrift?
1 | 1. 需要在非常多的语言间进行数据交换 (支持语言更多) |
etcd3中的gRPC
最新发布的etcd3
中使用了的gRPC
Native etcd3 clients communicate over a gRPC protocol. The protocol messages are defined using protobuf, which simplifies the generation of efficient RPC stub code and makes protocol extensions easier to manage. For comparison, even after optimizing etcd2’s client-side JSON parsing, etcd3 gRPC still holds a 2x message processing performance edge over etcd2. Likewise, gRPC is better at handling connections. Where gRPC uses HTTP2 to multiplex multiple streams of RPCs over a single TCP connection, a JSON client must establish a new connection for every request.
下面是centos
中官网的对使用gRPC
的介绍
grpc中关于使用rest的介绍
CoreOS中关于grpc的介绍
参考
Take a REST with HTTP/2, Protobufs, and Swagger
gRPC with REST and Open APIs
etcd3: A new etcd
谁能用通俗的语言解释一下什么是RPC框架?
什么是 RESTful ?到底 REST 和 SOAP、RPC 有何区别?
thrift入门教程
Protocol Buffer 基础教程: Java
gRPC vs Thrift
Java使用Protocol Buffers入门四步骤
gRPC 官方文档中文版