请教《深入浅出node.js》中的一个关于解决雪崩的问题
发布于 10 年前 作者 whatispython 5295 次浏览 最后一次编辑是 8 年前

原文链接如下: http://www.infoq.com/cn/articles/tyq-nodejs-event,作者为淘宝的朴灵,原名田永强

其中提到了通过将请求的回调函数压入事件队列中来解决雪崩的办法,核心代码如下:

var proxy = new EventProxy();
var status = "ready";
var select = function (callback) {
    proxy.once("selected", callback);
    if (status === "ready") {
        status = "pending";
        db.select("SQL", function (results) {
            proxy.emit("selected", results);
            status = "ready";
        });
    }
};

由于没找到完整代码,我便创建了一个http server来验证,验证结果确实是db查询的次数大大减少,补全后的核心代码如下:

var _db,
    status = 'ready',
    event = new emitter();

event.setMaxListeners(0);
mongodb.open(function(err, db) {
    _db = db;
});

http.createServer(function(request, response) {
    event.once('got', function(result) {
        response.writeHead(200);
        response.end(result.name);
    });

    if (status == 'ready') {
        status = "pendding";
        _db.collection('users', function(err, collection) {
            collection.findOne({name: 'leo'}, function(err, doc) {
                doc && event.emit('got', doc);
                status = "ready";
            });
        });
    }
}).listen(9090);

我现在的问题就是我的代码这样写对吗?请高人指点一二。

7 回复

我觉得加入不加这个status 判断状态的话,假如有10个并发,一个一个的接着去连接数据库,回调函数压入事件队列中,等操作系统处理完回传给回调函数。假如数据库读写响应出现瓶颈的时候,回传数据给node就慢, 当上一个请求还没处理完的时候,这个请求又开始处理,这样的话就会造成不必须的系统消耗,降低系统的吞吐量。

你的意思是说加入不加入这个状态锁都不会影响性能吗?但是实际上聪ab测试的结果来看的话,rps(request per second)差了三倍。

还想问一下这个问题,需要为每个请求打开并且关闭一次数据库吗?你可以看到我现在的代码是打开数据库连接后就没有关闭的,这样有关系吗?

要加状态锁。

node是单线程异步IO的,没有必要打开在关闭数据库,之所以要打开和关闭数据库,因为像php就是同步操作io的,一个请求跑在一个线程上,然后操作数据库,假如这时候不关闭的话,线程越多,数据库所占的内存也会增多,最后导致服务器crash掉, 而 node是单线程的,始终只有单个数据库进程在处理,如果还频繁的打开和关闭数据库,会造成不必要的浪费。

这个问题太关键了,不胜感激!

可以告诉我你的邮箱地址吗?

回到顶部