ÁÖÀÇ: º»¹®¼­´Â ¸¶ÀÌÅ©·Î¼ÒÇÁÆ®¿þ¾î 2002~11¿ù,12¿ùÈ£¿¡ ¼ÛÁöÈÆ´ÔÀÌ ±â°íÇÑ ±Û·Î½á º»ÀÎÀÇ µ¿ÀǾøÀÌ ¹«´Ü ¹èÆ÷ÇÏ´Â °ÍÀ» ±ÝÁöÇÔ. ¸¸¾à ±ÛÀ» ´Ù¸¥ °÷¿¡ Æ÷½ºÆÃÇÏ·Á ÇÒ °æ¿ì ¹Ýµå½Ã °­ÁÂÀÇ URL ¸µÅ©¸¦ »ç¿ëÇØ¾ßÇÔ.


ByteBufferPool°ú ThreadPoolÀ» Ãß°¡ÇØ ¼º´É ¾÷±×·¹À̵åÇϱâ

¸¸µçÀÌ: ¼ÛÁöÈÆ
¼Ò¼Ó: JavaCafe ºÎ½Ã¼¥
email: johnleen@hanmail.net

¼­¹öÀÇ ¼º´É Çâ»óÀ» À§ÇØ Pooling ±â¹ýÀ» µµÀÔÇϰí Command ÆÐÅϰú ·±Å¸ÀÓ µ¿Àû ·ÎµùÀ» ÀÌ¿ëÇØ ¸ØÃßÁö ¾Ê´Â ¼­¹ö ¸¸µé±â

À̹ø È£¿¡¼­´Â ¼­¹öÀÇ ¼º´É Çâ»óÀ» À§ÇØ °í·ÁÇØ¾ß ÇÒ Á¡µéÀ» »ìÆìº¸°í ±× °³¼± ¹æ¹ýµé¿¡ ´ëÇØ ¾ð±ÞÇÒ °ÍÀÌ´Ù. ±×¸®°í ±× Áß ÀϺθ¦ Áö³­ ½Ã°£¿¡ ¸¸µé¾ú´ø °£´ÜÇÑ Ã¤ÆÃ ¼­¹ö¿¡ Àû¿ë½ÃÄÑ º¼ °ÍÀÌ´Ù. ±×·³ ÀÌ ±â»ç¸¦ ÅëÇØ »ó¿ë ¼­¹ö ÇÁ·Î±×·¥ ¼öÁØ¿¡ ÇѰÉÀ½ ´õ ´Ù°¡¼­ º¸ÀÚ.

ThreadPool °ú ByteBufferPool ·Î ¼­¹ö¿¡ ³¯°³¸¦ ´ÞÀÚ
¸ð¹ÙÀÏ ÇÁ·Î±×·¥ÀÌ Á¦ÇÑµÈ ½Ã½ºÅÛ »ç¾ç¿¡¼­ ¸¸Á·ÇÒ ¸¸ÇÑ ¼Óµµ¸¦ ¾ò±â À§ÇØ Äڵ带 ÃÖÀûÈ­ ½Ã۵íÀÌ ³×Æ®¿öÅ© ÇÁ·Î±×·¡¹Öµµ È¿À²À» Áß½ÃÇϱ⠶§¹®¿¡ ÄÚµù½Ã °í·ÁÇØ¾ßÇÒ Á¡µéÀÌ ¸¹´Ù. È¿À²°ú È®À强, ¾ÈÁ¤¼ºÀ» °í·ÁÇØ¾ßÇÏ´Â ³×Æ®¿öÅ© ÇÁ·Î±×·¡¹ÖÀº ´Ù¸¥ ÇÁ·Î±×·¥¿¡ ºñÇØ ±â¼ú Áý¾àÀûÀÎ ÇüÅÂÀÇ ¼º´ÉÇâ»óÀ» °í·ÁÇÑ ÄÚµåµé·Î ÀÌ·ç¾îÁ®¾ß ÇÑ´Ù. À̹ۿ¡µµ ³×Æ®¿öÅ©¶ó´Â °÷ÀÌ ÁÖ¹«´ëÀÌ´Ù º¸´Ï ¿¹±âÄ¡ ¸øÇÑ ´Ù¾çÇÑ »óȲ¿¡ ´ëºñÇØ¾ßÇÏ´Â °Íµµ ÇÁ·Î±×·¡¸Ó ÀÔÀå¿¡¼± °ñÄ¡ ¾ÆÇ ÀÏÀÌ´Ù. Áö¸é°ü°è»ó ÀÌ ±ÛÀ» ÅëÇØ ¼­¹ö ÇÁ·Î±×·¡¹Ö¿¡¼­ °í·ÁÇØ¾ßÇÒ ¸ðµç °ÍµéÀ» ´Ù ¾ð±ÞÇÏÁö´Â ¸øÇÒ °ÍÀÌ´Ù. ÇÏÁö¸¸ Àü ½Ã°£¿¡ ¾ð±ÞÇßµíÀÌ È¿À²ÀûÀÎ ¾²·¹µå ¿î¿µÀ» À§ÇÑ ThreadPool, ¹öÆÛÀÇ È¿À²ÀûÀÎ ¿î¿µ°ú ÆÄÀÏÀ» ¸Þ¸ð¸®·Î »ç¿ëÇϱâ À§ÇÑ ByteBufferPoolÀ» Áß½ÉÀ¸·Î ¼³¸íÇØ ³ª°¥ °ÍÀÌ´Ù. ¶Ç Command ÆÐÅϰú ÀÚ¹ÙÀÇ ¾ð¾îÀû Ư¡ÀÎ ·±Å¸ÀÓ µ¿Àû ·ÎµùÀ» ÀÌ¿ëÇØ ±â´É È®Àå½Ã ¼­¹ö¸¦ ÀçºÎÆÃ ÇÏÁö ¾Ê¾Æµµ µÇ´Â ±â¹ýÀ» ¼³¸íÇÒ °ÍÀÌ´Ù. À̿ܿ¡ ±âŸ ÇÊ¿äÇÏ´Ù°í »ý°¢µÇ´Â ºÎºÐµé¿¡ ´ëÇØ¼­µµ Ãß°¡ÀûÀÎ ¼³¸í°ú Äڵ带 ¼Ò°³ÇØ ³ª°¥ °ÍÀÌ´Ù. ±×·³ ¿ì¸®°¡ Áö³­ ½Ã°£¿¡ ¸¸µé¾ú´ø ¼­¹ö¸¦ ¾÷±×·¹ÀÌµå ½ÃÄѺ¸ÀÚ.

È¿À²ÀûÀÎ Thread ¿î¿µ-°ü¸®¸¦ À§ÇÑ ThreadPool
µ¿½Ã¿¡ ¼ö¸¹Àº ¿äûÀ» ó¸®Çϱâ À§Çؼ± ¹«¾ùº¸´Ùµµ È¿À²Àû(ÀûÀº ¸Þ¸ð¸® »ç¿ë, ºü¸¥ 󸮼ӵµ) À¸·Î ¼­¹ö¸¦ ¸¸µå´Â °ÍÀÌ °¡Àå Áß¿äÇÏ´Ù. ¾²·¹µå¸¦ ÇÊ¿äÇÒ ¶§¸¶´Ù ±×¶§±×¶§ ¸¸µé¾î¼­ »ç¿ëÇÏ°Ô µÇ¸é ¾²·¹µå ÀÚü¸¦ »ý¼ºÇÏ´Â °Íµµ ²Ï(¼­¹ö ÇÁ·Î±×·¥ ÀÔÀå¿¡¼±) ½Ã°£ÀÌ °É¸®´Â ´À¸° ÀÛ¾÷ÀÌ°í ¾²·¹µå¶ó´Â °´Ã¼°¡ ÀÚÁÖ »ý¼º-ÇØÁ¦ µÇ´Â »óȲ ¶§¹®¿¡ °¡ºñÁö Ä÷ºÅÍ(Garbage Collector)°¡ ºó¹øÇÏ°Ô È£ÃâµÉ ¼ö Àֱ⠶§¹®ÀÌ´Ù.

±×·¡¼­ ÀÌ·± ¹®Á¦Á¡À» ÇØ°áÇϱâ À§ÇÑ ¹æ¹ýÀ¸·Î GoF °¡ ¾´ ¸í¼­ Design Pattern ¿¡ ¼Ò°³µÈ Object Pool ÆÐÅÏÀ» ÀÌ¿ëÇÒ °ÍÀÌ´Ù. »ý¼ºÇÒ °´Ã¼°¡ ³Ê¹« ½Ã°£ÀÌ ¿À·¡ °É¸®°Å³ª ¸¹Àº °æ¿ì µîÀ¸·Î ÀÎÇÑ ¹®Á¦Á¡ÀÌ ÀÖÀ» ¶§ <±×¸² 1> °ú °°ÀÌ ±× °´Ã¼¸¦ Å¥(Ä÷º¼Ç °´Ã¼)¿¡ ³Ö¾î³õ°í Àç»ç¿ëÇÏ´Â °ÍÀÌ ÀÌ ÆÐÅÏÀÇ ÇÙ½É ¿ø¸®´Ù. ÆÐÅÏ À̸§À» º¸°í ÁüÀÛÇÒ ¼ö ÀÖ°ÚÁö¸¸ Object ´Â ¹ü¿ëÀûÀÎ ÇüÅÂÀÌ´Ù. °´Ã¼ÁöÇâ ¾ð¾î¿¡¼­ ÃÖ»óÀ§ÀÇ Ç¥Çö´ÜÀ§°¡ ¹Ù·Î Object ¾Æ´Ñ°¡...
µû¶ó¼­ ¿ì¸®´Â ¡°Thread¡°¸¦ Àç»ç¿ëÇÏ·Á°í Çϱ⠶§¹®¿¡ ObjectPool Pattern À» ±¸Ã¼ÀûÀ¸·Î Àû¿ëÇÑ ThreadPool À̶ó´Â Ŭ·¡½º¸¦ ¸¸µé¾î¼­ »ç¿ëÇÒ °ÍÀÌ´Ù. ObjectPool Pattern ÀÇ ´Ù¸¥ Àû¿ë ¿¹·Î´Â jsp/servlet À¸·Î À¥ÇÁ·Î±×·¡¹ÖÀ» ÇÒ¶§ DB Á¢¼Ó¿¡ ÈçÈ÷ »ç¿ëÇÏ´Â ConnectionPool ÀÌ ÀÖ´Ù.



<±×¸² 1> ThreadPool µµ½Äµµ

¾î¶² ±â¼úÀ» °øºÎÇÒ ¶§ Ç×»ó »ý°¢ÇØ¾ß ÇÏ´Â °Íµé Áß Çϳª°¡ ¹Ù·Î ±× ±â¼úÀÇ Àå´ÜÁ¡°ú ÃÖÀûÀÇ Àû¿ë °¡´É ºÐ¾ß µîÀ» Á¤È®ÇÏ°Ô ÆÄ¾ÇÇÏ´Â °ÍÀÌ´Ù. ±×·¡¾ß¸¸ Á» ´õ ±× ±â¼ú¿¡ ´ëÇÑ ÀÌÇØµµµµ ³ôÀÏ ¼ö ÀÖ°í ±× ±â¼úÀÌ ÇÊ¿äÇÑ °÷¿¡ ÃÖÀûÈ­ ½ÃÄÑ »ç¿ëÇÒ ¼ö Àֱ⠶§¹®ÀÌ´Ù.
±×·¯¹Ç·Î ¿ì¼± ThreadPoolÀ» ¸¸µé±â Àü¿¡ ÀÌ ThreadPoolÀ» ¸¸µé¾î »ç¿ëÇÒ ¶§ ¾òÀ» ¼ö ÀÖ´Â ÀåÁ¡ÀÌ ±¸Ã¼ÀûÀ¸·Î ¹«¾ùÀÌ ÀÖ´ÂÁö ¾Ë¾Æº¸ÀÚ. ÀåÁ¡À» ¾È´Ù¸é ´ç¿¬È÷ ¾î´À °÷¿¡, ¾î¶»°Ô ¾²¿©¾ß ÇÒÁöµµ ½±°Ô ¾Ë ¼ö ÀÖÀ» °ÍÀÌ´Ù.

