小测thrift和http在node.js中的性能对比
发布于 2个月前 作者 DoubleSpout 472 次浏览 来自 分享

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性能更出色

9 回复

那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请求数据的。

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

回到顶部