Golang经过Thrift框架完美实现跨语言调用


  每种语言都有本身最擅长的领域,Golang 最适合的领域就是服务器端程序。php

  作为服务器端程序,须要考虑性能同时也要考虑与各类语言之间方便的通信。采用http协议简单,但性能不高。采用TCP通信,则须要考虑封包、解包、粘包等等不少因素,并且想写个高效的TCP服务,也很难。java

  其实,对于此类需求,采用RPC(Remote Procedure Call Protocol)编程最靠谱。使用 RPC 编程被认为是在分布式环境中运行的客户机和服务器应用程序之间进行可靠通讯的最强大、最高效的方法之一。linux

  Golang内置了对RPC支持,但只能适用于go语言程序之间调用,且貌似序列化、反序列化性能不高。若是go语言能使用Thrift开发,那么就如虎添翼了。惋惜,thrift虽然很早就包含了golang的代码,但一直都存在各类问题没法正确执行,以致于GitHub上有许多大牛小牛自行实现的Thrift代码,但依然各类问题……直到0.9.1版本的发布!c++

  是的,最近,Apache Thrift 0.9.1正式发布了。新版的Thrift终于对Golang提供了完美的支持。通过实验,服务器端、客户端已经完美支持跨语言调用,且性能、尤为是内存占用上,编译型语言的特色展示出来,比java版的实现强了不少。golang

  下面,咱们采用golang实现一个Thrift的Server端和Client端程序。编程



http://blog.csdn.net/liuxinmingcode/article/details/45696237
服务器




 开源RPC(gRPC/Thrift)框架性能评测

   |   |   
[ 不指定 2015/07/31 11:06 | by  ipaddr ]
海量互联网业务系统只能依赖分布式架构来解决,而分布式开发的基石则是RPC;本文主要针对两个开源的RPC框架(gRPC、 Apache Thrift),以及配合GoLang、C++两个开发语言进行性能对比分析。C++、Thrift都是比较成熟的技术,先简单介绍一下GoLang以及gRPC;

GoLang
Go语言是由Google开发的一个开源项目,目的之一为了提升开发人员的编程效率。 Go语言语法灵活、简洁、清晰、高效。它对的并发特性能够方便地用于多核处理器 和网络开发,同时灵活新颖的类型系统能够方便地编写模块化的系统。Go集成了C、Python(PHP)、ErLang等语言的优势,主要特色有:
  • 面向过程的改良, 不追求极致面向对象;
  • 强类型、静态编译,几乎没有部署依赖(Java须要JVM,PHP/Python须要解析执行器,与静态编译的C/C++至关);性能优秀,与C/C++、Java同量级;
  • 为分布式而生,优雅高效的并发能力,基于消息的并发和同步;
  • 自动垃圾回收,不用再担忧内存泄露;
  • 内置各类高级语言类型,各类互联网协议和类库;

gRPC
一个高性能、通用的开源RPC框架,其由Google主要面向移动应用开发并基于HTTP/2协议标准而设计,基于ProtoBuf(Protocol Buffers)序列化协议开发,且支持众多开发语言。
gRPC基于HTTP/2标准设计,带来诸如双向流控、头部压缩、单TCP链接上的多复用请求等特性。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。
(tomzhou原创,转载请注明,我的博客: http://www.iamadmin.com/ )

本次测试对象主要有三个组合:
  • gRPC & GoLang
  • Thrift & GoLang
  • Thrift & C++
经过这三个组合,基本能够对比出gRPC/Thrift, go/c++二者在RPC下的性能;
此外,Thrift & C++还有多种服务器模式,我挑选了TSimpleServer、TNonblockingServer两种进行测试;

测试环境
CPU:Intel E5-2640 2.50GHz (8 cores)
内存:16GB
软件: CentOS 6.5,Go 1.四、Gcc 4.4.6,开启tcp reuse, tcp recycle;

测试逻辑
【远程加法运算】,参考IDL:

MathService.proto

syntax = "proto3";
service MathService {
rpc Add (AddRequest) returns (AddReply) {}
}
message AddRequest {
int32 A = 1;
int32 B = 2;
}
message AddReply {
int32 X = 1;
}

MathService.thrift

service MathService {
i32 Add(1:i32 A, 2:i32 B)
}

测试场景
  • client, server都是单进程,长链接,在单次链接内发起1w(5w)次rpc调用,计算耗时;
  • client, server都是单进程,短链接,共发起1w(5w)次链接,每次链接单次RPC调用,计算耗时;
  • 并发4个client进程,每一个进程长链接10w rpc,服务端单进程多线程(协程),计算耗时;

因为不一样语言,耗时统计存在误差,好比boost.timer在程序里计算出来的耗时明显偏小,因此统一使用linux命令time来计算耗时;

测试数据和分析

1、 单进程下,长短链接,两个RPC框架和两大语言对比





小结:

  • 总体上看,长链接性能优于短链接,性能差距在两倍以上;
  • 对比Go语言的两个RPC框架,Thrift性能明显优于gRPC,性能差距也在两倍以上;
  • 对比Thrift框架下的的两种语言,长链接下Go 与C++的RPC性能基本在同一个量级,在短链接下,Go性能大概是C++的二倍;
  • 对比Thrift&C++下的TSimpleServer与TNonblockingServer,在单进程客户端长链接的场景下,TNonblockingServer由于存在线程管理开销,性能较TSimpleServer差一些;但在短链接时,主要开销在链接创建上,线程池管理开销可忽略;
  • 两套RPC框架,以及两大语言运行都很是稳定,5w次请求耗时约是1w次的5倍;

2、 多进程(线程,协程)下,两大RPC框架和两大语言对比




小结:
  • Go语言自己的并发设计很是优秀,相关RPC框架默认支持协程和非堵塞,经过设置GOMAXPROCS能够很是容易的控制程序占用的CPU核数,编码角度无需关心并发实现;
  • C++有堵塞和非堵塞的选择,同时须要本身实现线程池(Thrift自带),高并发场景下编码须要特别设计;
  • Thrift框架性能比gRPC框架快两倍以上;
  • 堵塞模式下的Thrift&C++组合,只能同时针对单个客户端提供服务,四个客户端依次顺序执行;高并发调用场景下,基本不太可能采用;
  • 高并发场景下,使用Thrift框架,Go/C++性能至关,服务端单核处理能力可达3.2w/s。
总结:
  • Go语言性能强劲,语法上灵活、简单、清晰,易于发布和部署,可大规模应用于业务、运维、测试系统;(自动GC类语言,GC势必会影响业务逻辑执行性能,具体影响待海量业务下进一步验证)
  • gRPC作为Google开源出来的RPC框架,性能上明显低于Thrift; 但设计上更为规范,基于HTTP/2能够较好的网络适应及扩展,协议自带的流控等功能未能进一步测试;