rpcx框架介绍和简单测评
一、简介
rpcx与Alibaba Dubbo, Weibo Motan项目类似,项目地址:https://github.com/smallnest/rpcx
主要特色:
- 简单:非常容易使用,对比thrift,grpc来看,代码量和可读性都要优秀很多很多;
- 高性能:官方号称性能高于grpc,实测确实比grpc性能要好,但比thrift要差一些,详见后面数据;
- 跨语言: 可以与其它语言交互,但只是提供了一个gateway来转换协议,而thrift,grpc是可以做到跨语言直接调用的;
- 服务发现和治理:这个确实非常不错,比thrift,grpc之类的完整太多了,基本可以开箱即用;
其它特性(来自官网):
- Support raw Go functions. There's no need to define proto files.
- Pluggable. Features can be extended such as service discovery, tracing.
- Support TCP, HTTP, QUIC and KCP
- Support multiple codecs such as JSON, Protobuf, MessagePack and raw bytes.
- Service discovery. Support peer2peer, configured peers, zookeeper, etcd, consul and mDNS.
- Fault tolerance:Failover, Failfast, Failtry.
- Load banlancing:support Random, RoundRobin, Consistent hashing, Weighted, network quality and Geography.
- Support Compression.
- Support passing metadata.
- Support Authorization.
- Support heartbeat and one-way request.
- Other features: metrics, log, timeout, alias, circuit breaker.
- Support bidirectional communication.
- Support access via HTTP so you can write clients in any programming languages.
- Support API gateway.
- Support backup request, forking and broadcast.
二、性能测试
抽空做了个简单的性能测试,主要是评估rpc处理耗时:
1.测试环境
OS: ubuntu 16.04, kenerl 4.4.0
Go: 1.10.3
机器:Thinkpad T450
CPU:i5-5300u 2.3G
内存:8G
2.测试用例
服务端:只做简单的整数加法;
客户端:单个长连,10w次rpc请求计算总耗时;
3.数据和结论
Thrift(go):
- 总耗时:31s
- CPU使用率:84% (client, server使用率差不多)
gRpc(go):
- 总耗时:120s
- CPU使用率:87% (server cpu使用率略高一些)
rpcx(go):
- 总耗时:70s
- CPU使用率:70%-80% (server比client的使用率高10%)
粗略来看,Thrift性能仍能非常优秀,其次是rpcx,gRpc性能最差的;
三、小结
rpcx优点:
- 简单易用;
- 性能优秀;
- 配套的服务发现和服务治理;
- 完整的负载均衡、故障转移;
rpcx缺点:
- 跨语言调用;
Thrift 0.11.0 下go代码编译不过的问题解决
公司内的技术比较闭塞,以至于个人对外博客很久没有东东可以分享了;
最近稍有闲情,打算对比一下golang下的几个rpc框架,折腾thrift时发现了一个小问题记录;
一、环境
官网 https://thrift.apache.org/download 下载的thrift 0.11.0版本;
go get git.apache.org/thrift.git/lib/go/thrift 安装的最新thrift go包;
二、错误
在build server时,发现以下两类错误:
tomzhou@TZ-NB:/data/gocode/demo/bin$ go build server
# model
../src/model/MathService.go:103:14: not enough arguments in call to oprot.Flush
have ()
want (context.Context)
../src/model/MathService.go:120:16: not enough arguments in call to oprot.Flush
have ()
want (context.Context)
../src/model/MathService.go:133:16: not enough arguments in call to oprot.Flush
have ()
want (context.Context)
../src/model/MathService.go:147:24: not enough arguments in call to oprot.Flush
have ()
want (context.Context)
tomzhou@TZ-NB:/data/gocode/demo/bin$ go build server
# server
../src/server/main.go:36:44: cannot use handler (type *MathServiceImpl) as type model.MathService in argument to model.NewMathServiceProcessor:
*MathServiceImpl does not implement model.MathService (wrong type for Add method)
have Add(int32, int32) (int32, error)
want Add(context.Context, int32, int32) (int32, error)
三、原因
google一下发现不少人碰到这个问题,但没有人给出如何解决;
仔细查阅资料,发现根本原因是thrift在git上的go包更新了增加对go 1.7中的http.request + context的用法,部分函数中增加了context参数;但是官网下载的0.11.0.tgz包并没有更新;所以不兼容无法编译;
具体commit的原因参考:
https://github.com/apache/thrift/pull/1459
四、解决办法
需要解决两个问题:
1. 更新thrift
从 https://github.com/apache/thrift 下载最新zip包,编译thrift;
2. 服务实现的时候,前面增加一个context.Context的参数;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Golang学习资料参考
go语法学习:
https://tour.golang.org/welcome/1
官方类库查询:
https://golang.org/pkg/
golang web:
https://github.com/astaxie/build-web-application-with-golang
常见类库:
https://github.com/golang/go/wiki/Projects
IDE:
https://github.com/golang/go/wiki/IDEsAndTextEditorPlugins
Golang常见数据结构:
https://github.com/Workiva/go-datastructures
[转] Go高性能编程技巧
- 在高并发队列任务分发的场景中Ring Buffer比Channel的性能更好
- defer功能不是静态编译时提供的,而是运行时提供的,所以使用defer会产生一些额外的性能开销(了解就好,该用还是得用)
- encoding/json序列化是通过反射机制实现的,性能很差,可以使用ffjson生成encode/decode代码来提升性能。如果可能,使用MsgPack替代JSON,因为MsgPack性能更好。
- 在栈中创建对象比在堆中创建对象性能高,所以少用new来创建对象。需要创建大量临时对象的场景可以使用sync.Pool已减少GC的压力。
- 在性能要求特别高的并发访问同一个对象的场景中,可以通过增加padding的方式避免false sharing,提升CPU cache的命中率,从而提升性能。
- 考虑使用无锁的数据结构减少锁对并发性能造成的影响
- 只对关键节点进行优化,权衡优化和开发成本
开源RPC(gRPC/Thrift)框架性能评测
- 面向过程的改良, 不追求极致面向对象;
- 强类型、静态编译,几乎没有部署依赖(Java需要JVM,PHP/Python需要解析执行器,与静态编译的C/C++相当);性能优秀,与C/C++、Java同量级;
- 为分布式而生,优雅高效的并发能力,基于消息的并发和同步;
- 自动垃圾回收,不用再担心内存泄露;
- 内置各种高级语言类型,各种互联网协议和类库;
- gRPC & GoLang
- Thrift & GoLang
- Thrift & C++
syntax = "proto3";service MathService {rpc Add (AddRequest) returns (AddReply) {}}message AddRequest {int32 A = 1;int32 B = 2;}message AddReply {int32 X = 1;}
service MathService {i32 Add(1:i32 A, 2:i32 B)}
- client, server都是单进程,长连接,在单次连接内发起1w(5w)次rpc调用,计算耗时;
- client, server都是单进程,短连接,共发起1w(5w)次连接,每次连接单次RPC调用,计算耗时;
- 并发4个client进程,每个进程长连接10w rpc,服务端单进程多线程(协程),计算耗时;
- 整体上看,长连接性能优于短连接,性能差距在两倍以上;
- 对比Go语言的两个RPC框架,Thrift性能明显优于gRPC,性能差距也在两倍以上;
- 对比Thrift框架下的的两种语言,长连接下Go 与C++的RPC性能基本在同一个量级,在短连接下,Go性能大概是C++的二倍;
- 对比Thrift&C++下的TSimpleServer与TNonblockingServer,在单进程客户端长连接的场景下,TNonblockingServer因为存在线程管理开销,性能较TSimpleServer差一些;但在短连接时,主要开销在连接建立上,线程池管理开销可忽略;
- 两套RPC框架,以及两大语言运行都非常稳定,5w次请求耗时约是1w次的5倍;
- 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可以较好的网络适应及扩展,协议自带的流控等功能未能进一步测试;
GoLang下的gRPC, Thrift安装
一、gRPC for golang安装
1. 安装Go 1.4+,参考前一篇文章;
2. 安装ProtoBuff
下载protobuff
unzip protobuf-master.zip
cd protobuf-master
./autogen.sh
./configure --prefix=/usr
make
make check
make install
(www.iamadmin.com 特别提醒:受墙影响,某些网络可能无法下载gtest,导致在autogen.sh时失败,可以手动下载gtest-1.7.0.zip,并在运行autogen.sh脚本前,将此文件移到autogen.sh同目录,同时注释掉autogen.sh中的curl gtest的命令行)
3. go get -a github.com/golang/protobuf/protoc-gen-go
4. go get google.golang.org/grpc
成功安装后,可简单写个脚本,将当前目录所有proto转成go程序:
find ./ -type f -name "*.proto"|while read tFile
do
protoc "$tFile" --go_out=plugins=grpc:./
done
二、Thrift for golang安装
Thrift官方推荐的安装路径:
go get git.apache.org/thrift.git/lib/go/thrift
但最近在安装时发现此目录无法访问,可以使用下面的命令安装:
go get github.com/apache/thrift/lib/go/thrift
安装完后,默认生成的go模板,import的还是git.apache.org下的类库,导致无法编译,可以使用下面的命令生成go模板程序:
find ./ -type f -name "*.thrift"|while read tFile
do
thrift -gen go:thrift_import=github.com/apache/thrift/lib/go/thrift -out ../ "$tFile"
done
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
GoLang简单安装手册
Kango - cross-browser extension framework
[转]Go项目的目录结构
项目目录结构如何组织,一般语言都是没有规定。但Go语言这方面做了规定,这样可以保持一致性
1、一般的,一个Go项目在GOPATH下,会有如下三个目录:
其中,bin存放编译后的可执行文件;pkg存放编译后的包文件;src存放项目源文件。一般,bin和pkg目录可以不创建,go命令会自动创建(如 go install),只需要创建src目录即可。
对于pkg目录,曾经有人问:我把Go中的包放入pkg下面,怎么不行啊?他直接把Go包的源文件放入了pkg中。这显然是不对的。pkg中的文件是Go编译生成的,而不是手动放进去的。(一般文件后缀.a)
对于src目录,存放源文件,Go中源文件以包(package)的形式组织。通常,新建一个包就在src目录中新建一个文件夹。
2、举例说明
比如:我新建一个项目,test,开始的目录结构如下:
为了编译方便,我在其中增加了一个install文件,目录结构:
其中install的内容如下:(linux下)
之所以加上这个install,是不用配置GOPATH(避免新增一个GO项目就要往GOPATH中增加一个路径)
接下来,增加一个包:config和一个main程序。目录结构如下:
注意,config.go中的package名称必须最好和目录config一致,而文件名可以随便。main.go表示main包,文件名建议为main.go。(注:不一致时,生成的.a文件名和目录名一致,这样,在import 时,应该是目录名,而引用包时,需要包名。例如:目录为myconfig,包名为config,则生产的静态包文件是:myconfig.a,引用该包:import “myconfig”,使用包中成员:config.LoadConfig())
config.go和main.go的代码如下:
config.go代码
main.go代码
接下来,在项目根目录执行./install
这时候的目录结构为:
其中config.a是包config编译后生成的;bin/test是生成的二进制文件
这个时候可以执行:bin/test了。会输出:Hello, GO!
3、补充说明
1)包可以多层目录,比如:net/http包,表示源文件在src/net/http目录下面,不过源文件中的包名是最后一个目录的名字,如http
而在import包时,必须完整的路径,如:import “net/http”
2)有时候会见到local import(不建议使用),语法类似这样:
import “./config”
当代码中有这样的语句时,很多时候都会见到类似这样的错误:local import “./config” in non-local package
我所了解的这种导入方式的使用是:当写一个简单的测试脚本,想要使用go run命令时,可以使用这种导入方式。
比如上面的例子,把test/main.go移到src目录中,test目录删除,修改main.go中的import “config”为import “./config”,然后可以在src目录下执行:go run main.go
可见,local import不依赖于GOPATH
4、Windows下的install.bat
注,冒号和ok之间不应该有空格,但是放在一起总是会被wordpress转成一个表情。汗……
5、更新日志
1)2012-12-05 发布
2)2013-04-13 修正:目录名可以和包名不同,但建议一致;将make文件名改为install
Linux 学习 Eclipse美化,解决工具栏过大和 Javadoc背景色修改
Eclipse 在Ubuntu 下总是感觉上面的工具栏感觉特别的大,控件之间的空隙非常的大,和在Windows 下的感觉非常的不一样(毕竟是刚刚从windows叛逃出来),其实也不光光是Eclipse 是这样,其他也软件也同样有这个问题。尝试过通过更换主题来解决这样的问题,老是看着一个主题,审美总是会疲劳的。在网上找来一圈,
解决方案:
修改或者新建(系统默认是没有的)
/home/Your_username/.gtkrc-2.0 (ubuntu中 . 开头的文件默认是隐藏文件,快捷键Ctrl+H可显示隐藏文件)
复制如下的内容:
style "gtkcompact" {
font_name="Sans 9"
GtkButton::default_border={0,0,0,0}
GtkButton::default_outside_border={0,0,0,0}
GtkButtonBox::child_min_width=0
GtkButtonBox::child_min_heigth=0
GtkButtonBox::child_internal_pad_x=0
GtkButtonBox::child_internal_pad_y=0
GtkMenu::vertical-padding=1
GtkMenuBar::internal_padding=0
GtkMenuItem::horizontal_padding=4
GtkToolbar::internal-padding=0
GtkToolbar::space-size=0
GtkOptionMenu::indicator_size=0
GtkOptionMenu::indicator_spacing=0
GtkPaned::handle_size=4
GtkRange::trough_border=0
GtkRange::stepper_spacing=0
GtkScale::value_spacing=0
GtkScrolledWindow::scrollbar_spacing=0
GtkExpander::expander_size=10
GtkExpander::expander_spacing=0
GtkTreeView::vertical-separator=0
GtkTreeView::horizontal-separator=0
GtkTreeView::expander-size=8
GtkTreeView::fixed-height-mode=TRUE
GtkWidget::focus_padding=0
}
class "GtkWidget" style "gtkcompact"
style "gtkcompactextra" {
xthickness=1
ythickness=1
}
class "GtkButton" style "gtkcompactextra"
class "GtkToolbar" style "gtkcompactextra"
class "GtkPaned" style "gtkcompactextra"
注销系统再次登录,打开Eclipse 的界面果然是紧凑来,感觉不错,打开其他的程序界面也同样是紧凑来不少。
界面美观了不少,但是Eclipse的自动提示的背景色是黑色的,看起来也非常的难受:
修改方案:
打开终端移动到当前主题目录下:
cd/usr/share/themes/当前的主题名/
打开gtk-2.0/gtkrc文件:
sudo gedit gtk-2.0/gtkrc
寻找到“ntooltip_fg_color”和“ntooltip_bg_color”兩個屬性的值,如果沒有改屬性,可以自行添加,其值仿照windows的默認值,分別設定位:
tooltip_fg_color:#000000 tooltip_bg_color:#f2edbc
然後保存退出,打開系統外觀配置,切換一下主題,當切換回來的時候,修改的效果就生效了。
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>