æåã«çµæ
12è¡ã®å€æŽåŸãã¿ã€ã ã¢ãŠãã€ãã³ãã¯ããµãŒããŒãã¯ã©ã€ã¢ã³ãã«å¿çãããã¯ã©ã€ã¢ã³ãããããåŸ ã€ãšãã«ã®ã¿çºçãå§ããŸããã æ¥ç¶ã¿ã€ã ã¢ãŠãã¯ããã©ã«ãå€ã®2åã®ãŸãŸã§ãããhttp.Server.keepAliveTimeoutã¯ããã©ã«ãå€ã®5ç§ïŒApacheãªã©ïŒã§è¡šç€ºãããŸããã ä¿®æ£ãªããžããªïŒ tshemsedinov / node ïŒnode.js 0.12ã®å ŽåïŒããã³tshemsedinov / io.js ïŒio.jsã®å ŽåïŒã ããã«ãããããjoyent / nodeãšnodejs / nodeã«ããŒã«ãªã¯ãšã¹ããéä¿¡ããŸãïŒä»¥åã®io.jsã§ãããçŸåšã¯æ¢ã«ãããžã§ã¯ããçµåããŠããŸãïŒã
ä¿®æ£ã®æ¬è³ªã¯ãæ¥ç¶ããã³ã°ããŠãªã¯ãšã¹ããå¿çãããªããŸãŸã§ããœã±ãããéããŠããå Žåã«æ¥ç¶ã¿ã€ã ã¢ãŠããæ©èœããã¯ãã§ãããããã¹ãŠã®ãªã¯ãšã¹ããå¿çããããšãããŒãã¢ã©ã€ãã¢ãŒãã§å¥ã®ãªã¯ãšã¹ããéä¿¡ããæ©äŒãäžããå¿ èŠãã¯ããã«å°ãªããªãå¿ èŠãããããšã§ãã
å¯äœçšã«ã€ããŠã¯ãã§ã«æšæž¬ã§ããŸããå€ãã®ã¡ã¢ãªãšãœã±ããèšè¿°åã解æŸãããçŸåšã®é«è² è·ãããžã§ã¯ãã§ããã«å šäœã®ããã©ãŒãã³ã¹ã2å以äžåäžããŸããã ããã§ãã³ãŒãã䜿çšããå°ããªãã¹ãã瀺ããŸãããã®çµæã¯äžã®ã°ã©ãã§ç¢ºèªã§ããäœãèµ·ãã£ãŠããã®ããç¥ãããšãã§ããŸãã
ãã¹ãã®æ¬è³ªïŒ15,000ã®HTTP / 1.1æ¥ç¶ïŒç¹å¥ãªããããŒããªããŠãããã©ã«ãã§ããŒãã¢ã©ã€ããšèŠãªãããïŒãäœæãããœã±ããã®äœæãšã¯ããŒãºã®åŒ·åºŠãšã¡ã¢ãªæ¶è²»ã確èªããŸãã ãã¹ãã¯200ç§éå®è¡ãããããŒã¿ã¯10ç§ããšã«èšé²ãããŸããã å·ŠåŽã®ã°ã©ãã¯ä¿®æ£ãªãã®Node.js 0.2.7ã§ãããå³åŽã®ã°ã©ãã¯Node.jsã«ããããé©çšããŠåæ§ç¯ãããã®ã§ãã éãç·ã¯éããŠãããœã±ããã®æ°ãèµ€ãç·ã¯éãããœã±ããã®æ°ã§ãã ãã¡ããããããè¡ãã«ã¯ããã¹ãŠã®ãœã±ãããé åã«æžã蟌ãå¿ èŠããããŸããããã¡ã¢ãªãå®å šã«ã¯è§£æŸããŸããã§ããã ãããã£ãŠããã¹ãã®ã¯ã©ã€ã¢ã³ãéšåã«ã¯ãã¡ã¢ãªããã§ãã¯ããããã®ãœã±ããã®é åã䜿çšããå Žåãšäœ¿çšããªãå Žåã®2ã€ã®ãªãã·ã§ã³ããããŸãã äºæ³ã©ããããœã±ããã¯2åéã解æŸãããŸããããã¯ãèšè¿°åãå æããããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã®TCP / IPã¹ã¿ãã¯ãããŒãããªãããšãæå³ããŸããããŒãã«å ããŠãåèšè¿°åã®ããŒã¿æ§é ãšãããã¡ãä¿æããŸãã
éãç·ã¯RSSïŒåžžé§ã»ãããµã€ãºïŒ-åèšããã»ã¹ã«ãããæéãèµ€ãç·-ããŒãåèš-ã¢ããªã±ãŒã·ã§ã³ã«å²ãåœãŠãããã¡ã¢ãªãç·ã®ç·-䜿çšãããããŒã-䜿çšãããã¡ã¢ãª åœç¶ã解æŸããããã¹ãŠã®ã¡ã¢ãªã¯ãæåã®å²ãåœãŠãããé«éã§ãä»ã®ãœã±ããã«åå©çšã§ããŸãã
ãã¹ãã³ãŒãïŒ
ãã¹ãã®ã¯ã©ã€ã¢ã³ãéšå
var net = require('net'); var count = 0; keepAliveConnect(); function keepAliveConnect() { var c = net.connect({ port: 80, allowHalfOpen: true }, function() { c.write('GET / HTTP/1.1\r\nHost: localhost\r\n\r\n'); if (count++ < 15000) keepAliveConnect(); }); }
ãœã±ããã«ãŠã³ã¿ãŒãåãããµãŒããŒåŽ
var http = require('http'); var pad = ''; for (var i = 0; i < 10; i++) pad += '- - - - - - - - - - - - - - - - - '; var sockets = []; var server = http.createServer(function (req, res) { var socket = req.socket; sockets.push(socket); res.writeHead(200, {'Content-Type': 'text/plain'}); res.end(pad + 'Hello World\n'); }); setInterval(function() { var destroyedSockets = 0; for (var i = 0; i < sockets.length; i++) { if (sockets[i].destroyed) destroyedSockets++; } var m = process.memoryUsage(), a = [m.rss, m.heapTotal, m.heapUsed, sockets.length, destroyedSockets]; console.log(a.join(',')); }, 10000); server.listen(80, '127.0.0.1');
ãœã±ããã«ãŠã³ã¿ãŒã®ãªããµãŒããŒåŽ
var http = require('http'); var pad = ''; for (var i = 0; i < 10; i++) pad += '- - - - - - - - - - - - - - - - - '; var server = http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end(pad + 'Hello World\n'); }); setInterval(function() { var m = process.memoryUsage(); console.log([m.rss, m.heapTotal, m.heapUsed].join(',')); }, 10000); server.listen(80, '127.0.0.1');
åé¡ã®è©³çŽ°
ã¯ã©ã€ã¢ã³ãåŽãããŒãã¢ã©ã€ããèŠæ±ããªãå ŽåãNode.jsã¯res.endïŒïŒãåŒã³åºãããšã§ããã«ãœã±ãããéãããªãœãŒã¹ãªãŒã¯ã¯çºçããŸããã ãããã£ãŠãhttp.getïŒ '/'ïŒã倧èŠæš¡ã«è¡ããã¹ãŠã®ãã¹ãã§ã¯ãOnïŒ 'error'ãfunctionïŒïŒ{}ïŒãŸãã¯curl http://domain.com/ãŸãã¯abïŒapacheãã³ãããŒã¯ïŒãä»ããŠãããã ãŸãããã©ãŠã¶ã¯åžžã«ããŒãã¢ã©ã€ããæãã§ããŸãããããŒãã®ããã«ããŸãæ©èœããŸããã ããŒãã¢ã©ã€ãã®åé¡ã¯ãè€æ°ã®ãªã¯ãšã¹ããé çªã«éä¿¡ã§ããã ãã§ãååçãã©ã®ç«¶åãªã¯ãšã¹ãã«å¿çããããããŒã¯ãããããã¡ã«ããºã ããªãããšã§ãã åæããŸããããã¯éåžžã«äžäŸ¿ã§ãã SPDYããã³HTTP / 2ã§ã¯ããã®ãããªåé¡ã¯ãããŸããã ãã©ãŠã¶ãŒãå€ãã®ãªãœãŒã¹ãå«ãããŒãžãããŒããããšããããŒãã¢ã©ã€ãã䜿çšããããšããããŸãããå€ãã®å Žåãæ£ããããããŒãéä¿¡ãããµãŒããŒã«éããæ¥ç¶ãç¶æããããã«æ瀺ããèªåèªèº«ã§ãããã»ãšãã©äœ¿çšããªãããç¡èŠããããšããã§ããŸãã ããã§ãFirebugãšDevToolsã¯ããªã¯ãšã¹ããå®äºãããœã±ããããã³ã°ããŠããããšã瀺ããŠããŸãã ããŒãžããã§ã«å®å šã«ããŒããããŠããŠãããã€ãã®ãœã±ãããäœæãããŠããŠãããããã¯éããããŠããããAPIã«äžå¹žãªãªã¯ãšã¹ãã1ã€è¡ãå¿ èŠããããŸãããç§ã®èŠ³å¯ã§ã¯ããã©ãŠã¶ãŒã¯åžžã«æ°ããæ¥ç¶ãäœæãããœã±ããã¯ãµãŒããŒãŸã§ä¿æãç¶ããããšã瀺ããŠããŸãéããŸãã ãã®ãããªäžæåæ¢ããããœã±ããã¯äžŠåãªã¯ãšã¹ããšã¯èŠãªãããªãããããã©ãŠã¶ãŒã®å¶éã«åœ±é¿ããŸããïŒç§ã¯ç解ããŠããããã«ãããŒããªãŒãã³ãšããŠããŒã¯ããã䜿çšããããã«ãŠã³ã¿ãŒããé€å€ãããŸãïŒã ããã¯ããã©ãŠã¶ãéãããšç¢ºèªã§ããŸããããŒããµãŒããŒã§ã¯ã2åã®ã¿ã€ã ã¢ãŠããåŸ ã€æéããªããœã±ããã®æãããã«éããããŸãã
å¿çãã¯ã©ã€ã¢ã³ãåŽã«éä¿¡ããããã©ããã«é¢ä¿ãªããããŒãã®ã¿ã€ã ã¢ãŠãã¯2åã§ãã ãã®ã¿ã€ã ã¢ãŠãããããšãã°5ç§ã«äžããããšã¯ãªãã·ã§ã³ã§ã¯ãããŸããããã®çµæã客芳çã«5ç§ä»¥äžãããæ¥ç¶ã¯åæãããŸãã ããŒãã¢ã©ã€ãã«ã¯å¥ã®ã¿ã€ã ã¢ãŠããå¿ èŠã§ãããã®ã«ãŠã³ãããŠã³ã¯ããã«ã¯éå§ãããŸãããããœã±ããã®æåŸã®ã¢ã¯ãã£ããã£ã®åŸãã€ãŸã ããã¯ãã¯ã©ã€ã¢ã³ãããã®æ¬¡ã®ãªã¯ãšã¹ããåŸ ã€ãªã¢ã«ã¿ã€ã ã§ãã
äžè¬ã«ãããŒãã¢ã©ã€ããå®å šã«å®è£ ããã«ã¯ãããã«å€ãã®ããšãè¡ãå¿ èŠããããã¯ã©ã€ã¢ã³ãããéä¿¡ãããHTTPããããŒããç®çã®ã¿ã€ã ã¢ãŠãæéãååŸããå¿çããããŒã§å®éã«èšå®ãããã¿ã€ã ã¢ãŠãæéãã¯ã©ã€ã¢ã³ãã«éä¿¡ããmaxããã³Keep-Alive Extensionsãã©ã¡ãŒã¿ãŒãåŠçããŸãã ããããææ°ã®ãã©ãŠã¶ã¯ããããã¹ãŠã䜿çšããŠããããã§ã¯ãããŸããããããã«ããŠããç§ãå®æœããå®éšã§ã¯ããããã®HTTPããããŒã¯ç¡èŠãããŠããŸããã ãã®ãããå°ããªç·šéã§çŽ æŽãããçµæãåŸãããèœã¡çããŸããã
Node.jsã®ä¿®æ£
æåã«ãã€ãã³ããçºçãããªãae9a1a5ãé²ãããã«ãç°¡åãªæ¹æ³ã§è¿œå ã®ã¿ã€ã ã¢ãŠãã䜿çšããŠåé¡ãä¿®æ£ããããšã«ããŸãã ã ãããããã®ããã«ã¯ã³ãŒãã«æ £ããå¿ èŠããããã³ãŒãã®èšè¿°æ¹æ³ãæ°ã«å ¥ããªãã£ãã äžéšã®å Žæã«ã¯ãé¢æ°ã®ãã¹ããåãé€ãããã«å€§ããªã¯ããŒãžã£ãŒãå解ããå¿ èŠããããšããã³ã¡ã³ãã¯ãããŸããããã¹ããåéã§ãããå€ãã®äººã ããã¹ãŠã®äŸåã³ãŒããå°ç¡ãã«ããå¯èœæ§ãããããããããã®ã©ã€ãã©ãªã«ã¯è§ŠããŸããã ããŠããã¹ãŠã¯æ©èœããŸãããããœã±ããã®ãªãŒã¯ã¯ç§ã«äŒæ¯ãäžããŸããã§ããã ãããŠãç§ã¯1ã€ã®res.endïŒïŒãæ¢ã«éä¿¡ããããšãã«ServerResponse.prototype.detachSocketã®åŸã«ãœã±ãããç Žæ£ããããšã§åé¡ã解決ããããšãèšç»ããŸããããããã¯å€ãã®æçšãªããŒãã¢ã©ã€ãåäœãå£ããŸããïŒ 9d9484b ã ä»ã®ãµãŒããŒã®RFCãšããã¥ã¡ã³ããèªãã§å®éšããçµæãããŒãã¢ã©ã€ãã¿ã€ã ã¢ãŠããå®è£ ããå¿ èŠããããæ¥ç¶ã¿ã€ã ã¢ãŠããšã¯ç°ãªãããšãæããã«ãªããŸããã
ä¿®æ£ïŒ
- server.keepAliveTimeoutãã©ã¡ãŒã¿ãŒãè¿œå ãããŸããããã®ãã©ã¡ãŒã¿ãŒã¯æåã§èšå®ã§ããŸã/lib/_http_server.js#L259
- prefinishã€ãã³ãé¢æ°ã®ååãå¥ã®å Žæã§äœ¿çšããããã«å€æŽããŸãã/lib/_http_server.js#L455,L456
- ãã¹ãŠããã§ã«åçãããç¬éããã£ããããããã«ãçµäºã€ãã³ãããã³ã°ãããŸããã ãããããœã±ããã®ã¿ã€ã ã¢ãŠãã€ãã³ãã§ãã³ã°ããEventEmitterãããã³ãã©ãŒãåé€ãããœã±ãããç Žå£ããã€ãã³ãããããŒããã£ã¹ãããŸã/lib/_http_server.js#L483,L491
- httpsãµãŒããŒã®å ŽåãkeepAliveTimeoutãã©ã¡ãŒã¿ãŒãè¿œå ããŸããããã¯ã / lib / https.jsïŒL51ãããã¿ã€ãããä»ã®ãã¹ãŠãç¶æ¿ããããã§ãã
Impress Application Serverã®å Žå ããããã®å€æŽã¯ãã¹ãŠçŸãããããã®åœ¢ã§å éšçã«å®è£ ãããNode.jsã«ãããããªããŠãå¹æãå©çšã§ããŸãããœãŒã¹ã§ã¯ããã®ç°¡åããããããŸãã ããã«ãæè¿ã®ãããžã§ã¯ãã§ã¯ãSSEãããã³ã«ïŒãµãŒããŒéä¿¡ã€ãã³ãïŒã«åºã¥ããŠã¯ã©ã¹ã¿ãŒã«çµ±åããã4å°ã®ãµãŒããŒã§1000äžã®æ°žç¶çãªæ¥ç¶ïŒãµãŒããŒããã250äžïŒãªã©ãä»ã®å°è±¡çãªçµæãéæããŸããã Webãœã±ããã§ãåãã§ãã Impressã¯ã©ã¹ã¿ãŒã«ã¢ããªã±ãŒã·ã§ã³ãã©ã³ã·ã³ã°ãå®è£ ãã以åã«äœ¿çšããZMQã®ä»£ããã«ã¯ã©ã¹ã¿ãŒããŒããTCPããŒã¹ã®ãããã³ã«ã§æ¥ç¶ããŸããã ãã®äœæ¥ã®çµæã¯ã次ã®èšäºã§ãäžéšå ¬éãããŸãã å€ãã®äººãããã®æé©åãšããã©ãŒãã³ã¹ãå¿ èŠãšãã人ã¯ããªããšèšã£ãŠããŸãã誰ããç¡é¢å¿ã§ãã ããããå°ãªããšã4ã€ã®é«è² è·ã®ã©ã€ãäŸã§ã¯ãäžåœã®é¡§å®¢ãšã€ã³ã¿ã©ã¯ãã£ããã¬ã圢åŒãSeventh Senseãã®å Žåãçç£æ§ã2ã3åãã1泚æã«å šè¬çã«åäžããŠããããšãããããŸãã ãããè¡ãã«ã¯ãããã«ãŠã§ã¢ã®ååãæŸæ£ããããã»ã¹ééä¿¡ãæžãçŽããã¢ããªã±ãŒã·ã§ã³ãã©ã³ã·ã³ã°ãå®è£ ããå¿ èŠããããŸããïŒããŒããŠã§ã¢ãã©ã³ãµãŒã¯å¯Ÿå¿ã§ããŸããïŒãªã©ã ããã¯ãããã«ãŠã§ã¢ã䜿çšããéã®ããã©ãŒãã³ã¹ã®æãããã«ã€ããŠã®å¥ã®èšäºã§ãããããŒããäžãããã®ããã®åŸããã«ãŠã§ã¢ãåã£ããã®ãã ç§ã¯ãã§ã«ååãªäºå®ãçµ±èšãäŸãçšæããŠãããèŠè¿ãã«äœããæäŸããŠããŸãã
ããã«ãã¹ãŠã欲ããã§ããïŒ
次ã«ããã«ãã«åºã¥ããŠã§ã¯ãªããNode.js 0.12.7ã®å ¬åŒããŒãžã§ã³ã§ãã®å¹æã瀺ãããã«ããã®ãããªãããããã¹ãããå¿ èŠããããŸãã 次ã«ããªã¯ãšã¹ãã€ãã³ãã«ããã«7è¡ã®ã³ãŒããè¿œå ããå Žåã«äœãèµ·ãããã確èªããŸãã ãœã±ããã¯å¿ èŠã«å¿ããŠéããããäœåãªã¿ã€ã ã¢ãŠãã€ãã³ãã䌎ããšã©ãŒãæ¶ããŸããããã¯ç解ã§ããŸãã ããããã¡ã¢ãªãããã°ãç¶æ³ã¯ç¢ºãã«æ¹åãããŸãããNode.jsãåæ§ç¯ãããšãã»ã©ã§ã¯ãããŸããã
http.createServer(function (req, res) { var socket = req.socket; res.on('finish', function() { socket.removeAllListeners('timeout'); socket.setTimeout(5000, function() { socket.destroy(); }); }); res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); });
ã°ã©ãã®çµæãæ¯èŒããŸããå·ŠåŽã¯Node.js 0.12.7ã®åæç¶æ ãäžå€®ã¯ãªã¯ãšã¹ããžã®7è¡ã®è¿œå ã§ãããå ¬åŒã®0.12.7ã§èµ·åãããŸããå³åŽã¯ç§ã®ãªããžããªããããããé©çšããNode.jsã§ãã ãã®çç±ã¯æããã§ãã0.12.7ã®ã¯ããŒã³ã¯äœæããŸããã§ããããå°ãæ°ããããŒãžã§ã³ãäœæãããããæéããŸããã ãã¡ãããæåŸã®ãã¹ããé€ããã¹ãŠã®ãã¹ãã¯ããããã䜿çšããŠããããã䜿çšããã«ç§ã®ãªããžããªã§å®è¡ãããŸããã ãããŠãæåŸã®ãã¹ããå ¬åŒããŒãžã§ã³0.12.7ãšæ¯èŒããã®ã§ããããçŸåšã®ã³ãŒãã«ã©ã®ããã«åœ±é¿ããããæ確ã«ãªããŸããã
ãªããžããªã®V8ã®ããŒãžã§ã³ã¯0.12.7ãšåãã§ãããããŒãã§æé©åãè¡ãããããšã¯æããã§ãã ãã°ããåŸ ã€å Žåã¯ãäžèšã®ãããã䜿çšããããä¿®æ£ãããŒãã«é©çšãããŸãã ããã2ã€ã®ãªãã·ã§ã³ã®çµæã¯ã»ãŒåãã§ãã äžè¬çã«ãç§ã¯ãã®æ¹åã§å®éšãšæé©åãç¶ããŠãããŸããã¢ã€ãã¢ãããã°ãé æ ®ãªããæãéèŠãªçµã¿èŸŒã¿ããŒãã©ã€ãã©ãªã®ã³ãŒãå€æãææ¡ããŠé©åãªå€èŠ³ã«æ¥ç¶ããŠãã ããã ç§ãä¿¡ããŠãããããã¬ãã«ã®å°é家ã®ããã«å€ãã®ä»äºããããŸãã ããã«ããœãŒã¹ã³ãŒããå匷ããããšã¯ããã©ãããã©ãŒã ãéçºããäžã§ç¥ã£ãŠããæè¯ã®æ¹æ³ã§ãã
æŽæ° ïŒ_lastã«å¥ã®åé¡ãèŠã€ãããŸãããã誰ãèšç®ããŠããŸããã è¿é£ã®ç·šéãšããŒãžããããã¹ããããããŒã«ãªã¯ãšã¹ããšhttps://github.com/nodejs/node/pull/2534ãæçš¿ãããŸããã