Node.js 利用事件解决雪崩问题

Nodejs cyanprobe 8年前 (2016-03-31) 8123次浏览 已收录 13个评论

前言:

话说至今为止我还是不太清除事件存在的意义,然后各种纠缠 Geemo 兄,然后他给我讲了一大顿,各种洗脑。最后我一直保持我智障的状态,然后他甩了一个demo给我,我定睛一看,我勒个去,似曾相识的东东,这尼玛不就是我朴大大,写的那个事件解决雪崩问题的demo升级版么。

回顾(朴灵大大):

雪崩问题是在缓存失效的情景下,大并发高访问量同时涌入数据库中查询,数据库无法同时承受如此大的查询请求,进而往前影响到网站整体响应缓慢。那么在Node.js中如何应付这种情景呢。

var select = function (callback) {
        db.select("SQL", function (results) {
            callback(results);
        });
    };

以上是一句数据库查询的调用,如果站点刚好启动,这时候缓存中是不存在数据的,而如果访问量巨大,同一句SQL会被发送到数据库中反复查询,影响到服务的整体性能。一个改进是添加一个状态锁。

var status = "ready";
var select = function (callback) {
        if (status === "ready") {
            status = "pending";
            db.select("SQL", function (results) {
                callback(results);
                status = "ready";
            });
        }
    };

但是这种情景,连续的多次调用select发,只有第一次调用是生效的,后续的select是没有数据服务的。所以这个时候引入事件队列吧:

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";
            });
        }
    };

这里利用了EventProxy对象的once方法,将所有请求的回调都压入事件队列中,并利用其执行一次就会将监视器移除的特点,保证每一个回调只会被执行一次。对于相同的SQL语句,保证在同一个查询开始到结束的时间中永远只有一次,在这查询期间到来的调用,只需在队列中等待数据就绪即可,节省了重复的数据库调用开销。由于Node.js单线程执行的原因,此处无需担心状态问题。这种方式其实也可以应用到其他远程调用的场景中,即使外部没有缓存策略,也能有效节省重复开销。此处也可以用EventEmitter替代EventProxy,不过可能存在侦听器过多,引发警告,需要调用setMaxListeners(0)移除掉警告,或者设更大的警告阀值。

理解:

之前看这个一头雾水,首先状态锁的问题,状态锁是不是在锁一个查询。乍一看,感觉并无什么卵用。然后事件怎么能通过事件返回了所有并发的结果而进行一次查询。自己画了一张图,来解释下,首先这依赖于单线程和异步,状态锁在并发状态下被改变即是在所有异步并发中被改变(单线程);那么我们假设第一个异步访问,他执行了以上代码,当执行完查询,他会在当前时间线以前以后的状态锁改变(跳过数据库查询步骤),阻止其他异步并发的查询,触发所有事件,返回查询的内容给所有异步并发。下一阶段,新的并发请求来到,再次进行查询。这样面对很大的并发时候之后有很少量的数据查询,极大的减轻了数据库鸭梨。 画了一张图:
eventemitter

后记:

这个东西显然勇于相同请求的,如载入首页内容。如果执行不同的数据库查询,在大并发情况下,将会导致最新结束的查询结果被copy至后面的一切请求。用了一下午时间折腾懂了,但是...我还是不知道事件有什么卵用。
 


CyanProbe , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Node.js 利用事件解决雪崩问题
喜欢 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(13)个小伙伴在吐槽
  1. 没看出什么大作用
    米粒博客2016-03-31 20:45 回复
  2. 前端大拿呀,现在前端开发的人,少而金贵
    历史上的今天2016-04-02 12:20 回复
  3. 太专业的内容了,有需要的时候来转转,找解决方法
    优妈妈博客2016-04-05 09:22 回复
  4. 过来学习,打打酱油。
    电影王国2016-04-05 20:12 回复
  5. 分享是美德!虽然看不懂。。。
    颜如玉美图2016-04-05 20:12 回复
  6. 洗脑之后,顿悟?
    themebetter2016-04-06 15:06 回复
  7. 不错,不错,看看了!
    zengda2016-04-06 15:42 回复
  8. 卧槽,我出名了。。。
    geemo2016-05-28 21:50 回复
  9. 别名:单例模式
    leoskey2016-11-19 12:02 回复