zoukankan      html  css  js  c++  java
  • NodeJS,我对“高、高、非”的一些看法

    ·众所周知

         NodeJS三大神器"事件驱动,V8,回调函数"。

    ·事件驱动,故名思议:等快递和收快递区别。NodeJS将原先大牛们掌握的神神秘秘的EPOLL走向大众化,这点是最大的贡献。当然事件驱动最早最有发言权的还是FLASH拥护者,在那个学校只教授顺序编程的年代里,一些广为流传的FLASH作品都源自事件驱动。

    ·V8:初闻该名比较深奥。网上有不少介绍不再累述,个人理解快在JIT和HASH定位对象上,跳过了CLASS代码。

    ·事件回调:这些年比较流行的风格,熟悉之后如沐清风,不熟悉的时候死活想不明白。

    仅接着,围绕着三项,无论是官方还是民间立即给NodeJS贴上了高性能、高并发、非阻塞I/O的标签。一篇繁荣景象的面前,要想真正将此落地,仍然有许多功课需要完成。

    ·最大的硬伤"单线程"

         NodeJS有句话就"除了代码,所有一切都是并行执行的"。这句话乍一看不是很明白,下面这个例子之后,

    req.on('end',function(){
    
    console.log(j+":"+body);
    
    // sleep(11); //BLOCK
    
    /* //FORK
    
    exec("systeminfo",function(err,stdot,stderr){
    
    res.end("aa"+'
    ');
    
    });
    
    */
    
    j++;
    
    res.write("ccc"+"
    ");
    
    });

    就会发现如果出现了要想完成SLEEP这件事,光靠Node本身一个进程一个线程根本不可能实现。但在其他高级语言C/JAVA中,SLEEP并不是一件什么大事,多起一个Thread就解决了。Node要想实现,只可能再Fork一个进程来分担老爹进程的活。所以,市面上所谓的Node多线程模块都是一种曲线救国,实际上是多进程,包括以后能不能火起来的H5-WebWorker。所以,批注中的取systeminfo,这个比较耗时的动作也只能依靠Fork来绕开,已达到表面上的高并发高性能。

        那是不是通过神器"事件回调就能绕开"了呢?答案也是否定的,即便是在单线程模式下最接近异步调用的eventproxy也无法彻底解决这一难题。如下代码,但这不妨碍eventproxy成为一件大众佳作。

    function sleep(milliSeconds) {
        var startTime = new Date().getTime();
        while (new Date().getTime() < startTime + milliSeconds);
    }
    
    function test300(obj){
        sleep(2000);
        obj.trigger("v3",300);
    }
    
    var EventProxy = require("eventproxy").EventProxy;
    
    var obj = new EventProxy();
    var counter = 0;
    var add= function (v1, v2, v3){
        console.log(v1+v2+v3+'');
    };
    obj.assign("v1", "v2", "v3", add);
    
    
    obj.trigger("v1",100);
    test300(obj);
    obj.trigger("v2",200);
    
    console.log("I'm Done");

        很多时候,有人甚至把NodeJS这一特性作为卖点,个人绝对这个卖点用不好就会啃人,如果真要说卖点,倒是可以往业务逻辑可读性上去扯开。但是事件回调又给代码可读性脱了不少后退。所以,现在想想老外的那句话真是一语中的,绝对算是非常负责的一句话。

    ·如果要做到"高、高、非"有办法吗?

    老实说,就官网API来说难度真是不小,很多的例子太过理想化了。所以多少是要借助其他高级语言的辅助,其中取巧的方法就是EPOLL+多线程,当然这前提得要有足够时间思考,因为这个水非常深,并且要步步为营。在没有强大的技术基础上,还是推荐下面一些技巧,希望对大家有所借鉴。

    1. 首先,充分评估要实现的功能,如果业务量少的阻塞,可以借fork的力(child_process模块)。
    2. 当你是一个服务端,如果有点良心的话,把settimeout留好,别外面人给拖死。写代码的都不容易。
    3. 当你是一个客户端,记得保护好自己,要设超时,NodeJS的http没有现成的timeout事件和模块,这个得要重写socket和streaming模块,很麻烦。
    4. 针对短连接,调优操作系统TIME_WAIT参数的CD时间。并且弃用Fork,想尽办法优化自身业务逻辑。

    ·万事不离"能量守恒定律"

         没有绝对的高性能服务器,就像世界上没有永动机一样,开门关窗、开窗关门。C/JAVA的Thread是以牺牲CPU为交换代价,Node的事件已自我承担单线程风险为代价。把复杂的运算成本留给谁,这是值得认真思考的一件事情。

  • 相关阅读:
    洛谷P2062 分队问题
    bzoj1800 飞行棋
    UVA11100 The Trip, 2007
    UVA11134 Fabled Rooks
    每天一道博弈论之“威佐夫博弈”
    每天一道博弈论之“A game”(伪博弈
    每天一道博弈论之“谁能赢呢?”
    每天一道博弈论之“牛的数字游戏”
    每天一道博弈论之“E&D”
    每天一道博弈论之“巴什博弈”
  • 原文地址:https://www.cnblogs.com/zacard-orc/p/3561344.html
Copyright © 2011-2022 走看看