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的参数;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Etcd V3新特性
Etcd 3.0已经于2016/07正式发布了,新版还是带来了不少新特性:
- RPC调用的优化,使用gRpc+ProtoBuff来替代原来的HTTP;
- 使用租约来替代原来的TTL;
- Watcher的优化
- ...
以下记录下一些官方文档以及前人的总结:
官方文档: https://coreos.com/blog/etcd3-a-new-etcd.html
中文翻译: http://www.infoq.com/cn/news/2016/07/etcd3
升级实录: https://segmentfault.com/a/1190000005947453c
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
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的命中率,从而提升性能。
- 考虑使用无锁的数据结构减少锁对并发性能造成的影响
- 只对关键节点进行优化,权衡优化和开发成本
GoLang里的DB连接池
DB is a database handle representing a pool of zero or more underlying connections. It's safe for concurrent use by multiple goroutines.
The sql package creates and frees connections automatically; it also maintains a free pool of idle connections. If the database has a concept of per-connection state, such state can only be reliably observed within a transaction. Once DB.Begin is called, the returned Tx is bound to a single connection. Once Commit or Rollback is called on the transaction, that transaction's connection is returned to DB's idle connection pool. The pool size can be controlled with SetMaxIdleConns.
开源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
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>