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性能更出色
那rpc和httpserver去对比,貌似没啥意义吧?
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端的异步方式 怎么做?
mark