gRPC vs Thrift

简介: 远程过程调用(Remote Procedure Call,RPC)服务于分布式架构,本文从分布式构架面临的问题,期望的结果,引出两种比较受关注的RPC框架,并从框架的出身、实现原理、特性、性能等方面做了对比分析,从而给出两者之间的选择建议。

远程过程调用(Remote Procedure Call,RPC)服务于分布式架构,本文从分布式构架面临的问题,期望的结果,引出两种比较受关注的RPC框架,并从框架的出身、实现原理、特性、性能等方面做了对比分析,从而给出两者之间的选择建议。

原文:http://blog.csdn.net/dazheng/article/details/48830511

简单分布式架构

这里写图片描述

  • 基本问题 
    • 传输什么样的数据,用哪种协议
    • 哪种方式数据交换的效率好
    • 服务端如何处理请求

需要扩展服务端时

  • 当你的服务超过最简单结构时,你想要 
    • 灵活性
    • 可扩展
    • 低延迟
    • 当然,你更想要简单

应该用这些协议吗

  • SOAP 
    • XML, XML还是XML
  • CORBA 
    • 美好的想法,糟糕的实现
    • 过渡设计和臃肿
  • DCOM, COM+

    • 主要用于windows平台
  • HTTP/TCP/Socket/Whatever 
    • 久经考验的
    • 但是缺少协议处理 
      • 需要自己实现协议封装
      • 自己实现客户端、服务端
      • 关注底层协议及状态

那我们需要什么

  • 不同的语言间可以透明交互 
    • 平台和语言无关
  • 可以很好的平衡 
    • 效率(时间、空间)
    • 开发易用性和执行速度
    • 使用已有的类库

RPC编程简介

  • 远程过程调用(Remote Procedure Call,RPC) 
    • 是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。
  • 为什么选择RPC 
    • 提高开发效率,开发人员可以把更多精力放在具体的接口实现,而不必考虑数据的底层传输问题。
    • 大多数rpc框架都是很多优秀开发人员的智慧结晶,它们的功能实现和执行效率都很优秀。
    • client端和server端必须遵循统一的接口规范,避免产生client和server之间接口或数据局结构不匹配的情况。

Google gRPC

  • gRPC 
    • gRPC是一个高性能、通用的开源RPC框架,其由Google 
      2015年主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf(Protocol 
      Buffers)序列化协议开发,且支持众多开发语言。gRPC提供了一种简单的方法来精确地定义服务和为iOS、Android和后台支持服务自动生成可靠性很强的客户端功能库。客户端充分利用高级流和链接功能,从而有助于节省带宽、降低的TCP链接次数、节省CPU使用、电池寿命。
    • 最新的Google API支持gRPC
    • 支持 C, C++, Node.js, Python, Ruby, Objective-C,PHP and C#
    • 当前版本Alpha
    • 协议 BSD
  • ProtoBuf 
    • 其由Google 2001年设计,2008年开源。
    • Google内部的服务几乎都是用的PB协议
    • 久经考验、充分验证、良好实现 
      -使用ProtoBuf: Google、Hadoop、ActiveMQ、Netty
    • 当前版本v3.0.0-alpha-3
    • 协议 BSD

Apache Thrift

  • thrift是一种可伸缩的跨语言服务的RPC软件框架。它结合了功能强大的软件堆栈的代码生成引擎,以建设服务,高效、无缝地在多种语言间结合使用。2007年由facebook贡献到apache基金,是apache下的顶级项目。
  • 支持C、C++ 、C# 、D 、Delphi 、Erlang 、Go 、Haxe 、Haskell 、Java 、JavaScript 
    、node.js 、OCaml 、Perl 、PHP 、Python 、Ruby 、SmallTalk
  • 使用Thrift:Hadoop、HBase、Cassandra、Scribe、LastFM、Facebook、 Evernote
  • 当前版本 0.9.2
  • 协议Apache License 2.0

典型操作模型

  • IDL-like语言定义接口
  • 运行工具生成java、python、Go等引用程序 
    • 如: thrift –gen go MyProject.thrift
  • 生成的引用程序哪怕再多,都是可读的
  • 在自己的程序中引用生成的程序
  • DO NOT EDIT!

Tthritr操作原理

这里写图片描述 
gRPC实现原理类似

Interface Definition Language (IDL)

gRPC

syntax = "proto3";  //protobuf3协议
package infg;

option optimize_for=SPEED;

message Person {
    string name = 1;
    map<string, int64> tel = 2;
}
message MediaRp {
    string uri = 1; 
    string title = 2;
    int32 width = 3; 
    int32 height = 4; 
    repeated Person person = 5; 
    enum Player {
        JAVA = 0;
        FLASH = 1;
    }
    Player player = 6; 
}
message MediaRq {
    string uri = 1;
}

service media {
    rpc Media(MediaRq) returns (MediaRp);
}
  • 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

Thrift

namespace go inft

typedef i32 int;
typedef i64 long;

enum Player {
    JAVA = 0;
    FLASH = 1;
}
struct Person {
    1: required string name;
    2: optional map<string, long> tel;
}
struct MediaRp {
    1: required string uri; 
    2: optional string title;
    3: required int width;
    4: required int height;
    5: required list<Person> person;
    6: required Player player;
}
struct MediaRq {
    1: required string uri;
}

