翻譯:瘋狂的技術宅
原文標題:A Node.js speed dilemma: AJAX or Socket.IO?
原文連接:http://www.cubrid.org/blog/no...
本文首發微信公衆號:充實的腦洞。轉載需註明出處!javascript
當我開始本身的第一個Node.js項目時,我發現的第一件事就是如何處理瀏覽器(客戶端)和中間件之間的通訊(中間件是用CUBRID Node.js驅動編寫的(node-cubrid)的Node.js應用與CUBRID 8.4.1數據庫交換信息)。html
我已經很是熟悉AJAX了,可是在學習Node.js時,我發現了Socket.IO模塊,甚至在互聯網上發現了一些很是不錯的代碼示例... 很是好用(重用)...java
所以,這很快成爲一個難題:應該選哪一個,Ajax仍是sockets.io?node
顯然,因爲個人經驗很是有限,因此我須要更多的信息。換句話說,應該好好的Google一番 :)jquery
顯然相關的信息很是多,可是須要過濾掉那些沒用的 "噪音",並獲得真正有用的東西。讓我跟你們分享一下關於這個話題的一些連接:web
http://howtonode.org/websocke...segmentfault
總而言之,這是我發現的:
Socket.IO(一般)用的是客戶端和服務器(中間件)之間的持續鏈接,所以你會達到服務器端資源所容許的併發鏈接數上限(而相同的資源能夠支持更多的AJAX異步請求)。
使用AJAX,你能夠請求RESTful接口。這意味着您能夠利用現有的 HTTP 服務,例如:代理緩存請求和帶條件的GET請求。
與 Socket.IO 相比,AJAX 有更多(通訊)數據開銷(例如:HTTP頭,Cookie等)。
AJAX一般比Socket.IO快 ...
當使用Socket.IO時,能夠進行雙向通訊,其中每一方——客戶端或服務器均可以發起請求。在AJAX中,只有客戶才能發起請求!
Socket.IO有更多的傳輸選項,包括Adobe Flash。
如今,對於我本身的應用,我最感興趣的是發起請求並從(Node.js)服務器獲取數據的速度!
關於與CUBRID數據庫中間件的數據通訊,由於大約90%的數據訪問是隻讀的,一個好的數據緩存機制顯然是一個不錯的途徑!但關於這個,我下次再談。
因此我決定對他們的(Ajax和socket)速度進行測試,看看哪個更快(至少在個人硬件和軟件環境下)!個人硬件環境是:i5處理器,8GB內存和英特爾X25 SSD硬盤。
可是嚴格來講,任何性能測試都取決於您的硬件和軟件配置,在你本身的環境中去測試終歸是一個好主意,不要過於依賴你在互聯網上找到的各類信息,更多的問題須要你本身去發現!
我要作的測試須要知足如下要求:
測試:
AJAX
Socket.IO 持續鏈接模式
Socket.IO 非持續連接模式
測試客戶端與服務器之間進行十、100,、250、500條數據交換時的狀況
中間件服務器(Node.js Web 服務器)和客戶端(瀏覽器)之間交換的每條數據都是一個4KBytes的隨機數據串
在 release(非調試)模式下運行服務器
用Firefox做爲客戶端
最小化控制檯消息輸出,不論是服務器端仍是客戶端
在客戶端頁面硬性從新加載後進行每一個測試
每次測試至少重複3次,以確保結果一致
我建立了一小型的小Node.js服務器,用它處理客戶端請求:
io.sockets.on('connection', function (client) { client.on('send_me_data', function (idx) { client.emit('you_have_data', idx, random_string(4096)); }); });
這是我用於測試的JS客戶端腳本:
var socket = io.connect(document.location.href); socket.on('you_have_data', function (idx, data) { var end_time = new Date(); total_time += end_time - start_time; logMsg(total_time + '(ms.) [' + idx + '] - Received ' + data.length + ' bytes.'); if (idx++ < countMax) { setTimeout(function () { start_time = new Date(); socket.emit('send_me_data', idx); }, 500); } });
此次,對於每次數據交換,我都打開一個新的socket-io鏈接。
Node.js服務器代碼與上一個相似,可是我決定在鏈接以後當即發送客戶端數據,由於每次數據交換都會啓動一個新的鏈接:
io.sockets.on('connection', function (client) { client.emit('you_have_data', random_string(4096)); });
客戶端測試代碼:
function exchange(idx) { var start_time = new Date(); var socket = io.connect(document.location.href, {'force new connection' : true}); socket.on('you_have_data', function (data) { var end_time = new Date(); total_time += end_time - start_time; socket.removeAllListeners(); socket.disconnect(); logMsg(total_time + '(ms.) [' + idx + '] - Received ' + data.length + ' bytes.'); if (idx++ < countMax) { setTimeout(function () { exchange(idx); }, 500); } }); }
最後是AJAX測試...
Node.js服務器代碼與之前的代碼不一樣:
res.writeHead(200, {'Content-Type' : 'text/plain'}); res.end('_testcb(\'{"message": "' + random_string(4096) + '"}\')');
至於客戶端代碼,這是我之前測試的:
function exchange(idx) { var start_time = new Date(); $.ajax({ url : 'http://localhost:8080/', dataType : "jsonp", jsonpCallback : "_testcb", timeout : 300, success : function (data) { var end_time = new Date(); total_time += end_time - start_time; logMsg(total_time + '(ms.) [' + idx + '] - Received ' + data.length + ' bytes.'); if (idx++ < countMax) { setTimeout(function () { exchange(idx); }, 500); } }, error : function (jqXHR, textStatus, errorThrown) { alert('Error: ' + textStatus + " " + errorThrown); } }); }
記住,當將AJAX和Node.js一塊兒編碼時,你須要考慮到可能的跨域請求和同源策略,所以應該使用基於JSONP的格式!
順便說一句,能夠看到,我僅引用了測試代碼中最重要的部分,以節省篇幅。若是有人須要完整的服務器和客戶端代碼,請告訴我 - 我很樂意分享。
我分別運行了十、100、250和500個數據交換的測試,這是最終測試結果:
Data exchanges | Socket.IO NON-persistent (ms.) | AJAX (ms.) | Socket.IO persistent (ms.) |
---|---|---|---|
10 | 90 | 40 | 32 |
100 | 900 | 320 | 340 |
250 | 2,400 | 800 | 830 |
500 | 4,900 | 1,500 | 1,600 |
看看結果,咱們會注意一些狀況:
對於每種類型的測試,結果遵循線性增加的規律,這很好——代表結果是一致的。
結果清楚地代表,當使用Socket.IO非持久性鏈接時,性能數字比其餘數據差得多。
在AJAX和Socket.IO持久鏈接之間彷佛並無太大區別——咱們只談幾毫秒的差別。 這意味着,若是您天天的數據交換次數不超過10,000次的話,用戶基本上不會注意到速度差別...
下圖描述了在測試中得到的數字:
那麼接下來呢?
嗯,我必須弄清楚本身須要支持什麼樣的流量,而後我將從新運行這些測試,但此次不包括Socket.IO非持久鏈接。由於很明顯,我須要在AJAX和持久的Socket.IO鏈接之間進行選擇。
並且我也瞭解到,最有可能的是,速度差別不會像人們想象的那樣大,至少不是爲了一個「小流量」的網站,因此我在肯定本身的解決方案時,還須要研究每一個方法/技術的其餘優缺點!
這裏有一些資源,能夠找到關於Node.js、Socket.IO 和 AJAX 的一些有趣的東西:
關注微信公衆號:充實的腦洞, 一個技術宅的保留地 | |
---|---|