ù ¹øÂ° ÀÌÁ¡À¸·Î´Â ¾²·¹µå¸¦ Àç»ç¿ëÇÔÀ¸·Î½á °¡ºñÁö Ä÷ºÅÍÀÇ È£ÃâÀ» Á» ´õ ÁÙÀÏ ¼ö ÀÖ´Ù´Â °ÍÀÌ´Ù. ¾²·¹µåÀÇ ÀæÀº »ý¼º ¼Ò¸ê·Î ÀÎÇØ »ý¼ºµÉ °¡ºñÁö Ä÷º¼Ç(Garbage Collection)ÀÇ ´ë»óÀ» ÁÙÀÓÀ¸·Î½á °¡ºñÁö Ä÷ºÅÍÀÇ È£ÃâÀ» ÁÙÀ̰í ÀÌ·Î ÀÎÇØ ÆÛÆ÷¸Õ½º¿¡ ¾Ç¿µÇâÀ» ÁÙ ¼ö ÀÖ´Â ¿ä¼Ò¸¦ ÀÛ°Ô³ª¸¶ »çÀü¿¡ ¿¹¹æÇÑ´Ù´Â °ÍÀÌ´Ù. Áö³­ ȸ¿¡¼­µµ ¾ê±âÇß¾úÁö¸¸ °¡ºñÁö Ä÷ºÅÍ·Î ¸Þ¸ð¸®¸¦ ¼ö°ÅÇÏ´Â °ÍÀº »ó´çÈ÷ ´À¸° ÀÛ¾÷ÀÌ´Ù. (1ȸ ±â»ç¿¡¼­ ¼³¸íÇß¾ú´Ù. ±â¾ïÀÌ ¾È³­´Ù¸é ´Ù½Ã ã¾Æº¸ÀÚ)

µÎ ¹øÂ° ÀÌÁ¡Àº ¾²·¹µå¸¦ »õ·Î »ý¼ºÇÏÁö ¾Ê°í ÀÌ¹Ì »ý¼ºµÈ ¾²·¹µå¸¦ °¡Á®´Ù°¡ ¾²±â ¶§¹®¿¡ ¾²·¹µå¸¦ »õ·Î »ý¼ºÇÏ´Â °Í¿¡ ºñÇØ ¼Óµµ°¡ ºü¸£´Ù´Â °ÍÀÌ´Ù. ¸Þ¸ð¸®»ó¿¡ Á¸ÀçÇÏ´Â ¾²·¹µå¸¦ ±×³É °¡Á®¿À´Â °ÍÀÌ ´ç¿¬È÷ »õ·Î¿î ¾²·¹µå¸¦ ¸Þ¸ð¸®¿¡ ÇÒ´çÇØ¼­ °¡Á®´Ù ¾²´Â °Íº¸´Ù ºü¸¦ °ÍÀÌ´Ù. ¾Õ¼­µµ ¾ð±ÞÇßÁö¸¸ ¾²·¹µå´Â »ý¼º ½Ã°£ÀÌ °áÄÚ ÂªÁö ¾Ê´Ù.

¼¼ ¹øÂ° ÀÌÁ¡Àº ThreadPool¿¡ ÀÖ´Â ÀûÀýÈ÷ ¼³Á¤µÈ °³¼ö(Ãʱ⠻ý¼ºÇÒ ¾²·¹µåÀÇ °³¼ö¿Í »ý¼ºÇÒ ¼ö ÀÖ´Â ÃÖ´ëÀÇ ¾²·¹µå °³¼ö)ÀÇ ¾²·¹µå¸¸À» »ç¿ëÇÔÀ¸·Î½á ³Ê¹« ¸¹Àº ¾²·¹µå »ý¼º¿¡ ÀÇÇÑ ½Ã½ºÅÛ ¼º´ÉÀúÇϳª ÃÖ¾ÇÀÇ °æ¿ì OutOfMemoryException À» ÇÇÇÒ ¼ö ÀÖ´Ù´Â °ÍÀÌ´Ù. (1ȸ ±â»ç¿¡¼­ °¢°¢ÀÇ ¾²·¹µå´Â ÀڽŸ¸ÀÇ CPU¿Í ½ºÅà ¿µ¿ª(¸Þ¸ð¸®)À» »ç¿ëÇÑ´Ù°í Çß´Ù. Áï, ¾²·¹µå ÀÚü°¡ ¸Þ¸ð¸®¸¦ ¼ÒºñÇÑ´Ù´Â ¸»ÀÌ´Ù)

<source 1> Àº ThreadPool Ŭ·¡½ºÀÇ ÄÚµåÀÌ´Ù. ThreadPoolÀº ÇÁ·Î±×·¥ÀÇ ÃʱâÈ­ ¶§ ÁöÁ¤ÇÑ °³¼ö ¸¸Å­ÀÇ ¾²·¹µå¸¦ ¹Ì¸® ¸¸µé¾î¼­ Å¥(¼±ÀÔ¼±Ãâ Å¥ : FIFO Queue)¿¡ ³Ö¾îµÐ´Ù. ±×¸®°í ÇÊ¿äÇÒ ¶§¸¶´Ù Å¥¿¡ Á¢±ÙÇØ¼­ ¾²·¹µå¸¦ ²¨³»¼­ »ç¿ëÇÏ°í »ç¿ëÀÌ ´Ù ³¡³ª¸é ´Ù½Ã Å¥¿¡ ÀúÀåÇØ¼­ ³ªÁß¿¡ ´Ù½Ã Àç»ç¿ëÇϵµ·Ï ÇÏ´Â °ÍÀÌ´Ù. ±×·¯³ª Å¥¿¡ Á¢±ÙÇØ¼­ ¾²·¹µå¸¦ ²¨³»·Á°í Çϴµ¥, ¸¸¾à Å¥¿¡ ´ë±âÁßÀÎ ¾²·¹µå°¡ ¾ø´Ù¸é ÇöÀç »ý¼ºµÈ ¾²·¹µåÀÇ °³¼ö¸¦ È®ÀÎÇÏ°í »ý¼ºÇÒ ¼ö ÀÖ´Â ÃÖ´ëÀÇ ¾²·¹µå °³¼ö¸¦ ³ÑÁö ¾Ê¾Ò´Ù¸é »õ·Î »ý¼ºÇؼ­ °Ç³×ÁÖµµ·Ï ÇÒ °ÍÀÌ´Ù. ¿©±â¼­ »ý¼ºÇÒ ¼ö ÀÖ´Â ÃÖ´ëÀÇ ¾²·¹µå °³¼ö¿¡ µµ´ÞÇß´Ù¸é »ç¿ëÁßÀÎ ¾²·¹µå°¡ Å¥¿¡ ¹ÝȯµÇ±â¸¦ ±â´Ù·È´Ù°¡ °Ç³× ÁÙ °ÍÀÌ´Ù. ¶ÇÇÑ Å¥´Â ÇöÀç ´ë±âÁßÀÎ ¾²·¹µåÀÇ °³¼ö°¡ Ãʱ⿡ »ý¼ºÇÑ ¾²·¹µå °³¼öº¸´Ù Ŭ °æ¿ì Å¥·Î ¹ÝȯµÇ´Â ¾²·¹µå¸¦ º¸°üÇÏÁö ¾Ê°í Æó±âÇÒ °ÍÀÌ´Ù. wait º¯¼ö´Â Å¥¿¡ ´ë±âÁßÀÎ ¾²·¹µå°¡ ¾øÀ» °æ¿ì »ý¼ºÇÒ ¼ö ÀÖ´Â ÃÖ´ëÀÇ ¾²·¹µå °³¼ö¸¦ ³ÑÁö ¾Ê¾ÒÀ» °æ¿ì ¹Ù·Î »ý¼ºÇؼ­ °Ç³×ÁÙÁö ¾Æ´Ï¸é Å¥¿¡ »ç¿ëÀÌ ³¡³­ ¾²·¹µå°¡ µé¾î¿À±â¸¦ ±â´Ù¸±Áö¸¦ °áÁ¤ÇÑ´Ù. ¿©±â¼­ ÁÖÀÇ ±í°Ô ºÁ¾ßÇÒ Á¡Àº synchronized Ű¿öµåÀÌ´Ù. µ¿±âÈ­ ¹®Á¦°¡ ¹ß»ýÇÏÁö ¾Êµµ·Ï synchronized¸¦ »ç¿ëÇÏµÇ È¿À²À» À§ÇØ »ç¿ë ºí·ÏÀ» ÃÖ¼ÒÈ­ ½ÃÄÑ¾ß ÇÑ´Ù.

<source 1> ThreadPool.java

public class ThreadPool {
private static final int MAX_POOLSIZE = 15;
private static int poolSize = 5;

private final ArrayList queue = new ArrayList();

private boolean wait = false
private int total = 0;
private int index = 0;

private AdvancedNioServer server;

public ThreadPool(AdvancedNioServer server) {
this(poolSize, server);
this.server = server;
}

public ThreadPool(int size, AdvancedNioServer server) {
poolSize = size;

for (index = 0; index < poolSize; index++) {
WorkerThread thread = new WorkerThread(this, server);
thread.setName("Worker" + (index + 1));
thread.start();
queue.add(thread);
total++;
}
}

public WorkerThread getThread() {
WorkerThread worker = null

if (queue.size() > 0) {
synchronized (queue) {
worker = (WorkerThread) queue.remove(0);
}
} else {
if (wait) {
return waitQueue();
} else {
if (index < MAX_POOLSIZE) {
worker = new WorkerThread(this, server);
worker.setName("Worker" + (index + 1));
worker.start();
total++;
return worker;
} else {
return waitQueue();
}
}
}
return worker;
}

private synchronized WorkerThread waitQueue() {
while (queue.isEmpty()) {
try {
queue.wait();
} catch (InterruptedException ignored) {
}
}
return (WorkerThread) queue.remove(0);
}

public void putThread(WorkerThread thread) {
if (queue.size() >= poolSize) {
thread = null;
--index;
} else {
synchronized (queue) {
queue.add(thread);
queue.notify();
}
}
}

public boolean isWait() { return wait; }
public void setWait(boolean wait) { this.wait = wait; }
}


Çʿ伺À» ¸ø´À²¸ ThreadPool Á¾·á½Ã Å¥ ¾ÈÀÇ ¸ðµç ¾²·¹µå¸¦ ¸Þ¸ð¸®¿¡¼­ ÇØÁ¦ÇÏ´Â ¸Þ¼Òµå¸¦ ¸¸µéÁö´Â ¾Ê¾ÒÁö¸¸ ¸¸¾à ÇÊ¿äÇÏ´Ù¸é °£´ÜÇϹǷΠÁ÷Á¢ À§ ¼Ò½º¿¡ Ãß°¡ÇÏ¸é µÉ °ÍÀÌ´Ù.