service media {
    MediaRp media(1: MediaRq mediaRq);
}
  • 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

IDL 规则

  • 每列必须有一个唯一的正整数标识符
  • Thrift每列可以标识是“optional”、“required”,pb不可以,每列都是“optional”
  • gRPC service中,都必须有输入和输出,而且参数及返回值必须是定义好的message类型,而thrift中,输入和输出都可以为空,而且参数可以是定义好的struct,也可以是其他支持的类型
  • structs/messages都可以包含其他的structs/messages
  • 每列可以有“default”值
  • 同一个文件中, 多个structs/messages可以被引用
  • 可以引入其他文件定义
  • 整数标识符 
    • “= 1”, “ = 2” or “ 1:”, “ 2:”,在二进制文件中唯一标识一列
    • 保持数字标识不变非常重要
    • 数字1到15占用一个字节
    • 数字16到2047占用两个字节
    • 保持1到15用以最频繁使用的字段

比较

这里写图片描述 
这里写图片描述

这里写图片描述

这里写图片描述 
测试环境: 
116做RPC服务器,118做AS server、RPC客户端 
116 24核CPU 128G内存, 118 32核CPU 196G内存, 
都是万兆网

多版本

  • 系统应该支持多版本,哪怕是老的客户端调用新的服务端,或者相反
  • 在Thrift和protobuf中,多版本是通过字段标识符实现的
  • 正在使用的字段,请不要更新整数标识符
  • 可以删除不在使用的字段,原标识符可以分给其他字段
  • PB中[deprecated=true]标识废弃字段
  • 字段标识符和字段类型唯一标识一个字段
  • 不需要重新编译新版本

如何选择

  • 什么时候应该选择gRPC而不是Thrift 
    • 需要良好的文档、示例
    • 喜欢、习惯HTTP/2、ProtoBuf
    • 对网络传输带宽敏感
  • 什么时候应该选择Thrift而不是gRPC 
    • 需要在非常多的语言间进行数据交换
    • 对CPU敏感
    • 协议层、传输层有多种控制要求
    • 需要稳定的版本
    • 不需要良好的文档和示例

参考

gRPC官网 http://www.grpc.io/ 
Thrift官网 http://thrift.apache.org/ 
Pb vs thrift vsf avro http://www.slideshare.net/IgorAnishchenko/pb-vs-thrift-vs-avro 
golang gRPC示例 http://blog.csdn.net/dazheng/article/details/46544045 
THRIFT VS. PROTOCOL BUFFERS http://old.floatingsun.net/articles/thrift-vs-protocol-buffers/ 
Thrift使用指南 http://dongxicheng.org/search-engine/thrift-guide/



目录
相关文章
|
网络协议 Java 编译器
Thrift在C++中的使用
Thrift在C++中的使用
Thrift在C++中的使用
|
6月前
|
Java 编译器 测试技术
Thrift
Thrift是一个用于跨语言服务开发的工具,可以轻松实现不同语言间的通信和数据交换 【2月更文挑战第27天】
79 1
|
6月前
|
Dubbo Java 应用服务中间件
grpc&rpc
grpc&rpc
|
XML JSON 网络协议
gRPC介绍
gRPC介绍
|
XML JSON 编解码
Thrift 介绍
Thrift 介绍
169 0
|
JSON 网络协议 Dubbo
gRPC(一)入门:什么是RPC?
RPC是一种方法,而HTTP是一种协议。两者都常用于实现服务,在这个层面最本质的区别是RPC服务主要工作在TCP协议之上(也可以在HTTP协议),而HTTP服务工作在HTTP协议之上。由于HTTP协议基于TCP协议,所以RPC服务天然比HTTP更轻量,效率更胜一筹。
420 0
gRPC(一)入门:什么是RPC?
|
编译器 API
GRPC
GRPC
216 0
GRPC
|
Dubbo Java 应用服务中间件
5分钟学会 gRPC(中)
我猜测大部分长期使用 Java 的开发者应该较少会接触 gRPC,毕竟在 Java 圈子里大部分使用的还是 Dubbo/SpringClound 这两类服务框架。 我也是近段时间有机会从零开始重构业务才接触到 gRPC 的,当时选择 gRPC 时也有几个原因
|
自然语言处理 负载均衡 监控
5分钟学会 gRPC(上)
我猜测大部分长期使用 Java 的开发者应该较少会接触 gRPC,毕竟在 Java 圈子里大部分使用的还是 Dubbo/SpringClound 这两类服务框架。 我也是近段时间有机会从零开始重构业务才接触到 gRPC 的,当时选择 gRPC 时也有几个原因
|
负载均衡 Cloud Native Dubbo
5分钟学会 gRPC(下)
我猜测大部分长期使用 Java 的开发者应该较少会接触 gRPC,毕竟在 Java 圈子里大部分使用的还是 Dubbo/SpringClound 这两类服务框架。 我也是近段时间有机会从零开始重构业务才接触到 gRPC 的,当时选择 gRPC 时也有几个原因