這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
每種語言都有自己最擅長的領域,Golang 最適合的領域就是伺服器端程式。
做為伺服器端程式,需要考慮效能同時也要考慮與各種語言之間方便的通訊。採用http協議簡單,但效能不高。採用TCP通訊,則需要考慮封包、解包、粘包等等很多因素,而且想寫個高效的TCP服務,也很難。
其實,對於此類需求,採用RPC(Remote Procedure Call Protocol)編程最靠譜。使用 RPC 編程被認為是在分布式環境中啟動並執行客戶機和伺服器應用程式之間進行可靠通訊的最強大、最高效的方法之一。
Golang內建了對RPC支援,但只能適用於go語言程式之間調用,且貌似序列化、還原序列化效能不高。如果go語言能使用Thrift開發,那麼就如虎添翼了。可惜,thrift雖然很早就包含了golang的代碼,但一直都存在各種問題無法正確執行,以至於GitHub上有許多大牛小牛自行實現的Thrift代碼,但依然各種問題……直到0.9.1版本的發布!
是的,最近,Apache Thrift 0.9.1正式發布了。新版的Thrift終於對Golang提供了完美的支援。經過實驗,伺服器端、用戶端已經完美支援跨語言調用,且效能、尤其是記憶體佔用上,編譯型語言的特點展現出來,比java版的實現強了很多。
下面,我們採用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;
GoLangGo語言是由Google開發的一個開源項目,目的之一為了提高開發人員的編程效率。 Go語言文法靈活、簡潔、清晰、高效。它對的並發特性可以方便地用於多核處理器 和網路開發,同時靈活新穎的類型系統可以方便地編寫模組化的系統。Go整合了C、Python(PHP)、ErLang等語言的優點,主要特點有:
- 面向過程的改良, 不追求極致物件導向;
- 強型別、靜態編譯,幾乎沒有部署依賴(Java需要JVM,PHP/Python需要解析執行器,與靜態編譯的C/C++相當);效能優秀,與C/C++、Java同量級;
- 為分布式而生,優雅高效的並發能力,基於訊息的並發和同步;
- 自動記憶體回收,不用再擔心記憶體泄露;
- 內建各種進階語言類型,各種互連網協議和類庫;
gRPC一個高效能、通用的開源RPC架構,其由Google主要面向行動裝置 App開發並基於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.4、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來計算耗時;
測試資料和分析
一、 單進程下,長短串連,兩個RPC架構和兩大語言對比
小結:
- 整體上看,長串連效能優於短串連,效能差距在兩倍以上;
- 對比Go語言的兩個RPC架構,Thrift效能明顯優於gRPC,效能差距也在兩倍以上;
- 對比Thrift架構下的的兩種語言,長串連下Go 與C++的RPC效能基本在同一個量級,在短串連下,Go效能大概是C++的二倍;
- 對比Thrift&C++下的TSimpleServer與TNonblockingServer,在單進程用戶端長串連的情境下,TNonblockingServer因為存線上程管理開銷,效能較TSimpleServer差一些;但在短串連時,主要開銷在串連建立上,線程池管理開銷可忽略;
- 兩套RPC架構,以及兩大語言運行都非常穩定,5w次請求耗時約是1w次的5倍;
二、 多進程(線程,協程)下,兩大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可以較好的網路適應及擴充,協議內建的流控等功能未能進一步測試;
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。