ÀÌÁ¦ ThreadPool ¾È¿¡ ÀúÀåµÇ¾î Àç»ç¿ëµÇ°í ¶Ç ¼­¹öÀÇ ½ÇÁ¦ ¼­ºñ½º¸¦ ´ã´çÇÒ WorkerThread ¸¸ ¸¸µé¾î Ãß°¡Çϸé ThreadPool ÄÄÆ÷³ÍÆ®°¡ ¿Ï¼ºµÈ´Ù. WorkerThread¸¦ ¸¸µé±â Àü¿¡ ¿ì¼± ÀÌ WorkerThread ¿¡¼­ »ç¿ëµÉ ByteBufferPool¸¦ ¸¸µé °ÍÀÌ´Ù. ±×¸®°í ¹æÈ­º® Åë°ú¸¦ À§ÇÑ ¹æ¹ý°ú ÇÁ·ÎÅäÄÝÀ» XML ·Î ÀÌ¿ëÇÏ´Â °Í¿¡ ´ëÇØ Àá½Ã ¼³¸íÇÒ °ÍÀÌ´Ù. ±×·± ÈÄ¿¡ ¸¶Áö¸· Áغñ·Î Àڹ٠ƯÀ¯ÀÇ ¾ð¾îÀû Ư¡À» ÀÌ¿ëÇØ¼­ ¼­¹öÀÇ ±â´É È®Àå½Ã ´Ù¸¥ ¾ð¾î·Î´Â »ó»óÇÒ ¼öµµ ¾ø´Â ¡°Á×Áö ¾Ê´Â ¼­¹ö¡±¸¦ ¸¸µé±â À§ÇÑ Å×Å©´Ð¿¡ ´ëÇØ »ìÆìº¸µµ·Ï ÇϰڴÙ. ±× ÈÄ¿¡ À̰͵éÀ» Á¾ÇÕÇÏ¿© WorkerThread¸¦ ¸¸µé °ÍÀÌ´Ù. ÀÚ, ±×·³ °è¼Ó ÀüÁøÀÌ´Ù.

ÆÄÀÏ ¸Þ¸ð¸®ÀÇ µµÀÔ°ú È¿À²ÀûÀÎ ¸Þ¸ð¸® »ç¿ëÀ» À§ÇÑ ByteBufferPool

ByteBuffer buf = ByteBuffer.allocateDirect(4096);
readCount = sc.read(buf);
if (readCount < 0) {
room.removeElement(sc);
sc.close();
}
buf.flip();
broadcast(buf);
buf.clear();
buf = null;


À§ÀÇ ¼Ò½º´Â 1ȸ ±â»ç¿¡¼­ »ç¿ëÇß¾ú´ø ¼Ò½ºÀÇ ÀϺκÐÀÌ´Ù. ¸¸¾à 1ȸ ±â»ç¸¦ Á¦´ë·Î Àоú´Ù¸é À§ ¼Ò½º¿¡ ¸î °¡Áö ¹®Á¦Á¡ÀÌ ÀÖÀ½À» °ð¹Ù·Î ¾Ë ¼ö ÀÖÀ» °ÍÀÌ´Ù. ¾Õ¼­ ¼³¸íÇß´ø ThreadPool ÀÇ »óȲ°ú °ÅÀÇ ºñ½ÁÇÏ´Ù.

ù ¹øÂ°´Â ByteBuffer ¸¦ ´Ã Á÷Á¢ ÇÒ´ç, ÇØÁ¦ Çϸ鼭 »ç¿ëÇϱ⠶§¹®¿¡ °¡ºñÁö Ä÷º¼Ç ´ë»óÀÌ Áõ°¡ÇϹǷΠ°¡ºñÁö Ä÷ºÅͰ¡ ÀÚÁÖ È£ÃâµÉ ¼ö ÀÖ´Ù´Â Á¡ÀÌ´Ù.

µÎ ¹øÂ°´Â ä³Î¿¡ write Çϱâ À§Çؼ­´Â ¾îÂ÷ÇÇ È¿À²À» À§ÇØ allocateDirect ·Î ¹öÆÛ¸¦ ¸¸µé¾î »ç¿ëÇØ¾ß Çϴµ¥ ÀÌ ³à¼®Àº »ý¼ºÇϴµ¥ ½Ã°£ÀÌ ¿À·¡ °É¸°´Ù´Â Á¡ÀÌ´Ù.

¼¼ ¹øÂ°´Â ¸¸¾à ÀÌ ¼­¹ö¿¡ ¼ø°£ÀûÀ¸·Î ³Ê¹« ¸¹Àº ¿äûÀÌ ÇѲ¨¹ø¿¡ ¸ô¸®¸é ¸Þ¸ð¸®¸¸À» ¹öÆÛ·Î »ç¿ëÇϱ⠶§¹®¿¡ OutOfMemoryException À¸·Î ½Ã½ºÅÛÀÌ ´Ù¿îµÉ À§ÇèÀÌ ÀÖ´Ù´Â Á¡ÀÌ´Ù. ¹°·Ð ÈçÈ÷ ¹ß»ýÇÏ´Â »óȲÀº ¾Æ´Ï°í CPU °úºÎÇÏ·Î ¸ÕÀú ¼­¹ö°¡ Á×Áö ¾Ê´Â´Ù´Â ÀüÁ¦ ¾È¿¡¼­ÀÇ À̾߱âÁö¸¸ ¿ì¸® °³¹ßÀÚµéÀº Ç×»ó ±× ¡°¸¸¾à¡±¿¡ ´ëºñÇØ¾ß ÇÏÁö ¾Ê´Â°¡!

±×·³ À§ÀÇ ¼¼°¡Áö ¹®Á¦¸¦ ¸ðµÎ ÇØ°áÇÒ ¼ö ÀÖ´Â ºñ±ÞÀ» ¼Ò°³ÇϰڴÙ. ¹Ù·Î ByteBufferPool ÀÌ´Ù.
ByteBufferPool Àº ¾Õ¼­ ¼³¸íÇÑ ThreadPool °ú ¸¶Âù°¡Áö·Î GoFÀÇ ObjectPool ÆÐÅÏÀ» ÀÌ¿ëÇÑ´Ù.

ÀÌ ³à¼®Àº ÀϹÝÀûÀ¸·Î getMemoryBuffer() ¸¦ ÅëÇØ¼­ ¸Þ¸ð¸®¸¦ ¹öÆÛ·Î ÇÒ´çÇØ¼­ »ç¿ëÇÑ´Ù. ÇÏÁö¸¸ Á¤ÇØÁø ¸Þ¸ð¸® ¹öÆÛ¸¦ ¸ðµÎ »ç¿ëÇϰí ÀÖÀ» ¶§¿¡´Â ÆÄÀÏÀ» ¹öÆÛ·Î »ç¿ëÇÑ´Ù. ¹°·Ð ÆÄÀÏÀ» ¸Þ¸ð¸®·Î »ç¿ëÇÏ¸é ½ÇÁ¦ ¸Þ¸ð¸®¸¦ »ç¿ëÇÏ´Â °Íº¸´Ù´Â ´À¸®´Ù. ÇÏÁö¸¸ Ŭ¶óÀÌ¾ðÆ®°¡ °ÅÀÇ Â÷À̸¦ ´À³¢Áö ¸øÇÒ ¸¸Å­ÀÇ ÆÛÆ÷¸Õ½º°¡ ³ª¿À¹Ç·Î ¼Óµµ ¹®Á¦·Î °í¹ÎÇÏÁö´Â ¸»ÀÚ. ¿ÀÈ÷·Á ¹®Á¦°¡ ÀÖ´Ù¸é ³×Æ®¿öÅ© Æ®·¡ÇÈÀÌ Å¬¶óÀ̾ðÆ®ÀÇ Ã¼°¨ ¼Óµµ¿¡ ´õ ¿µÇâÀ» ÁÙ °ÍÀÌ´Ù. ±×¸®°í ¹«¾ùº¸´Ùµµ ÆÄÀÏÀ» ¹öÆÛ·Î »ç¿ëÇÔÀ¸·Î½á ¸Þ¸ð¸®¸¸À» ¹öÆÛ·Î »ç¿ëÇÒ ¶§ ¹ß»ýÇÒ ¼ö ÀÖ´Â ¸Þ¸ð¸® ºÎÁ·À¸·Î ÀÎÇÑ ½Ã½ºÅÛ ´Ù¿îÀ» ¸·À» ¼ö ÀÖÁö ¾ÊÀº°¡. ¸¶Ä¡ À©µµ¿ì ¿î¿µÃ¼Á¦¿¡¼­ Çϵ带 °¡»ó¸Þ¸ð¸®·Î ¼³Á¤Çؼ­ »ç¿ëÇÏ´Â °Í°ú °°Àº ¿ø¸®´Ù. ¸ÚÁø ³à¼®ÀÌ´Ï Àüü ¼Ò½º¸¦ »ìÆìº¸µµ·Ï ÇÏÀÚ.

<source 2> ByteBufferPool.java

public class ByteBufferPool {
private static final int MEMORY_BLOCKSIZE = 4096;
private static final int FILE_BLOCKSIZE = 10240;

private final ArrayList memoryQueue = new ArrayList();
private final ArrayList fileQueue = new ArrayList();

private boolean wait = false;

public ByteBufferPool(int memorySize, int fileSize, File file) throws IOException {
if (memorySize > 0)
initMemoryBuffer(memorySize);

if (fileSize > 0)
initFileBuffer(fileSize, file);
}

private void initMemoryBuffer(int size) {
int bufferCount = size / MEMORY_BLOCKSIZE;
size = bufferCount * MEMORY_BLOCKSIZE;
ByteBuffer directBuf = ByteBuffer.allocateDirect(size);
divideBuffer(directBuf, MEMORY_BLOCKSIZE, memoryQueue);
}

private void initFileBuffer(int size, File f) throws IOException {
int bufferCount = size / FILE_BLOCKSIZE;
size = bufferCount * FILE_BLOCKSIZE;
RandomAccessFile file = new RandomAccessFile(f, "rw");
try {
file.setLength(size);
ByteBuffer fileBuffer = file.getChannel().map(FileChannel.MapMode.READ_WRITE, 0L, size);
divideBuffer(fileBuffer, FILE_BLOCKSIZE, fileQueue);
} finally {
file.close();
}
}

private void divideBuffer(ByteBuffer buf, int blockSize, ArrayList list) {
int bufferCount = buf.capacity() / blockSize;
int position = 0;
for (int i = 0; i < bufferCount; i++) {
int max = position + blockSize;
buf.limit(max);
list.add(buf.slice());
position = max;
buf.position(position);
}
}

public ByteBuffer getMemoryBuffer() {
return getBuffer(memoryQueue, fileQueue);
}

public ByteBuffer getFileBuffer() {
return getBuffer(fileQueue, memoryQueue);
}

private ByteBuffer getBuffer(ArrayList firstQueue, ArrayList secondQueue) {
ByteBuffer buffer = getBuffer(firstQueue, false);
if (buffer == null) {
buffer = getBuffer(secondQueue, false);
if (buffer == null) {
if (wait)
buffer = getBuffer(firstQueue, true);
else
buffer = ByteBuffer.allocate(MEMORY_BLOCKSIZE);
}
}
return buffer;
}

private ByteBuffer getBuffer(ArrayList queue, boolean wait) {
synchronized (queue) {
if (queue.isEmpty()) {
if (wait) {
try {
queue.wait();
} catch (InterruptedException e) {
return null;
}
} else {
return null;
}
}
return (ByteBuffer) queue.remove(0);
}
}

public void putBuffer(ByteBuffer buffer) {
if (buffer.isDirect()) {
switch (buffer.capacity()) {
case MEMORY_BLOCKSIZE :
putBuffer(buffer, memoryQueue);
break;
case FILE_BLOCKSIZE :
putBuffer(buffer, fileQueue);
break;
}
}
}

private void putBuffer(ByteBuffer buffer, ArrayList queue) {
buffer.clear();
synchronized(queue) {
queue.add(buffer);
queue.notify();
}
}

public synchronized void setWait(boolean wait) { this.wait = wait; }
public synchronized boolean isWait() { return wait; }
}


