为什么同时运行VSCode可以显着提高Windows服务器上的Node.js性能?

问题描述 投票:0回答:1

编辑:尽管我没有找到问题的答案,但是我找到了解决问题的方法:使用setImmediate()而不是setTimeout()。这确实提高了执行速度,而不会影响Web服务器的响应速度。但是,至少在目前,关于setTimeout()行为的奥秘仍未得到解答。


这是一个Node.js性能问题,令我非常困惑。

我仅使用内置的Node http库设置了在Windows 2012 R2上运行的node.js Web服务器应用程序。我没有使用任何其他Node库。为了开发该应用程序,我使用远程桌面连接从位于同一1GB LAN上的单独工作站登录服务器,然后使用服务器上的Visual Studio Code编辑Node.js源代码。使用>node webserver.js

通过单独的cmd窗口运行Web服务器

除了是网络服务器之外,该应用程序的主要目的是在多个小时内进行连续计算。计算非常简单,但很繁琐,并且大约在2000年左右进行了批量处理,使用了一个循环,该循环通过在每个循环结束时调用setTimeout( cycle_function, 1 )来启动下一个循环。如此设置循环,仅是为了允许应用程序响应传入的http请求而不会锁定。

循环的每次执行都称为滴答,并且滴答计数器保持不变。设置了一个单独的1000毫秒间隔计时器来运行一个小功能,该功能记录前一秒执行了多少次计算(滴答)周期,即每秒滴答。它通过记录刻度数,并在每次运行时计算先前的刻度数和当前的刻度数之间的差来实现此目的。

到目前为止可以进行计算的最新结果可以随时在网页中查看。 XMLHttp请求从工作站上html页面中的脚本发送到服务器。 Node Web服务器功能以结果的JSON结构进行响应,并将结果发送回浏览器(约250k)。该报告包括滴答计数和每秒滴答统计信息,它们显示在浏览器中。浏览器还使用计时器循环每100毫秒重复一次网页请求,以获取最新的最新信息。

它运行平稳,并留给自己的设备,网页上报告的周期数报告为每秒80个周期。我对此感到有些困惑,因为这相当低,而且我认为网页请求的频率可能太高了。但是,服务器CPU的负载不是很重(<3%),并且将网页刷新频率降低到1 /秒似乎对循环速率没有影响。完全关闭网络浏览器也无效。

现在为难题。如果我使用远程桌面登录到服务器,请打开VSCode(不打开任何源文件),然后在VSCode窗口中移动鼠标,然后计算周期速度显着加快。它可靠地从每秒80个循环的背景变为大约每秒500个循环的峰值。当我停止移动鼠标时,循环速率会降到每秒稳定的80。关闭VSCode并在服务器桌面或任何其他Windows应用程序(记事本,绘画等)上移动鼠标无效。似乎只有VSCode才有此影响。

为什么在VSCode窗口中增加鼠标活动会导致我完全独立的Node应用程序显着加速?

注:我认为VSCode中的活动可能会减慢统计信息的计算间隔-因此,如果它每6秒钟而不是每秒运行一次,那么它将记录更高的速率。但是,统计信息报告每秒在网页中更新一次,每秒周期也每秒变化一次,因此肯定要重新计算它。

以下是一些代码:

1)批计算周期:

// ========================================================================================== T1
/**
 * This function is triggered on a Timeout timer to run a calculation cycle
 */
var forestTimeTickCount = 0;
var ticksPerSecond = 0;
var prevTickCount = 0;

function forestTimeTick(){

    // increment the time tick count
    forestTimeTickCount++;
    if( forestTimeTickCount % 1000 == 0 ) log( "... tick " + forestTimeTickCount ) ;

    // update the plant calculations (batch of 2000)
    plants.timeTick(forestTimeTickCount);

    // if the clock is running, schedule the time for the next clock tick
    if( clockIsRunning ) setTimeout( forestTimeTick, 1 );
}

// calculator for the ticks per second
function calcTPS(){
    ticksPerSecond = forestTimeTickCount - prevTickCount;
    prevTickCount = forestTimeTickCount;
}

// repeat the ticks per second calculation every second
setInterval( calcTPS, 1000 );

2)这是Node.http Web服务器的创建:

//create a server object on port MainPort and listen for requests
try{

    var MainPortServer = http.createServer( (req, res) =>{

        let dataString = "";
        req.on( "data", chunk => {
            let sChunk = chunk.toString( "utf8" );
            log( "MainPort Chunk: ", sChunk );
            dataString += sChunk;
        });

        req.on( "end", () => {
            let qParams = getAllRequestData( req , dataString );
            handlePortMainPortRequest( req, res, qParams );

        });

    });

    MainPortServer.on("error", err=>{
        console.error( err );
        log( ">>>>>>>>>>>>> TERMINATING")
        process.exit (1);
    });

    MainPortServer.listen( mainPort);
    log( "Web server [MainPort] listening on port " + mainPort )

} catch(e) {
    console.error( e );
    log( ">>>>>>>>>>>>> TERMINATING")
    process.exit (1);
}

3)这是处理Web请求的功能:

function handlePortMainPortRequest (req, res, qParams ) {

    if( !qParams.path || qParams.path.length == 0 ) { qParams.path = [ "reset" ] };

    switch( qParams.path[0] ){

        // This case handles a request for JSON structure of latest status
        case "pcl":

            // generate the JSON to be sent
            var pcl = plants.getPlantStatusList();

            // add the tick count and ticks per second stats
            pcl.push( { tick: forest.ticks(), tps: forest.tps() } );

            res.setHeader( "Content-type", "application/json" );
            res.end( JSON.stringify( pcl ) );
            return; 

       //
       /// There are other cases here, not relevant to the question
       //

    }
}

网页剪辑

这显示了没有运行MSCode的正常报价速度(报价速度76 / ps):

Tick rate without MSCode running (76tps)

这是通过远程桌面在服务器上的MSCode上移动鼠标时的快照(滴答速率517 / s):

enter image description here

node.js
1个回答
0
投票

经过一些进一步的研究,这个问题的答案似乎在于定时器处理方面的异常,这影响了Node.js与系统定时器交互的方式。

我已将应用程序转移到了较新的服务器上,也将Windows Server 2012转移到了不同​​的主板/ CPU上,并重复了实验。

在此服务器上,运行VSCode对应用程序的性能没有影响。 AFAIK,服务器之间的唯一区别是,速度较慢的是运行在AMI主板上的(有些老化)富士通Intel XEON,而速度较快的是运行在华擎主板上的本地构建的Intel Core I7。 I7 / ASRock组合运行应用程序的速度比Xeon快3-5倍。

我的猜测是,运行VSCode并移动鼠标会导致多个中断,这些中断会导致Windows以某种方式缩短setTimout函数的运行时间-可能比其他方法更早检查计时器的经过时间。但是,进一步研究可能不值得麻烦。

感谢Alexei Levonkov和JFriend的评论。

© www.soinside.com 2019 - 2024. All rights reserved.