在網(wǎng)頁(yè)編程領(lǐng)域,我一直使用ASP.NET或LAMP技術(shù)寫(xiě)代碼,這成為我生活的絕大部分內(nèi)容?,F(xiàn)在,新的亮點(diǎn)是node.js。它是一個(gè)在服務(wù)器端運(yùn)行javascript的框架,并據(jù)說(shuō)通過(guò)使用異步I/ O,提升了一些性能。

  該理論認(rèn)為,同步I/O 阻塞模型的工作原理是這樣的:    

   (注* 關(guān)于異步非阻塞模型的工作原理,可參見(jiàn):  是什么讓Node.js比Java更快? )

 

  I / O是一個(gè)典型的網(wǎng)絡(luò)事務(wù)(web transaction)中的最昂貴的部分。當(dāng)一個(gè)請(qǐng)求到達(dá)Apache Web服務(wù)器,它傳遞給PHP解釋器來(lái)執(zhí)行腳本的動(dòng)態(tài)內(nèi)容?,F(xiàn)在到了棘手的部分 - 如果PHP腳本想要從磁盤(pán)/數(shù)據(jù)庫(kù)讀取或存取數(shù)據(jù),這就成了最慢的一環(huán)。當(dāng)你調(diào)用PHP函數(shù) file_get_contents(),整個(gè)線(xiàn)程被阻塞,直到內(nèi)容獲取完成!直到你的腳本獲得文件內(nèi)容,服務(wù)器不能做任何事情。想像一下當(dāng)并發(fā)請(qǐng)求增加數(shù)倍時(shí),會(huì)發(fā)生什么?他們要排隊(duì),因?yàn)闆](méi)有可用的線(xiàn)程可以做這份工作,因?yàn)樗麄兌急籌/O阻塞了!

  這里談到了 node.js 中獨(dú)特的賣(mài)點(diǎn)緣于 node.js 在幾乎所有的功能中都使用異步I / O,在上述方案中,只要服務(wù)器線(xiàn)程一被釋放,文件檢索功能(fs.readFile)就被調(diào)用。然后,一旦在I / O完成后,節(jié)點(diǎn)才會(huì)執(zhí)行傳進(jìn)來(lái)的回調(diào)函數(shù)(早些時(shí)候通過(guò)fs.readFile)。在此期間,該有價(jià)值的線(xiàn)程就可以用于服務(wù)其它一些請(qǐng)求。

  所以,這就是關(guān)于它的理論。但我不是那種只是因?yàn)樗淮笏列麄骰蛘呙總€(gè)人都使用它就接受新風(fēng)潮的人。不,我想在知道事實(shí)真相,并親自來(lái)驗(yàn)證它。我想看看這個(gè)理論是否能經(jīng)得起實(shí)際操作的考驗(yàn)。 

  所以為了測(cè)試它,我自己寫(xiě)了兩個(gè)簡(jiǎn)單的腳本 —— 一個(gè)在PHP(托管在apache2的),另一個(gè)是JavaScript(托管在node.js上的)。測(cè)試本身是非常簡(jiǎn)單的。該腳本將:

  1,接受請(qǐng)求。 

  2,生成一個(gè)隨機(jī)的108千字節(jié)的字符串。 

  3,將字符串寫(xiě)到磁盤(pán)的文件上。 

  4,從磁盤(pán)中讀取內(nèi)容。 

  5,在返回的響應(yīng)流中返回字符串。 

  這是第一個(gè)腳本,index.php文件:

<?php
//index.php
$s=""; //generate a random string of 108KB and a random filename
$fname = chr(rand(0,57)+65).chr(rand(0,57)+65).chr(rand(0,57)+65).chr(rand(0,57)+65).'.txt';
for($i=0;$i<108000;$i++)
{
$n=rand(0,57)+65;
$s = $s.chr($n);
}
 
//write s to a file
file_put_contents($fname,$s);
$result = file_get_contents($fname);
echo $result;

  這是第二個(gè)腳本

//server.js
var http = require('http'); 
var server = http.createServer(handler);
 