À§ÀÇ ¼Ò½º¿¡¼­ initFileBuffer(int size, File f) ¸Þ¼Òµå¿¡¼­ FileChannelÀÌ »ç¿ëµÇ¾ú´Ù. Àü ½Ã°£¿¡ »ìÆìº¸¾Ò´ø SocketChannel À̳ª ServerSocketChannel °ú ´Þ¸® ÆÄÀÏä³ÎÀº SelectableChannelÀ» »ó¼Ó¹ÞÁö ¾Ê´Â´Ù. ±×¸»Àº Áï, ÆÄÀÏä³ÎÀº ³Íºí·°Å· ¸ðµå·Î ¼³Á¤ÇÒ ¼ö ¾ø´Ù´Â ¸»ÀÌ´Ù. ±×·¯³ª ÆÄÀÏä³ÎÀº ±âÁ¸ÀÇ io ·Î ÆÄÀÏÀ» Á¦¾îÇÏ´Â °Íº¸´Ù ¸¹Àº ÀåÁ¡À» °®°í ÀÖ´Ù. ±×Áß Çϳª°¡ ÆÄÀÏä³ÎÀº ÇØ´ç OS ÀÇ ÆÄÀÏ Ä³½¬¸¦ »ç¿ëÇØ¼­ ÆÄÀÏ¿¡¼­ ÆÄÀÏ·Î Á÷Á¢ Àü´ÞÇÒ ¼ö ÀÖ°í ÆÄÀÏÀÇ Æ¯Á¤ ºÎºÐÀ» Àá±Û¼ö(locking) ÀÖ´Ù´Â Á¡ÀÌ´Ù. ¶ÇÇÑ ByteBufferPool Ŭ·¡½º¿¡¼­ »ç¿ëÇßµíÀÌ ÆÄÀÏä³ÎÀº ¸Þ¸ð¸®·Î ÆÄÀÏÀÇ ÀϺΠ¿µ¿ªÀ» ¸ÅÇÎ(mapping) ½Ãų ¼ö ÀÖ´Ù. ÆÄÀÏÀ» ¸Þ¸ð¸®·Î ¸ÅÇÎÇÒ ¶§ ÆÄÀÏÀÇ ³»¿ëÀ» ¸Þ¸ð¸® À§Ä¡µéó·³ »ç¿ëÇϱâ À§ÇØ OS ÀÇ ³×ÀÌÆ¼ºê ¸Þ¸ð¸® °ü¸®ÀÚ¸¦ »ç¿ëÇÑ´Ù. À̶§ È¿À²ÀûÀÎ ¸ÅÇÎÀ» À§ÇØ OS´Â µð½ºÅ© ÆäÀÌ¡ ½Ã½ºÅÛ(disk paging system)À» »ç¿ëÇÑ´Ù. ¾ÖÇø®ÄÉÀÌ¼Ç °üÁ¡¿¡¼­´Â ¸ÅÇÎµÈ ÆÄÀÏ ³»¿ëÀº ´ÜÁö ƯÁ¤ ÁÖ¼Ò°ªÀ» °®°í ¸Þ¸ð¸® ¾È¿¡ ÀÏ·Ä·Î Âß ´Ã¾î¼± °ÍÀ¸·Î ÀνÄÇÑ´Ù. Áï, ¸Þ¸ð¸®¿Í º°¹Ý Â÷À̰¡ ¾øÀÌ ÀνÄÇÑ´Ù´Â ¸»ÀÌ´Ù.
ÆÄÀÏä³ÎÀº ÆÄÀÏÀ» ¸Þ¸ð¸®·Î ¸ÅÇÎÇÒ ¶§ ¸Þ¸ð¸® ¿µ¿ªÀ» Ç¥ÇöÇϱâ À§ÇØ MappedByteBuffer¸¦ »ç¿ëÇϴµ¥ À̰ÍÀÇ Å¸ÀÔÀº direct ByteBuffer ÀÌ´Ù. MappedByteBuffer´Â 2°¡Áö Å« ÀåÁ¡ÀÌ Àִµ¥ ù°´Â ¸Þ¸ð¸®¿¡ ¸ÅÇÎµÈ ÆÄÀÏÀ» Àд °ÍÀÌ »ó´çÈ÷ ºü¸£´Ù´Â °ÍÀÌ´Ù. ¹°·Ð ÆÄÀÏÀ» ¼øÂ÷ÀûÀ¸·Î Àд °ÍÀÌ °¡Àå ºü¸£°í ±âÁ¸ io¸¦ »ç¿ëÇÏ´Â °Íº¸´Ù ¼º´ÉÀÌ ¸¹ÀÌ °³¼±µÇÁö¸¸ RandomAccessFile °ú °°ÀÌ ÀÓÀÇÀÇ ºÎºÐ¿¡ Á¢±ÙÇØ¼­ Àд °Íµµ ±âÁ¸¿¡ ºñÇØ ¼º´ÉÀÌ ¸¹ÀÌ °³¼±µÇ¾ú´Ù. À̰ÍÀº ±âÁ¸ÀÇ BufferedInputStream À¸·Î ƯÁ¤ ºí·ÏÀ» Àд °Íº¸´Ù ÈξÀ ´õ ¸¹Àº ºÎºÐÀ» ¸Þ¸ð¸® ¾ÈÀ¸·Î ÆÄÀÏÀ» ÆäÀÌÁö(page) ÇØ¼­ OS °¡ Àб⠶§¹®ÀÌ´Ù. µÎ ¹øÂ°´Â MappedByteBuffer¸¦ ÀÌ¿ëÇØ¼­ ÆÄÀÏÀ» º¸³»´Â °ÍÀÌ »ó´çÈ÷ °£´ÜÇÏ´Ù´Â °ÍÀÌ´Ù.

ByteBufferPool ¼Ò½º¸¦ º¸¸é ³»ºÎÀûÀ¸·Î 2°³ÀÇ Å¥¸¦ ¸¸µç´Ù. ¸Þ¸ð¸® ¹öÆÛ¿Í ÆÄÀÏ ¹öÆÛ¸¦ °ü¸®Çϱâ À§ÇÑ Å¥´Ù. »ý¼ºÀÚ¿¡¼­ ÀüÁ¦ÀûÀ¸·Î »ç¿ëÇÒ ¸Þ¸ð¸® Å©±â¿Í ÆÄÀÏ Å©±â ¹× ÆÄÀÏÀ» ¹Þ¾Æ¼­ °¢°¢ÀÇ ¹öÆÛ¸¦ ¸¸µç´Ù. wait º¯¼ö´Â Å¥¿¡ ´ë±âÁßÀÎ ¹öÆÛ°¡ ¾øÀ» °æ¿ì ±â´Ù¸±Áö ¿©ºÎ¸¦ °áÁ¤ÇÏ´Â Ç÷¡±×´Ù. ¿ì¸®°¡ Á÷Á¢ÀûÀ¸·Î Á¢±ÙÇØ¼­ »ç¿ëÇÒ ¼ö ÀÖ´Â ¸Þ¼Òµå´Â public À¸·Î ¼±¾ðµÈ °ÍµéÀÌ´Ù. ±âº»ÀûÀ¸·Î ¿ì¸®´Â getMemoryBuffer()¸¦ ÅëÇØ¼­ ¸Þ¸ð¸® ¹öÆÛ¸¦ »ç¿ëÇÒ °ÍÀÌ´Ù. ¼Ò½º¸¦ º¸¸é ¾Ë ¼ö ÀÖ°ÚÁö¸¸ ¸¸¾à ¸Þ¸ð¸® ¹öÆÛ¸¦ ¾òÀ¸·Á ÇÑ °æ¿ì Å¥¿¡ ´ë±âÁßÀÎ ¸Þ¸ð¸® ¹öÆÛ°¡ ¾øÀ» °æ¿ì¿¡´Â ÆÄÀÏ ¹öÆÛ¸¦ ¾ò±â À§ÇØ ½ÃµµÇÏ°í ±× ¹Ý´ëÀÇ °æ¿ì¿¡´Â ÆÄÀÏ ¹öÆÛ¸¦ ¾ò±â À§ÇØ ½ÃµµÇÒ °ÍÀÌ´Ù. µû¶ó¼­ ´ëºÎºÐ ¸Þ¸ð¸® ¹öÆÛ¸¦ ¸ÕÀú »ç¿ëÇÒ °ÍÀ̹ǷΠ¸Þ¸ð¸® ºÎÁ·À¸·Î ÀÎÇÑ ±â´Ù¸²À̳ª ½Ã½ºÅÛ ´Ù¿îÀ» ÆÄÀÏ ¹öÆÛ°¡ Ä¿¹öÇØÁÖ´Â ÇÑ¿¡¼­ ¿¹¹æÇÒ ¼ö ÀÖ´Ù.

¹æÈ­º®À» ¶Õ±â(Firewall Tunneling) À§ÇØ Http Åë½ÅÀ» ÀÌ¿ëÇÏÀÚ
¹æÈ­º®Àº ÆÐŶ ÇÊÅÍ¿Í ¾ÖÇø®ÄÉÀÌ¼Ç °èÃþ °ÔÀÌÆ®¿þÀÌ(ÇÁ¶ô½Ã)¶ó´Â µÎ°¡Áö ÇüŰ¡ Á¸ÀçÇÑ´Ù. ÆÐŶ ÇÊÅ͸µÀº º¸Åë ¿ÜºÎ¿Í ÀÎÅÍÆäÀ̽º¶ó´Â ¶ó¿ìÅÍÀÇ IP °èÃþ¿¡¼­ ÀϾ´Ù. ÆÐŶ ÇÊÅ͸µ ½Ã¿¡´Â Á¢±Ù Á¦¾î ¸®½ºÆ®¸¦ ÂüÁ¶Çؼ­ ³»ºÎ È£½ºÆ®·ÎÀÇ ÆÐŶÀ» Çã¿ëÇÒÁö ¿©ºÎ¸¦ °áÁ¤ÇÏ°Ô µÈ´Ù. ¾ÖÇø®ÄÉÀÌ¼Ç °èÃþ °ÔÀÌÆ®¿þÀÌ´Â º¸Åë ÇÁ¶ô½Ã¶ó´Â À̸§À¸·Î ¾Ë·ÁÁ® Àִµ¥ Ŭ¶óÀÌ¾ðÆ®°¡ ¿ÜºÎ·ÎÀÇ Á¢¼ÓÀ» ¸ÎÀ¸·Á ÇÒ ¶§ ³»ºÎ Ŭ¶óÀÌ¾ðÆ®¿Í ¿ÜºÎ ¼­ºñ½º¿ÍÀÇ »çÀ̸¦ Áß°èÇÏ´Â ¼­¹ö´Ù. º¸ÅëÀº ¿ÜºÎ È£½ºÆ®ÀÇ 80¹ø Æ÷Æ®·Î ³ª°¡´Â ³»ºÎ Ŭ¶óÀ̾ðÆ®ÀÇ Á¢¼ÓÀ» ¹Þ¾ÆµéÀδÙ.

