业精于勤而荒于嬉 行成于思而毁于随

rpcx框架介绍和简单测评

[不指定 2018/08/21 14:59 | by ipaddr ]
最近关注了go的一些新项目,发现了一个比较牛逼的框架rpcx,此项目已经不是简单的rpc框架,而是一整套微服务框架,包含了服务发现、服务治理、负载均衡、故障转移等能力。


一、简介

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缺点:

  • 跨语言调用;

公司内的技术比较闭塞,以至于个人对外博客很久没有东东可以分享了;
最近稍有闲情,打算对比一下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

提交的代码参考:
https://github.com/apache/thrift/commit/5785279e2e809f6c56dbbe0eb41d13fb17c88bdd#diff-8a01e4124163225974263ecb577e8bf4


四、解决办法

需要解决两个问题:
1. 更新thrift
https://github.com/apache/thrift 下载最新zip包,编译thrift;

2. 服务实现的时候,前面增加一个context.Context的参数;


Etcd V3新特性

[不指定 2016/08/26 15:09 | by ipaddr ]

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

升级介绍: https://chromium.googlesource.com/external/github.com/coreos/etcd/+/HEAD/Documentation/op-guide/v2-migration.md

 

 

 

[转] Go高性能编程技巧

[不指定 2016/07/07 16:20 | by ipaddr ]
英文原文地址:

中文摘要:

  1. 在高并发队列任务分发的场景中Ring Buffer比Channel的性能更好
  2. defer功能不是静态编译时提供的,而是运行时提供的,所以使用defer会产生一些额外的性能开销(了解就好,该用还是得用)
  3. encoding/json序列化是通过反射机制实现的,性能很差,可以使用ffjson生成encode/decode代码来提升性能。如果可能,使用MsgPack替代JSON,因为MsgPack性能更好。
  4. 在栈中创建对象比在堆中创建对象性能高,所以少用new来创建对象。需要创建大量临时对象的场景可以使用sync.Pool已减少GC的压力。
  5. 在性能要求特别高的并发访问同一个对象的场景中,可以通过增加padding的方式避免false sharing,提升CPU cache的命中率,从而提升性能。
  6. 考虑使用无锁的数据结构减少锁对并发性能造成的影响
  7. 只对关键节点进行优化,权衡优化和开发成本

GoLang里的DB连接池

[不指定 2015/11/03 18:01 | by ipaddr ]

GoLang的数据库类库,自带了DB连接池功能,官方文档有介绍:

https://golang.org/pkg/database/sql/#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.


可以通过SetMaxIdelConns, SetMaxOpenConns来限制DB的连接数。

GoLang自动进行连接池的管理,默认情况下没有连接数限制,同时没有连接可用的话会新建连接;所以代码中没有正确的释放连接将导致连接数不断增加,比如以下代码:

 _, err := db.Query("SELECT uId FROM tUser WHERE userName='tomzhou'")

此代码,由于返回的Row未使用,所以此连接会一直占用不会释放;正确的做法:

rows, err := db.Query("SELECT uId FROM tUser WHERE userName='tomzhou'")

defer rows.Close()
//或在合适的地方主动关闭rows;




海量互联网业务系统只能依赖分布式架构来解决,而分布式开发的基石则是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.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可以较好的网络适应及扩展,协议自带的流控等功能未能进一步测试;

GoLang下的gRPC, Thrift安装

[不指定 2015/06/15 20:45 | by ipaddr ]

一、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简单安装手册

[不指定 2015/05/31 12:07 | by ipaddr ]

下载和编译
1. 下载 go1.4.2.src.tar.gz  至  /data/tmp/tomzhou
2. cd /data/tmp/tomzhou && tar zxvf go1.4.2.src.tar.gz && cd go
3. cd src/ && ./all.bash
4. mv /data/tmp/tomzhou/go /usr/local/

配置环境
export GOROOT=/usr/local/go/
export PATH=$PATH:$GOROOT/bin
export GOPATH=/data/workspace/comm/:/data/workspace/projA:/data/workspace/projB

将/data/workspace/comm放在最前面的作用在于,使用go install的包,都将安装在GOPATH第一个路径中。
我们使用这样一个公共的目录来存放系统所有的安装包;

mkdir -p /data/workspace/comm/src

mkdir -p /data/workspace/projA/src/mainA
mkdir -p /data/workspace/projB/src/mainB

按以上配置后,就可以简的使用下面命令编译:
go build mainA
go build mainB


最近发现,升级Chrome后访问某些HTTPS站点,Chrome给出明显的红叉警告证书不安全,比如:


 


Chrome官方对此有说明:

主要原因是:
1. SHA1算法已被证明不够健壮,容易受到攻击;
2. Google, Microsoft将在2017年淘汰SHA1算法;
3. 从Chrome 41版本开始,将对SHA1算法的数字证书进行安全告警;
4. 如果SHA1证书有效期到2016年,将出现黄色告警,如果SHA1证书有效期到2017年以后,将出现红色告警;
www.iamadmin.com原创,转载请注明)
解决办法:
1. 证书签发时升级到SHA2算法, 但是还是有不少客户端不支持,比如WindowsXP SP2以下,以及Android 2.2;
2. 证书有效期缩短在2015或2016年内, 等业界推动旧客户端废弃后,再上SHA2;

目前Google, Baidu这些都是控制有效期在2015年, 部分站点直接上了SHA2;
分页: 1/57 第一页 1 2 3 4 5 6 7 8 9 10 下页 最后页 [ 显示模式: 摘要 | 列表 ]