function handler(request, response) {
    //console.log('request received!');
    response.writeHead(200, {'Content-Type': 'text/plain'});
 
    s=""; //generate a random string of 108KB and a random filename
    fname = String.fromCharCode(Math.floor(65 + (Math.random()*(122-65)) )) +
        String.fromCharCode(Math.floor(65 + (Math.random()*(122-65)) )) +
        String.fromCharCode(Math.floor(65 + (Math.random()*(122-65)) )) + 
        String.fromCharCode(Math.floor(65 + (Math.random()*(122-65)) )) + ".txt";
 
    for(i=0;i<108000;i++)
    {
        n=Math.floor(65 + (Math.random()*(122-65)) );
        s+=String.fromCharCode(n);
    }
 
    //write s to a file
    var fs = require('fs');
    fs.writeFile(fname, s, function(err, fd) {
            if (err) throw err;
            //console.log("The file was saved!");
            //read back from the file
            fs.readFile(fname, function (err, data) {
                if (err) throw err;
                result = data;
                response.end(result);
            }); 
        }
    );
}
 
server.listen(8124);
console.log('Server running at http://127.0.0.1:8124/');

  然后,然后我通過(guò)apache評(píng)測(cè)工具,向他們兩者一共發(fā)了2000個(gè)請(qǐng)求(200并發(fā))。當(dāng)我看到時(shí)間統(tǒng)計(jì)結(jié)果,我大吃一驚: 

#PHP:
Concurrency Level:      200
Time taken for tests:   574.796 seconds
Complete requests:      2000
 
#node.js:
Concurrency Level:      200
Time taken for tests:   41.887 seconds
Complete requests:      2000

  真相大白了。node.js比PHP快14倍!這結(jié)果是驚人的。它簡(jiǎn)直意味著node.js將在不久的未來(lái)成為編寫(xiě)性能驅(qū)動(dòng)應(yīng)用程序事實(shí)上的標(biāo)準(zhǔn),這也是毫無(wú)疑問(wèn)的!

  大家一致認(rèn)為NodeJS生態(tài)系統(tǒng)還沒(méi)有被廣泛開(kāi)發(fā)掘,并且大多數(shù)節(jié)點(diǎn)模塊,比如數(shù)據(jù)庫(kù)連接,網(wǎng)絡(luò)接入,公用設(shè)施等,正在積極開(kāi)發(fā)中。但盡管如此,看到這些結(jié)果后,實(shí)在是太顯而易見(jiàn)了。在發(fā)展node.js應(yīng)用程序所花費(fèi)的任何額外的努力都是非常值得的。 PHP的可能仍然保持著“網(wǎng)頁(yè)之王”的狀態(tài),但是作為焦點(diǎn)的node.js,我估計(jì)這種狀態(tài)不會(huì)持續(xù)很長(zhǎng)時(shí)間!

  更新 

  從下面一節(jié)看了一些評(píng)論之后,我覺(jué)得有義務(wù)也創(chuàng)建一個(gè)C#/mono 版本。不幸的是,這個(gè)已經(jīng)被證明是最慢的一組(約40秒1個(gè)請(qǐng)求)。也許是我的程序?qū)戝e(cuò)了,或者我的代碼有什么錯(cuò)誤。一旦等我閑下來(lái)我就會(huì)解決它,也許我的下一篇文章就是ASP.NET vs node.js vs PHP!。

  參考文獻(xiàn):

  1 https://en.wikipedia.org/wiki/Node.js

  2 http://notes.ericjiang.com/posts/751

  3 http://nodejs.org

  4.https://code.google.com/p/node-js-vs-apache-php-benchmark/wiki/Tests

  哈爾濱品用軟件有限公司致力于為哈爾濱的中小企業(yè)制作大氣、美觀(guān)的優(yōu)秀網(wǎng)站,并且能夠搭建符合百度排名規(guī)范的網(wǎng)站基底,使您的網(wǎng)站無(wú)需額外費(fèi)用,即可穩(wěn)步提升排名至首頁(yè)。歡迎體驗(yàn)最佳的哈爾濱網(wǎng)站建設(shè)。