ÇÊÀÚ°¡ ¸¸µç ¼­¹ö´Â 4567¹ø Æ÷Æ®¸¦ »ç¿ëÇϴµ¥ ¸¸¾à ÇÁ¶ô½Ã ¼­¹ö¸¦ °í·ÁÇÑ´Ù¸é ¼­¹öÀÇ Æ÷Æ®¸¦ 80¹øÀ¸·Î ¹Ù²Ù°í Ŭ¶óÀÌ¾ðÆ®¿¡¼­ System.setProperties() ¸Þ¼Òµå·Î ÇÁ¶ô½Ã ¼­¹ö·Î ¸ÕÀú Á¢¼ÓÇϵµ·Ï ¸¸µé¾î¾ß ÇÑ´Ù. ÇÏÁö¸¸ ÆíÀÇ»ó ÇÊÀÚ´Â ÇÁ¶ô½Ã ¼­¹ö¸¦ ÀÌ¿ëÇÑ ¹æÈ­º®Àº °í·ÁÇÏÁö ¾Ê¾Ò´Ù. ¶ÇÇÑ http ÇÁ·ÎÅäÄÝÀÇ ´Ù¾çÇÑ Äڵ忡 ´ëÇÑ Ã³¸®µµ ÇÏÁö ¾Ê¾Ò´Ù. µû¶ó¼­ ±×³É ÀϹÝÀûÀÎ http ÇÁ·ÎÅäÄÝÀ» Çã¿ëÇÏ´Â ¹æÈ­º® Åë°ú¸¦ À§ÇØ Å¬¶óÀÌ¾ðÆ®¿¡¼­ ¼­¹ö·Î ¿äûÀ» º¸³¾¶§¿Í ¼­¹ö¿¡¼­ Ŭ¶óÀÌ¾ðÆ®·Î ÀÀ´äÇÒ ¶§ ´ÙÀ½°ú °°ÀÌ °¢°¢ http ¿äû-ÀÀ´ä Çì´õ¸¸ ºÙ¿©¼­ »ç¿ëÇß´Ù.

private static final String HttpRequestHeader = "POST / HTTP/1.1\r\n\r\n";
private static final String HttpResponseHeader = "HTTP/1.1 200 OK\r\n\r\n";

ÇÁ·ÎÅäÄÝ¿¡ XMLÀ» ÀÔÈ÷ÀÚ
ÇÊÀÚ´Â ¼­¹ö°£ Åë½Å ¸Þ½ÃÁö¿¡ xmlÀ» »ç¿ëÇß´Ù. ±× ÀÌÀ¯´Â xml Àº »ç¶÷°ú ±â°è(ÄÄÇ»ÅÍ) ¸ðµÎ°¡ ÀÌÇØÇϱ⠽¬¿î ±¸Á¶·Î µÇ¾î ÀÖ°í ÀÌ¹Ì ³Î¸® ¾Ë·ÁÁ® ÀÖµíÀÌ W3C ¿¡ ÀÇÇØ Ç¥ÁØÀÌ µÈ ¾ð¾îÀÌ´Ù. ÇÁ·ÎÅäÄÝ¿¡ xmlÀ» »ç¿ëÇÔÀ¸·Î½á ¾òÀ» ¼ö ÀÌÁ¡Àº ¿©·¯ °¡Áö°¡ ÀÖÁö¸¸ ¿ì¼± ƯÁ¤ ¾ð¾î³ª ½Ã½ºÅÛ¿¡ Á¾¼ÓÀûÀÌÁö ¾Ê´Ù´Â Á¡ÀÌ´Ù. xml ·Î ÀÛ¼ºµÈ ¿ì¸®ÀÇ Åë½Å ÇÁ·ÎÅäÄÝÀº ¾î¶² ¿î¿µÃ¼Á¦³ª ÇÁ·Î±×·¥ ¾ð¾î¿¡¼­µµ ½±°Ô ÀÎ½Ä ¹× »ç¿ë °¡´ÉÇÏ´Ù. µÎ ¹øÂ°·Î´Â xml ¾ð¾î ÀÚü°¡ °®´Â È®À强ÀÌ ºÎ·ÏÀ¸·Î µû¶ó¿À±â ¶§¹®ÀÌ´Ù. ¸¸¾à ÇÁ·ÎÅäÄÝÀÇ È®ÀåÀÌ ÇÊ¿äÇÒ ¶§ ÀÌ¹Ì xmlÀ» »ç¿ëÇϰí ÀÖ¾ú´Ù¸é Å« °í¹Î¾øÀÌ ½±°Ô È®Àå ÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù. Áï, xml ÀÇ »ç¿ëÀ¸·Î ÇÁ·ÎÅäÄÝÀÇ È®À强°ú À¯¿¬¼ºÀ» °®°Ô µÈ´Ù°í ¸»ÇÒ ¼ö ÀÖ´Ù. ¼¼ ¹øÂ°·Î´Â ¸¸¾à ¿ì¸®ÀÇ Åë½Å ÇÁ·ÎÅäÄÝÀÌ Àß Á¤Àǰ¡ µÇ¾î ÀÖ´Ù¸é SOAP °ú °°ÀÌ Ç¥ÁØÀ¸·Î¼­ ÀÎÁ¤µÇ¾î »ç¿ëµÉ ¼ö ÀÖ´Ù´Â °ÍÀÌ´Ù. ¾ÆÁ÷ Ç¥ÁØÀ¸·Î ÀÎÁ¤µÇÁö´Â ¾Ê¾ÒÁö¸¸ jabber ¶ó´Â Ç÷§Æû¿¡¼± ÀÌ¹Ì ¸î ³â ÀüºÎÅÍ Àß ±¸Á¶È­µÈ ÇÁ·ÎÅäÄÝÀ» Á¤ÀÇÇØ¼­ »ç¿ëÇϰí ÀÖ´Ù. ÷¾ðÀÌÁö¸¸ ÇÊÀÚ´Â °³ÀÎÀûÀ¸·Î ÇöÀç IT ¾÷°èÀÇ ½Î¿òÀº ½ÇÁ¦ÀûÀÎ ±â¼úÀ̳ª Àü·« º¸´Ùµµ ÀÚ½ÅÀÇ ±â¼úÀ» Ç¥ÁØÀ¸·Î ¸¸µé±â À§ÇÑ Èû ½Î¿òÀ¸·Î »ý°¢Çϰí ÀÖ´Ù. µû¶ó¼­ Ç¥ÁØÀ̶ó´Â ¸»Àº Àû¾îµµ ÇÊÀÚ¿¡°Ô´Â Å« Àǹ̷Π´Ù°¡¿Â´Ù. ¸¶Áö¸·À¸·Î xml Àº ÇÁ·Î±×·¡¹Ö ¾ð¾î¿¡¼­ µ¥ÀÌÅÍ·Î »ç¿ëÇϱ⿡ »ó´çÈ÷ ´Ü¼øÇÏ°í °£ÆíÇÏ´Ù. ÇÊÀÚ°¡ ¸¸µç ¼­¹ö¿¡¼­ »ç¿ëÇÑ Çü½ÄÀÇ ´ÙÀ½ xml ¸Þ½ÃÁö ±¸Á¶¸¦ º¸¸é ¾Ë ¼ö ÀÖ°ÚÁö¸¸ xmlÀ» ¸ð¸£´õ¶óµµ ½±°Ô ÀÌÇØÇÒ ¼ö ÀÖÀ» °ÍÀÌ´Ù.

<?xml version='1.0' encoding='UTF-8'?>
<request>
<command>MessageCommand</command>
<message>¾È³çÇϼ¼¿ä~!</message>
</request>

<?xml version='1.0' encoding='UTF-8'?>
<response>
<message>³×. ¹Ý°©½À´Ï´Ù.</message>
</response>


ÇÊÀÚ´Â ¿¹Á¦·Î ¸¸µç ¼­¹ö¿¡¼­ ´ÜÁö Ŭ¶óÀÌ¾ðÆ®°¡ º¸³½ ¸Þ½ÃÁö¸¦ ºê·Îµåij½ºÆ® ÇÏ´Â ¹æ½ÄÀ¸·Î¸¸ ±¸ÇöÇßÁö¸¸ ½ÇÁ¦ ¸Þ½ÅÀú µîÀ» ¸¸µç´Ù°í »ý°¢Çϸé xmlÀ» ÀÌ¿ëÇÔÀ¸·Î½á ¾ó¸¶³ª ¸íÄèÇÏ°í Æí¸®ÇÏ°Ô ±¸ÇöÇÒ ¼ö ÀÖÀ»Áö°¡ ÇǺηΠ¿Í ´êÀ¸¸®¶ó »ý°¢ÇÑ´Ù. ¹°·Ð Àü¼Û µ¥ÀÌÅÍÀÇ ¾çÀÌ Á¶±Ý ´õ ¸¹¾ÆÁö¹Ç·Î ¼Óµµ¸é¿¡¼­´Â ¾à°£ÀÇ ¼ÕÇØ¸¦ º¼ °ÍÀÌ´Ù. ÇÏÁö¸¸ Çö¸íÇÑ µ¶ÀÚµéÀº xml »ç¿ë½Ã ¾ò´Â ÀåÁ¡¿¡ ÃÊÁ¡À» ¸ÂÃâ°Å¶ó »ý°¢ÇÑ´Ù.

Dynamic Class Loading °ú Command ÆÐÅÏÀ» ÀÌ¿ëÇÏ¿© "¸ØÃßÁö ¾Ê´Â ¼­¹ö" ¸¸µé±â
Áö³­ 3³â°£ ÀÚ¹Ù¸¦ °øºÎÇϸ鼭 ÇÊÀÚ¸¦ °¡Àå ÈïºÐ½ÃÄ×´ø ÀÚ¹ÙÀÇ Æ¯Â¡ÀÌ ¹Ù·Î ÀÚ¹ÙÀÇ Dynamic Class Loading ÀÌ¿´´Ù. ÄÄÆÄÀϽÿ¡ ¾î¶² Ŭ·¡½º°¡ ¾²ÀÏ °ÍÀ̶ó´Â »ç½ÇÀ» ¸ð¸£´õ¶óµµ ·±Å¸ÀÓ¿¡ ÇÊ¿äÇÑ Å¬·¡½º¸¦ ã¾Æ¼­ »ç¿ëÇÑ´Ù´Â °ÍÀÌ ¾ó¸¶³ª ÇÊÀÚÀÇ °¡½¿À» µÎ±Ù°Å¸®°Ô Çß¾ú´ÂÁö...

