小测thrift和http在node.js中的性能对比
发布于 6 年前 作者 DoubleSpout 10228 次浏览 最后一次编辑是 5 年前 来自 分享

1、http代码,server端:

var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser({limit: '1mb'}));
var count = 1;
app.post('/rec/data', function(req, res){
  var bufLen = (req.body.content || '').length
  res.send({
	  len:bufLen,
	  count:count++
  })
});
app.listen(4001);

2、http代码,client端

var request = require('request');
var assert = require('assert');
var async = require('async')
var host = 'http://127.0.0.1:4001'
var buf = new Buffer(1024)
var content = buf.fill('a').toString()
console.time('http1000');
var count = 0
var needCount  = 0
var reqList = []
for(var i=1;i<=1000;i++){
	needCount += i
	reqList.push(function(callback){
		request.post({url:host+'/rec/data', 
		form: {content:content}}, 
		function(err,httpResponse,body){
			if(err){
				callback(err)
				return console.log(err)
			}
			//console.log(body)
			var resJson = JSON.parse(body)
			assert(resJson.len === content.length)
			count += resJson.count
			callback()
		})			
	})
}
async.series(reqList, function(err){
	if(err){
		console.log(err)
	}
	assert(count === needCount)
	console.timeEnd('http1000');
})

3、thrift接口文件:

struct SendMsg {
  1: string content,
}

struct ResMsg {
  1: i32 len = 1,
  2: i32 count,
}

service Message{
   ResMsg send(1:SendMsg data),
}

4、thrif端的server代码:

var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser());
var count = 1;
app.post('/rec/data', function(req, res){
  
  var bufLen = (req.body.content || '').length
  res.send({
	  len:bufLen,
	  count:count++
  })
});
app.listen(4001);

5、thrift端的client代码:

var thrift = require('thrift');
var assert = require('assert');
var async = require('async');
var transport = thrift.TBufferedTransport();
var protocol = thrift.TBinaryProtocol();
var Message = require('./gen-nodejs/Message.js');
var ttypes = require('./gen-nodejs/nodejs_msg_types.js');

var connection = thrift.createConnection("127.0.0.1", 9090, {
  transport : transport,
  protocol : protocol
});
connection.on('error', function(err) {
  console.log(err)
});

var client = thrift.createClient(Message, connection);
var buf = new Buffer(1024)
var content = buf.fill('a').toString()

console.time('thrift1000');
var count = 0
var needCount  = 0
var reqList = []
for(var i=1;i<=1000;i++){
	needCount += i
	reqList.push(function(callback){
		
		var sendData = new ttypes.SendMsg()
		sendData.content = content
		client.send(sendData, function(err, response) {
			if(err){
				return callback(err)
			}
			//console.log(response)
			assert(response.len == content.length)
			count += response.count
			callback()
		});
						
	})
}

async.series(reqList, function(err){
	if(err){
		console.log(err)
	}
	assert(count === needCount)
	console.timeEnd('thrift1000');
})

6、测试结果对比 网络环境,内网千兆,依次循环1000次,发送数据包为1k

http:
http1000: 4879ms
thrift:
thrift1000: 1254ms

网络环境,内网千兆,依次循环1000次,发送数据包为100k

http:
http1000: 16924ms
thrift:
thrift1000: 2105ms

网络环境,内网千兆,并行执行1000次,发送数据包为1k,就是将async改为parallel

http:
http1000: 4265ms
thrift:
thrift1000: 437ms

总结一下,在内网大数据包的传输上,还是用thrift性能更出色

11 回复

那rpc和httpserver去对比,貌似没啥意义吧?

http://thrift.apache.org/

The Apache Thrift software framework, for scalable cross-language services development, combines a software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, OCaml and Delphi and other languages.

thrift最后生成的是机器语言吧

@i5ting 有意义啊,现在很多后端跨语言服务通信都用http协议的 restful json,这个和thrift完成功能相似,是方案2选1

@DoubleSpout express 会做很多请求的处理,所以这个比较不合理,如果你使用纯node,我觉得倒是可以比比

@yakczh 跨语言的rpc调用库

@i5ting 额,就算用nodejs的http模块性能也不过对express提升50%左右吧,完全达不到thrift的性能。不过http更加灵活,thrift要定义接口文件,一些改动相对麻烦,至于性能和灵活就看项目需求了。

另外一般如果有内部跨语言通信http需求,我相信绝大部分的开发者会用expressjs搭一个http服务器来接受其他语言的http请求数据的。

不考虑PB?

@chemdemo 跨语言支持thrift做的挺好~

请教楼主 node client端的异步方式 怎么做?

回到顶部