GREEãæ©ãNode.jsã®åé¡ãèãããã³ã
å æ¥ GREEを支える大規模インフラテクノロジー」-GREE Platform Summer Conference 2012 ã¨ããè¨äºãå ¬éãããGREEã®CTOã®è¤æ¬ãããã
javascriptããµã¼ãã¼ãµã¤ãã§ã使ãã±ã¼ã¹ãå¤ããªã£ã¦ãã¦ãã¦ãå¿ ç¶çã«node.jsã使ããã¨ã«ãªããã大ããï¼ã¤ã®åé¡ãããã
- ã²ããããããå¢ãã§ãã¼ã¸ã§ã³ã¢ãããã¦ããã®ã§å®å®ããªããã³ã¹ããæã£ã¦ã¤ãã¦ããè¦æãæã£ã¦åãçµãã§ããã
- ã¡ã¢ãªãªã¼ã¯ãããã®ã§ããµã¼ããèµ·åãã£ã±ãªãã«ããã¨ã¡ã¢ãªãé£ãã¤ã¶ãããã
- ã³ã¼ãããããã¤ãã¦ãåèµ·åããªãã¨èªã¿è¾¼ã¾ããªãã
ï¼ä¸ç¥)
ããã§çµ¶å¯¾å¤§ä¸å¤«ã¨ãã解決çããªãã¦ãnode.jsã§ä¸çªæ©ãã§ãããããã§ããããªè§£æ±ºããã¨ãããã®ãããã°ãæ¯éæãã¦æ¬²ããã
ã¨ãã£ãè©±ãæ²è¼ããã¦ãã¾ããã
GREEããã«éããä¸è¬çã« Node ã«å¯¾ãã¦åãå顿èãæã£ã¦ãã£ãããæ¹ãå¤ãã®ã§ã¯ãªããã¨æãã¾ãã
ãããï¼ã¤ã®åé¡ãèããä¸ã§ï¼ãããã«ãããã§ããããªè§£æ±ºãã¨ã¯ããã¾ãããï¼ãã©ã®ãããªã¢ããã¼ããããããèãããã³ããã¿ãããªãã®ãç§ãªãã«æ¸ãã¦ã¿ããã¨æãã¾ãã
Disclaimer
ãªã GREEããã®ææã¯ãç§ãããã§æ¸ãããã¨ãæ¢ã«ãã¡ãã¨æ¤è¨ããä¸ã§ã®ãæè¦ããããã¾ããããããå®éã«ç´é¢ãã¦ããåé¡ã«ã¤ãã¦ç§ã¯å ·ä½çãªäºãå ¨ãç¥ãã¾ãããããã¾ã§GREEãããå§ãã¨ããä¸è¬çã«ææããã Node ã®åé¡ç¹ãèãããã³ãã¨ãã¦ãèªã¿ãã ããã
ã§ã¯ï¼ã¤ã®åé¡ç¹ã«å¯¾ãã¦ä¸ã¤ä¸ã¤èãã¦ããã¾ãã
1. ã²ããããããå¢ãã§ãã¼ã¸ã§ã³ã¢ãããã¦ããã®ã§å®å®ããªãã
以åã¾ã¨ãã Node ã®æ´å²è¡¨ã以ä¸ã«è¼ãã¾ãã
ããè¦ã¦ããããããNodeã®å®å®ç(å¶æ°ãã¼ã¸ã§ã³)ã¯6ã9ã¶æã®ééã§ãªãªã¼ã¹ããã¦ãã¾ãã
ç¾å¨(8æ9æ¥æç¹ï¼ã®ææ°ã®å®å®ãã¼ã¸ã§ã³ã¯ 0.8.6 ã§ãã»ã¼æ¯é±ãã¤ãã¼ãã¼ã¸ã§ã³ã¢ããããã¦ãããã¨ã«ãªãã¾ãã
ãã®é »ç¹ãªãã¤ãã¼ãã¼ã¸ã§ã³ã¢ããã¯ããæå³æå³çã«è¡ããã¦ããããã§ãã å®å®çã§ã¯æ°æ©è½ã®è¿½å ãAPIã®å¤æ´ãªã©ã¯è¡ããããã°ãã£ãã¯ã¹ãä¸å¿ã¨ãããªãªã¼ã¹ã§ããï¼é±éã®éã«ããç¨åº¦ãã°ä¿®æ£ãã³ããããããã¦ãããªãã宿çã«ä¿®æ£çããªãªã¼ã¹ãã¦ã¦ã¼ã¶ã«ã§ããã ãå®å®ãã¦ãã Node ãæä¾ãããã¨ããæå³ãããããã¾ããï¼å®éã« isaacs ã«èãã¦ããªãã®ã§ãããã¾ãããâ¦ï¼
ãªã®ã§å®å®çããµã¼ãã¹ã«æ¡ç¨ãã¦ãããªãããã°ã«ã¶ã¡å½ãããªãéãæ¯é±ã®ãªãªã¼ã¹ã«è¿½å¾ããå¿
è¦ã¯ããã¾ããã API 仿§ã®å¤æ´ããªãã®ã§æ°ãã¼ã¸ã§ã³é£ã°ãã¦ãåä½ããããããªããªã¹ã¯ã¯å°ãªãã§ãããµã¼ãã¹ã®ã¡ã³ããã³ã¹è¨ç»ã«åããã¦ãã¼ã¸ã§ã³ã¢ãããè¡ãã°ããã¨æãã¾ããï¼ã¨ãã£ã¦ãæ°ãæã®ã¹ãã³ã§ããâ¦ï¼
ãã ã issue ãå ±åããéã¯ææ°å®å®çã§ã®å使åãå°ãããã¾ãã®ã§ãææ°å®å®ãã¼ã¸ã§ã³ãé©å¿ã§ããç°å¢ã¯å¸¸ã«æ´ãã¦ãããªãã¨ãããªãã§ãããã
次㫠0.6ãã0.8ã®ããã«å®å®çã®ãã¼ã¸ã§ã³ã¢ããã«ã¯ã©ã対å¿ãã¹ãã§ããããï¼
0.6ã®å¾åã®ãã¼ã¸ã§ã³ããããã¥ã¢ã«ã« "Stability Index" ã¨ããé ç®ã追å ããã¦ãã¾ããããã¯åAPI仿§ã®å®å®åº¦ãã©ã®ç¨åº¦ãã¨ããã«ãã´ãªã¼ã®èª¬æã§ãã 1:Experimental, 2:Unstable ã®ã¤ã³ããã¯ã¹ã®ã¤ããAPIã¯ä»å¾å¤æ´ãããå¯è½æ§ãé«ãã§ãã
ãã®APIã®ã«ãã´ãªã¼åã¯å§ã¾ã£ãã°ããã§ãä»å¾ã©ãã¾ã§å³æ ¼ã«é©å¿ããããã¾ã 䏿ã§ããã使ã£ã¦ããAPIã« Experimental ã Unstable ã¨ã«ãã´ãªã¼ããã¦ãããã®ãå«ã¾ãã¦ããã° github master ã§ã®æ©è½å¤æ´ã«æ³¨æããã¨ãã£ã対å¿ãå¿ è¦ã§ãã
Nodeã®éçºã¯ github ä¸ã§è¡ããã¦ããã®ã§é常ã«éææ§ãé«ããã»ã¨ãã©ã®å ´åå ¬éã®å ´ã§ã³ã¼ãã¬ãã¥ã¼ãè¡ããã¦ãã¾ããã©ããå¥ã®ã¨ããã§å¤§ããªéçºãé²ã¿ãç¥ããªããã¡ã«çªç¶å·¨å¤§ãªã³ããããé©å¿ããããã¨ãããã¨ã¯ããã¾ãããgithub repository ã watch ãã¦ããã°ãå®å¿ãã¦ææ°çã«ã¤ãã¦ããã¾ãã
ã¨ã¯ãããã®ã®ã®é »ç¹ã«ãã¼ã¸ã§ã³ãä¸ãã Node ã«ä¸å®ãæ±ãã®ã仿¹ããªãã¨æãã¾ããé²åã¨ã®ãã¬ã¼ããªããªã®ã§ãè¤æ¬ãããè¿°ã¹ããã¦ããããå²ãåããããªãã§ãã
2. ã¡ã¢ãªãªã¼ã¯ãããã®ã§ããµã¼ããèµ·åãã£ã±ãªãã«ããã¨ã¡ã¢ãªãé£ãã¤ã¶ãããã
Nodeã§ã¡ã¢ãªãªã¼ã¯ã® issue ãå ±åãããã¨ãåå ãç¹å®ãã¦ä¿®æ£ããã¾ã§ã¯çµæ§ãã£ãããªä½æ¥ã«ãªãã¾ããï¼ããã¯å¥ã«Nodeã«éããªãã¨æãã¾ããâ¦ï¼ ãã®éãå¿ ãæ¬¡ã®ã¹ããããæ±ãããã¾ãã
- ã¡ã¢ãªãªã¼ã¯ãçºçãã¦ãã客観çãªãã¼ã¿ã示ãã
- ã¡ã¢ãªãªã¼ã¯ãåç¾ããç°å¢ãç¹å®ããã(åç¾ã³ã¼ãã®æç¤ºçï¼
ãããè¡ãããã¤ãã®æ¹æ³ãæ¸ãã¾ãã
2.1 process.memoryUsage() ã®æ¨ç§»ãã¿ãã
process.memoryUsage() ã¯ç¨¼åä¸ã® Node ããã»ã¹ã¨V8ã®ã¡ã¢ãªæ å ±ãåºåãã¾ãã
> process.memoryUsage() { rss: 6909952, heapTotal: 4149120, heapUsed: 1903896 }
æéçµéã¨ã¨ãã«ãã¼ãé åã®é£ããå ·åã®æ¨ç§»ãåºåãã¦ã¡ã¢ãªã®ãªã¼ã¯åº¦åã調ã¹ã¾ãã
2.2 ãã¼ã«ã®åºåãè¦ãã
ã¡ã¢ãªãªã¼ã¯ã® issue ãç»é²ããã¨ãããã¢ããã¤ã¹ãããã®ã valgrind ã§ããv8 profiler ãæåãªæ å ±ãåºåãã¾ãã
- valgrindãä½¿ãæ¹æ³ Node.js leaking memory? Valgrind! (ãã ãæ§è½ä½ä¸ãæ¿ããã§ããçµæåºåãã¡ããã¨è§£æããã®ãé£ããã)
- v8 profiler Debugging memory leaks in node.js ã node-webkit-agentモジュール ã使ã£ã¦V8 Profileã®åºåçµæã§å¤æããæ¹æ³ (ç¾ç¶node-v0.8ã§ã¯åä½ç¢ºèªã§ãã¾ããã§ãããV8ãããã¡ã¤ã«åºåã®è¦æ¹ãçµæ§å¤§å¤ï¼
å人çã«ã¯ã¡ã¢ãªãªã¼ã¯èª¿æ»ã®åèç¨åº¦ã«ããã¾ã ãã¼ã«ãæ´»ç¨ã§ãã¦ãã¾ããã
2.3 ã¡ã¢ãªãªã¼ã¯ãèµ·ãã¦ããªããã¼ã¸ã§ã³ã»ã³ãããã¾ã§ããã®ã¼ã
ãã³ãåæã§ããããã¯å人çã«ã¯ä¸çªãã£ã¦ã¾ãã
ã³ãããåå¾ã® process.memoryUsage() ã®æ¨ç§»ã極端ã«éãã¨ãããè¦ã¤ãåºãã diff ãããã°ã®åå ãè¦ã¤ãã¾ãã
2.4 ã¡ã¢ãªãªã¼ã¯ã¨åéããã¦ããªãã確èªããã
- Full GC ãè¡ããã¦ããªããã¨ãã¡ã¢ãªãªã¼ã¯ã¨ééããã±ã¼ã¹ãããã¾ãã (ä¾ï¼socket.ioのheartbeat時におけるメモリリークについて ï¼ ç¢ºèªæ¹æ³ã¯ãã®MLã«è¿çããããæå gc ãå ¥ãè¾¼ãã§æåã®å¤åãè¦ããã¨ã§ãã
- FAQçãªæåã§ãªããï¼ æå³ããæåãã¡ã¢ãªãªã¼ã¯ã¨èª¤è§£ãããå ´åãããã¾ãã (ä¾ï¼Memory leak / segfault when outputting with streams in a single tickï¼
ã¡ã¢ãªãªã¼ã¯ã®ä¿®æ£ã«ã¯çéã¯ãªããã¨æãã¾ãããã¯ãå°éã«åºåãã¼ã¿ã調ã¹ãªããã²ãããã³ã¼ãã追ã£ãããããããã¾ããã
æå¾ã«ç¹°ãè¿ãã«ãªãã¾ããã Node ã¯ãªã¼ãã³ã½ã¼ã¹ã§ããã¦ã¼ã¶ããã®è²¢ç®ã§æãç«ã£ã¦ãã¾ããå ±åããã¦ããªãæªç¥ã®åé¡ãããã°æ¯é github ã® issue ã«ããã¦ããã ãããã¨é¡ãã°ããã§ãã
3. ã³ã¼ãããããã¤ãã¦ãåèµ·åããªãã¨èªã¿è¾¼ã¾ããªãã
ãããã "hot deploy" ã¾ã㯠"hot reload" ã "no downtime restart" ã¨å¼ã°ãã¦ããæ©è½ã§ãã
Node(ã¨ãããä¸è¬ç㪠JavaScript å¦çç³»)ã§ã¯ããã®ä»çµã¿ä¸ eval() ã§ã使ããªãéããåä½ä¸ã«åçã«ã³ã¼ããèªã¿è¾¼ãã§å®è¡ããã®ã¯é£ãã *1 ã¨æãã¾ããï¼åãªãç§ã®ç¥èä¸è¶³ããããã¾ãããâ¦ï¼ ããã eval() ã¯æé©åã妨ããæªçã¨ãã¦é常å©ç¨ãããã¨ãæ¨å¥¨ããã¦ãã¾ããã
ä»çµã¿ä¸å®å ¨ãªããããããã¤ãå®ç¾ããã®ã¯é£ããã®ã§ã代ããã«æ±ããããã®ã¯ graceful restart (ç¶ç¶ä¸ã®ã»ãã·ã§ã³ãåããã«åèµ·åãè¡ãï¼ã®æ¹æ³ã§ããã¨ã¯è¨ã£ã¦ã Node ã¯åºæ¬ã·ã³ã°ã«ããã»ã¹ã»ã·ã³ã°ã«ã¹ã¬ããã§åä½ããã®ã§ãæ°¸é ã«æ¥ç¶ããã¾ã¾ã®ã»ãã·ã§ã³ãåå¨ããã°ãã¤ã¾ã§ãã£ã¦ãåèµ·åã¯ã§ãã¾ããã
ãããã¢ããªã忣ç°å¢ã§åä½ããããã«è¨è¨ããããç¨åº¦ã»ãã·ã§ã³ã®æ¥ç¶ã¿ã¤ã ã¢ã¦ãã許容ããã°ãè¤æ°ããã»ã¹éã§ãµã¼ãã¹ã®åãæ¿ããªããå®è¡ã³ã¼ããæ´æ°ãããã¨ãã§ãã¾ãã
3.1 http.Server.close() ã®æåã®çè§£
gracefull restart ãããããã®ä¸çªããªããã£ããªAPI㯠http.Server.close() ã§ãããã®APIã¯æ°è¦ http ã»ãã·ã§ã³ã®æ¥ç¶ã忢ããã ãã§æ¢åã®æ¥ç¶ã»ãã·ã§ã³ã¯ç¶ç¶ããã¾ããclose() å¾ http ã»ãã·ã§ã³ãå ¨ã¦ãªããªã㨠server ãªãã¸ã§ã¯ãã§ close ã¤ãã³ããçºçãã¾ããæ ¹æ¬çã«ãã®ä»çµã¿ãçè§£ãããã¨ãå¿ è¦ã§ãã
3.2 cluster.disconnect() ã®å©ç¨
node-v0.8ã§å°å ¥ããã cluster ã®æ°æ©è½ã§ã¯ãworker ããã»ã¹ã® gracefull shutdown ãå®ç¾ãã cluster.disconnect() APIãæä¾ããã¾ããã ï¼å é¨çã«ã¯ server.close() å¦çã«åããã¦åããã»ã¹ã®ç®¡çããã¦ããã ãã§ããï¼
ããã使ãã°ã徿¥ããç°¡åã«è¤æ°ããã»ã¹ã使ã£ãgracefulãªå¦çããããããªãã¾ãã
3.3 ãªã¯ã¨ã¹ãæ¯ã«å¦çããã»ã¹ãå¤ãã
LearnBoost ã® upモジュール ã®ã¢ããã¼ããããã§ããï¼åèè¨äºï¼ Staying up with Node.JS ï¼ãã®ä»çµã¿ã§ã¯ã httpãªã¯ã¨ã¹ãã®ã¤ãã³ãæ¯ã«è¤æ°ããã»ã¹ã®å¥ãã¼ãã«æ¥ç¶ãã http ã ws ã®ãªã¯ã¨ã¹ãå¦çãå®è¡ãã¾ãããã¹ã¿ã¼ããã»ã¹ã¯æ¯ååçã«å²ãæ¯ããè¡ãã ãã§ãã
æ°ããã³ã¼ãããããã¤ãããã䏿çã« worker ã¸ã®ãªã¯ã¨ã¹ãå¦çã®å²ãæ¯ãã忢ããæ¥ç¶ã®ãªã worker ã¯ã³ã¼ããåèªã¿è¾¼ã¿ãã¾ãããã¯ãã®è¦ãç®ã§ã¯ããããããã¤ã«æãè¿ãæ¹æ³ã§ããæ¥ç¶ã®ãªã¼ããããããããå¦çæ§è½ã«å½±é¿ããå¯è½æ§ãããã¾ãããç¾ç¶ããããããã¤ãå®ç¾ããã«ã¯æãç¾å®çãªã¢ããã¼ãã§ãã
ãã©ã¼ã«ããã¬ã©ã³ããªè¦ä»¶ã§ Node ãåä½ãããã®ã¯ã¾ã ã¾ã è¶³ããªããã®ãå¤ãã¨æãã¾ããä»å¾ãæ§ã ãªã¢ã¸ã¥ã¼ã«ããã¬ã¼ã ã¯ã¼ã¯ã§ãã®æ©è½ãå å®ãã¦ãããã®ã¨æå¾ ãã¦ãã¾ãã
*1: ã³ã¡ã³ãã§ææãã¦ããã ãã¾ããããvmã¢ã¸ã¥ã¼ã«ã§åçã«å®è¡ã³ã³ããã¹ãã使ãããã¨ãã§ãã¾ãã ãã vmã¢ã¸ã¥ã¼ã«ã¯ããã¤ãåé¡ç¹ãææããã¦ãã¦ãè¿ããã¡ã«æ¹è¯ãå ããããäºå®ã§ãã vm module correction