ÀÌÁ¦ºÎÅÍ Command Pattern °ú ¹Ù·Î ÀÚ¹ÙÀÇ ¾ð¾îÀû Ư¡ Áß ÇϳªÀÎ Dynamic Class LoadingÀ» ÀÌ¿ëÇÏ¿© ¼­¹ö¸¦ ¸®ºÎÆÃ ÇÏÁö ¾Ê°íµµ ±â´É È®ÀåÀ» ÇÒ ¼ö ÀÖ´Â ¼­¹ö¸¦ ¸¸µé±â À§ÇÑ Å×Å©´ÐÀ» ¾Ë¾Æº¼ °ÍÀÌ´Ù. ±â´ëµÇÁö ¾Ê´Â°¡? ÀÚ, ±×·³ ¸¶À½À» °¡´Ùµë°í Á¤½ÅÀ» ÁýÁßÇØ¼­ »õ·Î¿î ¼¼»óÀ¸·Î ÇѰÉÀ½ ³ª¾Æ°¡º¸ÀÚ.

¸ÕÀú Dynamic Class Loading °ú Command Pattern ¿¡ ´ëÇØ¼­ ¾Ë¾Æº¸°í ÀÌ µÑÀ» ÀÌ¿ëÇØ¼­ ¾î¶»°Ô ¿ì¸®ÀÇ ¼­¹ö¸¦ ±â´É È®Àå½Ã¿¡ ¡°¸ØÃßÁö ¾Ê´Â ¼­¹ö¡±·Î ¸¸µé °ÍÀÎÁö¸¦ »ìÆìº¸µµ·Ï ÇÒ °ÍÀÌ´Ù.

ÀÚ¹Ù´Â JVM(ÀÚ¹Ù °¡»ó ¸Ó½Å) ½ÇÇà½Ã¿¡ java.lang.ClassLoader Ŭ·¡½º¿¡ ÀÇÇØ Äڵ尡 ¸µÅ©µÇ´Â µ¿Àû ¸µÅ© ½Ã½ºÅÛÀÌ´Ù. ¸ðµç Àڹ٠Ŭ·¡½º´Â ¸ðµÎ ¿¹¿Ü ¾øÀÌ ClassLoader¿¡ ÀÇÇØ ÀÚ¹Ù °¡»ó ¸Ó½Å ³»ºÎ·Î ·ÎµåµÈ´Ù. À̶§ 2°¡Áö ¹æ½ÄÀÇ ·ÎµùÀ» »ç¿ëÇϴµ¥ ¹Ù·Î ·ÎµåŸÀÓ µ¿Àû ·Îµù°ú ·±Å¸ÀÓ µ¿Àû ·ÎµùÀÌ´Ù.

¿ì¼± ¿ì¸®°¡ ÀϹÝÀûÀ¸·Î »ç¿ëÇÏ´ø ·ÎµåŸÀÓ µ¿Àû ·ÎµùÀ» º¸µµ·Ï ÇÏÀÚ.

public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, world!");
}
}


À§ÀÇ Äڵ忡¼± JVMÀÌ HelloWorld Ŭ·¡½º¸¦ ·ÎµåÇÒ ¶§, ÀÌ Å¬·¡½º ¾È¿¡¼­ System Ŭ·¡½º°¡ »ç¿ëµÈ´Ù°í ÄÄÆÄÀÏ·¯°¡ JVM ¿¡°Ô ¾Ë·ÁÁÖ°í ±×·³ JVMÀº HelloWorld Ŭ·¡½º ·ÎµùÀ» Àá½Ã Áß´ÜÇϰí System Ŭ·¡½º¸¦ ·ÎµùÇÑ ÈÄ¿¡ ´Ù½Ã HelloWorld Ŭ·¡½º¸¦ ·ÎµùÇÑ´Ù. Áï, HelloWorld Ŭ·¡½º ¾È¿¡¼­ »ç¿ëµÇ´Â ¸ðµç Ŭ·¡½ºµé(System À̿ܿ¡µµ ¸ðµç Ŭ·¡½º°¡ »ó¼ÓÇÏ´Â Object ¿Í System ¾È¿¡¼­ »ç¿ëµÇ´Â PrintStream Ŭ·¡½º)ÀÌ ·ÎµåŸÀÓ¿¡ ¹Ì¸® ·Îµå µÇ´Â °ÍÀÌ´Ù.

ÀÌ¿¡ ¹ÝÇØ ·±Å¸ÀÓ µ¿Àû ·ÎµùÀº ¾î·Á¿î °ÍÀº ¾Æ´ÏÁö¸¸ ¾Õ¼­ ¼³¸íÇÑ ·ÎµåŸÀÓ µ¿Àû ·Îµù°ú´Â ¾à°£ ´Ù¸¥ ¹æ½ÄÀ¸·Î »ç¿ëµÈ´Ù. ¾Æ·¡ Äڵ带 º¸°í ¡°¸¹ÀÌ º¸´ø°Çµ¥..¡° ÇÏ°í »ý°¢ÇϽô ºÐµéÀÌ °è½Ç°Å¶ó ÁüÀ۵ȴÙ.

Class cls = Class.forName("java.lang.String");
Object obj = cls.newInstance();
String s = (String) obj;


¡°Class.forName("org.gjt.mm.mysql.Driver")¡± °°ÀÌ JDBC¿¡¼­ ƯÁ¤ º¥´õÀÇ JDBC µå¶óÀ̹ö Ŭ·¡½º¸¦ ·ÎµùÇÒ ¶§ ¸¹ÀÌ º¸¾ÒÀ» °ÍÀÌ´Ù. À§ Äڵ忡¼­´Â forName() ¸Þ¼Òµå ¾ÈÀÇ ÀÎÀÚ·Î µé¾î¿Â String ¿¡ ÇØ´çÇϴ Ŭ·¡½º¸¦ ·±Å¸Àӽÿ¡ µ¿ÀûÀ¸·Î ·ÎµùÇÑ´Ù. ¼Ò½º¸¦ ÅëÇØ¼­µµ ¾Ë ¼ö ÀÖ°ÚÁö¸¸ forName() ¸Þ¼Òµå¸¦ ÅëÇØ ¸®ÅϵǴ °ÍÀº Class ´Ù. À̰ÍÀ» newInstance() ¸Þ¼Òµå¸¦ ÅëÇØ Object ŸÀÔÀ¸·Î ¹Ù²Ù°í À̰ÍÀ» ´Ù½Ã ¿øÇÏ´Â ÀûÀýÇÑ Å¸ÀÔÀ¸·Î ij½ºÆÃÇØ¼­ »ç¿ëÇÏ¸é µÇ´Â °ÍÀÌ´Ù. ÀÚ¹ÙÀÇ ·±Å¸ÀÓ µ¿Àû ·ÎµùÀÇ ÇѰ谡 ÀÖ´Ù¸é ¹Ù·Î ·ÎµùÇÒ Å¬·¡½ºÀÇ À̸§(ÆÐŰÁö¸¦ Æ÷ÇÔÇÑ)°ú ½ÇÁ¦ ŸÀÔ(ij½ºÆÃÇÒ Å¸ÀÔ)À» ¾Ë¾Æ¾ß¸¸ ÇÑ´Ù´Â °ÍÀÌ´Ù. ÇÏÁö¸¸ ÀÚ¹ÙÀÇ ·±Å¸ÀÓ µ¿Àû ·ÎµùÀº ±×·± ÇѰ踦 ±Øº¹ÇÏ°íµµ ³²À» ¸¸Å­ÀÇ ÃæºÐÇÑ °¡Ä¡°¡ ÀÖ´Ù.

<±×¸² 2>´Â ÇÊÀÚ°¡ ¸¸µç ¿¹Á¦ ¼Ò½º¿¡¼­ Command ÆÐÅÏÀÇ »ç¿ë ºÎºÐÀ» º¸¿©ÁÖ°í ÀÖ´Ù. ÀÌ ±â»ç´Â UML À̳ª DP(Design pattern)¸¦ ¼³¸íÇÏ´Â °ÍÀÌ ¸ñÀûÀÌ ¾Æ´Ï±â¿¡ ±×°ÍµéÀÌ ¿¹Á¦ ¼Ò½º¿¡¼­ ´Ü¼øÈ÷ ¾î¶»°Ô »ç¿ëµÇ¾ú´ÂÁö¿¡ ÃÊÁ¡À» ¸ÂÃç¼­ ¼³¸íÇϰڴÙ. WorkerThread¿¡¼­ Ŭ¶óÀÌ¾ðÆ®°¡ ¿äûÇÑ µ¥ÀÌÅ͸¦ ÆÄ½ÌÇØ¼­ Ä¿¸Çµå¿Í ¸Þ½ÃÁö¸¦ ºÐ¸®ÇÑ ÈÄ¿¡ Ä¿¸Çµå À̸§°ú °°Àº Ŭ·¡½º°¡ ÀÖ´ÂÁö¸¦ µ¿ÀûÀ¸·Î ã´Â´Ù. ¸¸¾à ÀÖ´Ù¸é ±× Å¬·¡½º¸¦ <±×¸² 2>¿¡¼­¿Í °°ÀÌ AbstractCommand Çü½ÄÀÇ »óÀ§ ŸÀÔÀ¸·Î ij½ºÆÃÇØ¼­ execute() ¸Þ¼Òµå¸¦ ½ÇÇà½ÃÄÑ ¼­ºñ½º¸¦ ÇÑ´Ù. ½ÇÁ¦·Î ¼öÇàµÇ´Â execute() ¸Þ¼Òµå´Â AbstractCommand Ŭ·¡½º¸¦ »ó¼ÓÇÑ ¿ì¸®°¡ µ¿ÀûÀ¸·Î ãÀº ¼­ºê Ä¿¸Çµå Ŭ·¡½ºÀÇ execute() ¸Þ¼ÒµåÀÌ´Ù. ¶ÇÇÑ ¿ì¸®´Â ÀÌ·¸°Ô »ç¿ëÇÒ Ä¿¸Çµå °´Ã¼¸¦ Àç»ç¿ëÇϱâ À§ÇØ ¼­¹ö¿¡ HashMap ÀúÀå¼Ò¸¦ Çϳª ¸¸µé°í À̰÷¿¡ óÀ½ »ý¼ºµÈ Ä¿¸Çµå Ŭ·¡½º¸¦ ÀúÀåÇØ¼­ Àç»ç¿ëÇÏ·Á°í ½ÃµµÇÒ °ÍÀÌ´Ù. ¸¸¾à ÀÌ¹Ì ÀúÀåµÇ¾î ÀÖ´Ù¸é ¾ÕÀ¸·Î´Â HashMap ÀúÀå¼Ò¿¡¼­ ÀúÀåµÈ Ä¿¸Çµå¸¦ ²¨³»¿Í¼­ »ç¿ëÇÏ°Ô µÈ´Ù. À̶§ ÀϺΠµ¶ÀÚ´Â ¸ÖƼ ¾²·¹µå ȯ°æ¿¡¼­ ÇϳªÀÇ °´Ã¼·Î ¼­ºñ½º ÇÏ´Â°Ô ¾ÈÀüÇѰ¡ ÇÏ´Â Áú¹®À» ´øÁö½Ã´Â ºÐµµ °è½Ã¸®¶ó »ý°¢µÈ´Ù. ±× ´äÀº ¡°¾ÈÀüÇÏ´Ù¡± ÀÌ´Ù. ¿Ö³ÄÇϸé Ä¿¸Çµå °´Ã¼¸¦ ÀÌ¿ëÇÏ´Â °ÍÀº ¾²·¹µåÀ̱⠶§¹®ÀÌ´Ù. ¾Õ¼­µµ ¼³¸íÇßµíÀÌ ¾²·¹µå´Â ÀڽŸ¸ÀÇ ½ºÅà ¿µ¿ª°ú CPU¸¦ Á¡À¯Çؼ­ »ç¿ëÇÑ´Ù°í Çß´Ù. ¿©±â¼­ ÀÚ½ÅÀÇ ½ºÅÃÀ» »ç¿ëÇÑ´Ù´Â ¸»Àº µ¥ÀÌÅÍ Ã³¸®¿¡ ÀÖ¾î ¿©·¯ ¾²·¹µå°¡ µ¿½Ã Á¢±ÙÀ» ÇÑ´Ù°í ÇØµµ ÀÚ½ÅÀÇ ½ºÅþȿ¡¼­ °ü·Ã µ¥ÀÌÅ͸¦ ó¸®ÇϹǷΠ¾ÈÀüÇÏ´Ù´Â ¸»ÀÌ´Ù.(¹°·Ð static °°Àº Á¤Àû µ¥ÀÌÅͳª Ŭ·¡½º ¸â¹ö·Î ¼±¾ðµÈ Çʵå´Â ¾²·¹µåµé »çÀÌ¿¡¼­ °øÀ¯µÈ´Ù.) Áö±Ý±îÁö °è¼Ó »ìÆìº¸¾ÒµíÀÌ Àç»ç¿ëÇÒ ¼ö ÀÖ´Â °´Ã¼µéÀº ÃÖ´ëÇÑ Àç»ç¿ëÇÒ ¼ö ÀÖ°Ô ÇÏ´Â °ÍÀÌ Áß¿äÇÏ´Ù.



