利用 Node.js events 解决雪崩现象

雪崩问题就是在浏览器缓存失效后,并发访问量大量涌入数据库执行查询操作,导致数据库无法同时承受如此大的访问量,从而影响网站效果。

在 Node.js 中一句数据库查询的代码为:

var select = function (callback) {
    db.select('SQL', function (results) {
        // 比如传入的函数是展示数据,那么该句的作用就是将查询后返回的数据展示出来
        callback(results);
    });
};

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

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

代码分析:
对于每一次查询,都会通过 once 方法订阅 selected 事件。当某个查询正在进行时,其他同时到达的查询处于 pending 状态,在订阅了 selected 事件后什么都不做,而请求的回调被压入事件队列中。当那个查询结束时,执行 emit 方法发布 selected 事件并更新状态。此时,那些订阅了 selected 事件的查询的回调函数被依次调用,并传入查询结果 results 作为参数。由于 once 方法的(执行一次就会将监视器移除)特点,每个查询的回调只会被执行一次。执行回调函数以后,由于 status 变为 ready,又可以响应其他的查询。

在这个过程中,对于相同的 SQL 语句,保证在同一个查询开始到结束的时间中永远只有一次,在这查询期间到来的相同查询,只需在队列中等待数据就绪即可。这些相同查询只是利用了这次查询的结果执行了回调而已,并没有查询数据库,节省了重复的数据库调用开销。

由于 Node.js 单线程执行的原因,此处无需担心状态问题。这种方式其实也可以应用到其他远程调用的场景中,即使外部没有缓存策略,也能有效节省重复开销。

此处也可以用 EventEmitter 替代 EventProxy,不过可能存在侦听器过多,引发警告,需要调用 setMaxListeners(0) 移除掉警告,或者设更大的警告阀值。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,084评论 19 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 33,150评论 18 399
  • 一. Java基础部分.................................................
    wy_sure阅读 9,291评论 0 11
  • 原文:https://my.oschina.net/liuyuantao/blog/751438 查询集API 参...
    阳光小镇少爷阅读 9,259评论 0 8
  • 《长恨歌》原著王安忆——“一个女人四十年的情与爱,被一只细腻而绚烂的笔写得哀婉动人。”文本本身是得过茅盾文学奖的,...
    江海澜阅读 5,653评论 0 4

友情链接更多精彩内容