<±×¸² 2> Command ÆÐÅÏÀÇ Class Diagram

½ÇÁ¦ ¼­ºñ½º¸¦ ´ã´çÇÏ´Â WorkerThread
ByteBuffer ¿¡ µ¥ÀÌÅ͸¦ ³ÖÀ» ¶§ 2°¡Áö ¹®Á¦Á¡À» ¸ÂÀÌÇÏ°Ô µÈ´Ù. ¹Ù·Î ¹ÙÀÌÆ® ¼ø¼­(byte ordering)¿Í ij¸¯ÅÍ º¯È¯(character conversion)ÀÌ´Ù. ByteBuffer ´Â ³»ºÎÀûÀ¸·Î ByteOrder Ŭ·¡½º¸¦ »ç¿ëÇØ¼­ ¹ÙÀÌÆ® ¼ø¼­¸¦ °áÁ¤ÇÑ´Ù. Big-endian °ú Little-endian µÎ°¡Áö·Î ¼³Á¤ÇÒ ¼ö Àִµ¥ ±âº»ÀûÀ¸·Î ByteBuffer ´Â Big-endianÀ» »ç¿ëÇÑ´Ù. ¸¸¾à ´Ù¸¥ ¾ð¾î³ª À̱âÁ¾ÀÇ ½Ã½ºÅÛ°£ÀÇ Åë½ÅÀ» ÇØ¾ß ÇÑ´Ù¸é ¹ÙÀÌÆ® ¼ø¼­¸¦ °í·ÁÇØ¾ß ÇÏÁö¸¸ ÀÚ¹Ù°£ÀÇ Åë½ÅÀ̶ó¸é º°µµÀÇ Ã³¸®°¡ ÇÊ¿äÇÏÁö ¾ÊÀ¸¹Ç·Î ´õ ÀÌ»ó ¾ð±ÞÇÏÁö ¾Ê°Ú´Ù. À̰Ϳ¡ ´ëÇÑ ÀÚ¼¼ÇÑ ³»¿ëÀº ¼±ÀÇ °ø½Ä ¹®¼­ µîÀ» Âü°íÇϱ⠹ٶõ´Ù.
ÀÌÁ¦ ij¸¯ÅÍ º¯È¯¿¡ ´ëÇØ À̾߱â ÇÒ Â÷·Ê´Ù. ¿µ¾î±Ç ³ª¶óµéÀÇ °æ¿ì¿¡´Â ÇϳªÀÇ ¹®ÀÚ¸¦ 1¹ÙÀÌÆ®·Î Ç¥ÇöÇϰí ÀÖ°í ¶Ç ´ëºÎºÐÀÇ ¿øÃµ ±â¼úÀÌ ±×µé¿¡°Ô¼­ ³ª¿À±â ¶§¹®¿¡ ¿ì¸® ³ª¶ó¿Í °°Àº 2¹ÙÀÌÆ® ¹®È­±ÇÀÇ ÇÁ·Î±×·¡¸ÓµéÀº ´Ã ÀÎÄÚµù ¹®Á¦·Î °í½ÉÇÏ°Ô µÈ´Ù. ÇÊÀÚ´Â ¿¹Á¦ ¼Ò½º¿¡¼­ xmlÀ» »ç¿ëÇϱ⠶§¹®¿¡ UTF-8 Çü½ÄÀÇ À¯´ÏÄÚµå ÀÎÄÚµùÀ» »ç¿ëÇß´Ù.(¶ÇÇÑ ÀÚ¹Ù¿¡¼­´Â µðÆúÆ®·Î À¯´ÏÄڵ带 »ç¿ëÇϱ⠶§¹®¿¡)
º¸Åë ÀÎÄÚµùÀº getBytes() ¸Þ¼Òµå¿¡ ÆÄ¶ó¹ÌÅÍ·Î ÀÎÄÚµù ŸÀÔÀ» ¸í½ÃÇØ¼­ »ç¿ëÇÑ´Ù. ¶ÇÇÑ ´ëºÎºÐÀÇ °æ¿ì µðÄÚµùÀº ByteBuffer¸¦ Á÷Á¢ Á¦¾îÇØ¼­ »ç¿ëÇÏ°Ô µÇ´Âµ¥ ÀÎÄÚµù ¹× µðÄÚµù »ç¿ë¹ýÀº ´ÙÀ½°ú °°ÀÌ »ó´çÈ÷ °£´ÜÇÏ´Ù. (java.nio.charset ÆÐŰÁö¿¡ Æ÷ÇԵǾî ÀÖÀ½)

Charset charset = Charset.forName("UTF-8");
CharsetEncoder encoder = charset.newEncoder();
// ÀÎÄÚµå ÈÄ ¸®ÅϵǴ ¹öÆÛ´Â non-direct ¹öÆÛÀÓ¿¡ ÁÖÀÇ.
ByteBuffer encodedBuffer = encoder.encode(buffer);

Charset charset = Charset.forName("UTF-8");
CharsetDecoder decoder = charset.newDecoder();
CharBuffer charBuffer = decoder.decode(buffer);
String result = charBuffer.toString();


<source 3>Àº ½ÇÁ¦ ¼­ºñ½º¸¦ ´ã´çÇÏ´Â WorkerThread ´Ù. WorkerThread ÀÇ ÇÙ½É ¸Þ¼Òµå´Â requestProcess() ÀÌ´Ù. ÀÌ ¸Þ¼Òµå´Â Ŭ¶óÀ̾ðÆ®ÀÇ ¿äûÀ» Àо http Çì´õ¸¦ Á¦°ÅÇÏ°í ¸öü·Î µþ·Á¿Â xml ºÎºÐÀ» ÆÄ½ÌÇØ¼­ Ä¿¸Çµå¿Í ¸Þ½ÃÁö·Î ³ª´«´Ù. À̶§¿¡µµ xmlÀ» ÆÄ½ÌÇÏ´Â SaxHandler Ŭ·¡½º¸¦ ½Ì±ÛÅÏ ÆÐÅÏÀ» »ç¿ëÇØ¼­ Àç»ç¿ëÇÑ´Ù. ¼Ò½º¸¦ º¸¸é ¾Ë ¼ö ÀÖ°ÚÁö¸¸ ÆÐÅÏÀ̶ó°í ÇØ¼­ ¾î·Æ°Ô »ý°¢ ÇÒ °ÍÀº ¾ø´Ù. ¾Æ¸¶ ÷ºÎµÈ ¼Ò½º¸¦ º¸¸é ½±°Ô ÀÌÇØ°¡ °¥ °ÍÀÌ´Ù.
±× ÈÄ Ä¿¸Çµå¿Í °°Àº À̸§ÀÇ Ä¿¸Çµå Ŭ·¡½º¸¦ µ¿ÀûÀ¸·Î ã´Â´Ù. ±×¸®°í ±× Ŭ·¡½ºÀÇ execute() ¸Þ¼Òµå¸¦ È£ÃâÇØ¼­ Ŭ¶óÀÌ¾ðÆ®¿¡°Ô ÀÀ´äÀ» º¸³½´Ù. ÀÌ Ä¿¸Çµå °´Ã¼µµ ¾Õ¼­ ¼³¸íÇßµíÀÌ HashMap ¿¡ ÀúÀåÇØ¼­ Àç»ç¿ëÇÑ´Ù. ¶ÇÇÑ ¼­ºñ½º¸¦ ¸¶Ä¡°í ³­ ÈÄ¿¡´Â ByteBufferPool¿¡¼­ °¡Á®¿Â ByteBuffer¸¦ finish() ¸Þ¼Òµå¿¡¼­ ¹ÝȯÇϰí WorkerThread µµ run() ¸Þ¼Òµå ³¡ºÎºÐ¿¡¼­ ThreadPool ·Î ¹ÝȯÇÑ´Ù.(Àüü ¼Ò½º´Â ¡®ÀÌ´ÞÀÇ µð½ºÄÏ¡¯¿¡ ÷ºÎÇß´Ù)

<source 3> WorkerThread.java

public class WorkerThread extends Thread {

...

private void requestProcess(SelectionKey key) throws IOException {
SocketChannel sc = (SocketChannel) key.channel();
ByteBuffer buffer = bufferPool.getMemoryBuffer();
int count;

AbstractCommand command = null;

count = sc.read(buffer);
buffer.flip();

if (count < 0) {
server.removeUser(sc);
sc.close();
bufferPool.putBuffer(buffer);
key.selector().wakeup();
server.info("Ŭ¶óÀÌ¾ðÆ®°¡ Á¢¼ÓÀ» Á¾·áÇß½À´Ï´Ù.");
return;
}

charBuffer = decoder.decode(buffer);
String temp = charBuffer.toString();
byte[] bb = temp.substring(temp.indexOf("\r\n\r\n")).trim().getBytes("UTF-8");
String[] param = parsingXML(bb);
if (param == null) {
finish(buffer);
return;
}

if (server.isContainCommand(param[0])) {
command = server.getCommand(param[0]);
} else {
try {
command = (AbstractCommand) Class.forName(CommandPath + param[0]).newInstance();
} catch (Exception e) {
server.info("¸í·ÉÀ» ¼öÇàÇÏ´Â Ä¿¸Çµå Ŭ·¡½º°¡ Á¸ÀçÇÏ´ÂÁö È®ÀÎÇØº¸¼¼¿ä.");
finish(buffer);
return;
}

if (command == null) {
finish(buffer);
return;
} else {
server.putCommand(param[0], command);
}
}
buffer.clear();
command.execute(server, buffer, param[1]);
finish(buffer);
}

private void finish(ByteBuffer buffer) {
bufferPool.putBuffer(buffer);
key.interestOps(key.interestOps() | SelectionKey.OP_READ);
key.selector().wakeup();
}

private String[] parsingXML(byte[] xml) {
String[] param = null;
ArrayList list = null;

if (xml == null)
return param;

in = new ByteArrayInputStream(xml);
try {
handler = SaxHandler.getInstance();
parser.parse(in, handler);
list = handler.getContents();
} catch (SAXException e) {
server.log(Level.WARNING, "WorkerThread/parsingXML()", e);
} catch (IOException ex) {
server.log(Level.WARNING, "WorkerThread/parsingXML()", ex);
}

param = new String[list.size()];
for (int i = 0; i < list.size(); i++) {
param[i] = (String) list.get(i);
}
handler.clearSaxHandler();
return param;
}
}


Ŭ¶óÀÌ¾ðÆ® ¾ÖÇø®ÄÉÀ̼Ç
ÇÊÀÚ´Â Áö³­¹ø¿¡ ¸»Çß´ø °Íó·³ Ŭ¶óÀÌ¾ðÆ®µµ nio(´Ï¿À)¸¦ »ç¿ëÇØ¼­ ¸¸µé¾ú´Ù. ¼­¹ö¿Í ´Þ¸® Ŭ¶óÀÌ¾ðÆ®´Â ¸¹Àº ¾çÀÇ µ¿½Ã󸮰¡ ÇÊ¿äÇÏÁö ¾ÊÀ¸¹Ç·Î ²À nio¸¦ »ç¿ëÇÒ ÇÊ¿ä´Â ¾ø´Ù. ¹°·Ð nio¸¦ »ç¿ëÇÏ¸é ºí·¯Å·ÀÌ ¾ø¾î Á» ´õ È¿À²ÀûÀÌÁö¸¸ ¸»ÀÌ´Ù. ±×·¯³ª ¾ÈÁ¤¼ºÀ» »ý°¢Çؼ­ Ŭ¶óÀÌ¾ðÆ®´Â ±âÁ¸ÀÇ ¼ÒÄÏÀ¸·Î ¸¸µå´Â °ÍÀÌ ´õ ÁÁÀ» µí ÇÏ´Ù. ÇÊÀÚ°¡ ½Ã°£ °ü°è»ó Ŭ¶óÀÌ¾ðÆ®´Â °ÅÀÇ ½Å°æÀ» ¾²Áö ¸øÇÏ°í ¿¹Á¦ ¼Ò½º¸¦ ¸¸µé¾úÁö¸¸ ¸¸¾à Á¦´ë·Î µÈ ±¸Á¶¸¦ °®Ãß°Ô ¼³°èÇÑ´Ù¸é Ŭ¶óÀÌ¾ðÆ®µµ <±×¸² 3>°ú °°ÀÌ À̺¥Æ® Á᫐ ¼³°è¸¦ ÇÏ´Â °ÍÀÌ ¹Ù¶÷Á÷ÇÏ´Ù. Áï, ¼­¹ö¿¡¼­ µµÂøÇÑ ¸ðµç ÀÀ´ä(À̺¥Æ®)À» Ä¿¸Çµå¿Í ¸Þ½ÃÁö µîÀ¸·Î ³ª´²¼­ °´Ã¼·Î Æ÷ÀåÇÏ°í ±× °´Ã¼¸¦ Å¥¿¡ ½×¾ÆµÎ°í Å¥¿¡ Á¢±ÙÇÏ´Â º°µµÀÇ ¼ÒºñÀÚ ¾²·¹µå°¡ Áö¼ÓÀûÀ¸·Î Å¥¸¦ üũÇϸ鼭 ó¸®ÇØ ³ª°¡´Â °ÍÀÌ´Ù. ÀÌ·¸°Ô ÇÏ´Â ÀÌÀ¯´Â Ŭ¶óÀÌ¾ðÆ® ÇÁ·Î±×·¥ÀÌ ¹Ýµå½Ã ¼­¹ö¿Í ´Ü ÇϳªÀÇ ¿¬°á¸¸À» °®°Ô µÈ´Ù´Â º¸ÀåÀÌ ¾ø°í ´ë°³ÀÇ °æ¿ì ÁÖ·Î ¿©·¯°³ÀÇ ¿¬°áÀ» À¯ÁöÇÏ´Â °æ¿ì°¡ ¸¹±â ¶§¹®ÀÌ´Ù. ¿¹¸¦ µé¾î MSN ¸Þ½ÅÀú Ŭ¶óÀÌ¾ðÆ®¸¦ °³¹ßÇÑ´Ù°í ÇßÀ» °æ¿ì MSN ¸Þ½ÅÀú´Â ÀÚ½ÅÀÇ »óÅ ¹× ´ëÈ­¸í µîÀ» °ü¸®ÇØÁÖ´Â Dispatcher ¼­¹ö¿Í ÇϳªÀÇ ¿¬°áÀÌ »ý¼ºµÇ°í Ä£±¸¿Í ´ëÈ­¸¦ ÇÒ ¶§¿¡´Â Switchboard ¼­¹ö¿¡ ¿¬°áÇØ¼­ 󸮸¦ ÇÑ´Ù. À̶§ ¼­¹ö·ÎºÎÅÍ µé¾î¿À´Â ¸ðµç ÀÀ´äÀ» ÇÑ °÷¿¡¼­ °ü¸®ÇÏ´Â °ÍÀÌ À¯Áöº¸¼ö³ª È®À强 µî¿¡¼­ Á» ´õ À¯¿ëÇϱ⠶§¹®ÀÌ´Ù. µû¶ó¼­ ÇÊÀÚ´Â ´ëºÎºÐÀÇ Å¬¶óÀÌ¾ðÆ® ¼ÒÄÏ ¾ÖÇø®ÄÉÀ̼ÇÀÇ °æ¿ì À̺¥Æ® Á᫐ ¼³°è°¡ ÈǸ¢ÇÑ ¸ðµ¨ÀÌ µÉ °ÍÀ̶ó°í »ý°¢ÇÑ´Ù.
±×¸®°í ¼­¹ö¿Í °°ÀÌ Command ÆÐÅÏÀ» µµÀÔÇØ¼­ ¼Õ½¬¿î È®ÀåÀÌ °¡´ÉÇϵµ·Ï ¸¸µé°í ¿©±â¿¡ ·±Å¸ÀÓ µ¿Àû ·ÎµùÀ» Ãß°¡ÇØ Å¬¶óÀÌ¾ðÆ®¸¦ ¾÷±×·¹À̵å ÇÒ ¶§ UI ºÎºÐÀÌ ¾Æ´Ñ ±â´É»óÀÇ º¯È­¶ó¸é ±»ÀÌ ÇÁ·Î±×·¥À» Àç½ÃÀÛ ÇÏÁö ¾Ê¾Æµµ µÇ°Ô Çϸé Á» ´õ ÁÁÀ» °ÍÀÌ´Ù.



<±×¸² 3> À̺¥Æ® Á᫐ ¾ÆÅ°ÅØÃÄ




¿¬À縦 ¸¶Ä¡¸ç...
Áö±Ý±îÁö ¼­¹öÀÇ ¼º´ÉÀ» Çâ»ó½Ã۱â À§ÇØ °´Ã¼ÀÇ Àç»ç¿ë¿¡ ÁßÁ¡À» µÎ°í ÇÊ¿äÇÑ °ÍµéÀ» ÇϳªÇϳª¾¿ ¸¸µé¾î Ãß°¡ÇغôÙ. ¼º´ÉÇâ»óÀ» À§ÇØ Æ¯º°ÇÑ ±â¼úÀ» »ç¿ëÇÑ °ÍÀº ¾ø¾ú´Ù. ´ÜÁö Àç»ç¿ëÇÒ ¼ö ÀÖ´Â °´Ã¼µéÀ» Àç»ç¿ëÇÔÀ¸·Î½á Á» ´õ È¿À²ÀûÀ¸·Î ¸Þ¸ð¸®¸¦ »ç¿ëÇÏ°í ¶ÇÇÑ °´Ã¼ÀÇ »ý¼ºÀ¸·Î ÀÎÇÑ ½Ã°£À» Àý¾àÇÒ ¼ö ÀÖ¾ú´Ù. ¶Ç ÀÌ·¸°Ô ÇÔÀ¸·Î½á ´«¿¡ º¸ÀÌÁö´Â ¾ÊÁö¸¸ °¡ºñÁö Ä÷ºÅÍÀÇ È£Ãâµµ Á¶±ÝÀº ÁÙ ÀÏ ¼ö À־ ÆÛÆ÷¸Õ½º Çâ»ó¿¡ µµ¿òÀÌ µÇ¾ú´Ù. Áö±Ý±îÁö ¿ì¸®°¡ °³¹ßÇÑ °ÍµéÀº ¼ÒÇÁÆ®¿þ¾îÀÇ °³¹ß½Ã¿¡ ÇÒ ¼ö ÀÖ´Â Æ©´× ÀÛ¾÷¿¡ ÇØ´çÇÑ´Ù. 2Â÷ÀûÀ¸·Î´Â ½ÇÁ¦·Î ¼­ºñ½º¸¦ Çϱâ À§ÇØ JVM ¿É¼ÇÀ» ÀÌ¿ëÇÏ¿© Èü(heap)À̳ª ¾²·¹µå Ãʱ⠽ºÅÃ(stack) »çÀÌÁî µîÀ» ÁöÁ¤ÇÔÀ¸·Î½á ¼º´ÉÀ» °³¼±ÇØ¾ß ÇÒ °ÍÀÌ´Ù. À̰ÍÀº ÃßÈÄ »ç¿ë ¼­ºñ½º¸¦ ÇÒ ¶§ ¸¹Àº Å×½ºÆ®¸¦ ÅëÇØ JVMÀ» ÃÖÀûÈ­ÇØ¾ß ÇÏ´Â °ÍÀ¸·Î µ¶ÀںеéÀÇ ¸òÀÌ´Ù. ¸¶Áö¸·À¸·Î µ¶Àڵ鿡°Ô ¹Ù¶÷ÀÌ ÀÖ´Ù¸é ¿ì¼± ÇÊÀÚ°¡ Á¦°øÇÑ ¿¹Á¦ ¼Ò½º¿¡ ±×Ä¡Áö ¸»°í Á» ´õ ³ªÀº äÆÃÀ̳ª ¸Þ½ÅÀú µîÀÇ ¼Ö·ç¼ÇÀ¸·Î ¹ßÀü½ÃÄ×À¸¸é ÇÏ°í ¶Ç ±×°ÍÀ» ³Ñ¾î¼­ ºÐ»ê󸮰¡ °¡´ÉÇÑ ´ë¿ë·®ÀÇ È®À强 ÀÖ´Â ¼­¹ö¸¦ ¸¸µé¾úÀ¸¸é ÇÑ´Ù. ±×·³ µ¶ÀںеéÀÇ Çà¿îÀ» ºô¸ç 2ȸ¿¡ °ÉÄ£ ±â»ç¸¦ ¸¶¹«¸® ÇϰڴÙ.

Âü°íÀÚ·á
1. Java Nio by Ron Hitchens, 2002 O'reilly

2. Patterns in Java Volume 1, Wiley

3. Server-Based Java Programming, ÀÎÆ÷ºÏ

4. Java Network Programming, ÀÎÆ÷ºÏ

5. http://www.jabber.org

6. http://developer.java.sun.com/developer/technicalArticles/InnerWorkings/JDCPerformTips

7. http://www.javaworld.com/javaworld/jw-09-2001/jw-0907-merlin.html

8. ¼Ò½º ÀÚ·á