Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
ÉîÈëÀí½âNettyÏß³ÌÄ£ÐÍ
 
  7373  次浏览      27
 2019-9-12
 
±à¼­ÍƼö:
±¾ÎÄÀ´×ÔÓÚ΢ÐŹ«ÖںţºOutOfMemoryError£¬±¾ÎÄÖ÷Òª½éÉÜÁËʲôÊÇI/O¶à·¸´Ó㬠ReactorÈýÖÖÏß³ÌÄ£ÐÍ £¬NettyÏß³ÌÄ£ÐÍ£¬NioEventLoopÔ´Âë·ÖÎöµÈÄÚÈÝ £¬Ï£Íû¶ÔÄúÄÜÓÐËù°ïÖú¡£

µ±ÎÒÃÇ̸ÂÛNettyµÄÏß³ÌÄ£ÐÍʱ£¬Ê×ÏÈ»áÏëµ½µÄÊǾ­µäµÄReactor IO¶à·¸´ÓÃÏß³ÌÄ£ÐÍ¡£´ÓÕâÆªÎÄÕÂÖУ¬´ó¼Ò¿ÉÒÔѧϰµ½ÈçÏÂ֪ʶ£º

ʲôÊÇI/O¶à·¸´ÓÃ

ReactorÈýÖÖÏß³ÌÄ£ÐÍ

NettyÏß³ÌÄ£ÐÍ

NioEventLoopÔ´Âë·ÖÎö

JDK epoll bug

ʲôÊÇI/O¶à·¸´ÓÃ

ѧϰI/O¶à·¸´ÓÃ֮ǰ£¬ÎÒÃÇÏÈÀ´Á˽âÈçϼ¸¸ö¸ÅÄ

×èÈûI/O£º¿Í»§¶Ë´ÓsocketÖжÁÈ¡Êý¾Ý»òдÈëÊý¾Ýʱ£¬Èç¹û¶ÁȡʱÁ÷ÖÐûÓÐÊý¾Ý£¬Ð´Èëʱ»º³åÇøÒÑÂú£¬¾ÍÐèÒªblock£¬ÖªµÀÁ÷ÖÐÓÐÊý¾Ý»òÕß»º³åÇøµÄÊý¾Ý±»Åſա£

·Ç×èÈûI/O£º¿Í»§¶Ë´ÓÁ÷ÖжÁÈ¡Êý¾Ý£¬Èç¹ûÁ÷ÖÐûÓÐÊý¾Ý£¬ÔòÁ¢¼´·µ»Ø£¬²»·¢Éúblock¡£

ͬ²½I/O£ºÍ¬²½I/O½«µ¼ÖÂÇëÇóµÄI/O²Ù×÷Ò»Ö±±»block£¬Ö±µ½I/OÍê³É¡£

Òì²½I/O£ºÒì²½I/O²»»áµ¼ÖÂblock£¬·¢³öI/OÇëÇóºóÁ¢¼´·µ»Ø£¬Ö±µ½Íê³ÉI/O²Ù×÷ºóÔÙÒ첽֪ͨµ÷Óýø³Ì¡£

I/O¶à·¸´ÓÿÉÒÔ¼àÊÓ¶à¸öFD£¨ÎļþÃèÊö·û£©£¬Ò»µ©Ä³¸öFD×¼±¸¾ÍÐ÷£¬¾Í»á֪ͨÏàÓ¦½ø³Ì´¦Àí¡£¶à·¸´ÓÃÒ²ÊÇ×èÈûµÄ£¬×èÈûµÄ·½·¨ÊÇselect/poll/epoll£¬¿ÉÒÔÔÚµ¥¸ö½ø³ÌÖÐͬʱ´¦Àí¶à¸öI/OÇëÇó£¬Ô­ÀíÊDzÉÓÃÂÖѯµÄ·½Ê½±ãÀûËùÓеÄI/O²Ù×÷£¬µ±Ä³Ð©I/OÓÐÊý¾Ýʱ£¬¾Í֪ͨÓû§½ø³Ì´¦Àí¡£

select£ºÏµÍ³Ìṩselectº¯ÊýÀ´ÊµÏÖ¶à·¸´ÓÃÊäÈë/Êä³öÄ£ÐÍ£¬selectϵͳµ÷ÓÃÊÇÓÃÀ´ÈÃÎÒÃǵijÌÐò¼àÊÓ¶à¸öÎļþ¾ä±úµÄ״̬±ä»¯¡£³ÌÐò»á×èÈûÔÚselectº¯ÊýÉÏ£¬Ö±µ½±»¼àÊÓµÄÎļþ¾ä±úÖÐÓÐÒ»¸ö»ò¶à¸ö·¢ÉúÁË״̬±ä»¯¡£

poll£ºpollº¯ÊýÓëselectº¯ÊýµÄ×î´ó²»Í¬Ö®´¦ÔÚÓÚ£ºselectº¯ÊýÓÐ×î´óÎļþÃèÊö·ûµÄÏÞÖÆ£¬Ò»°ã1024¸ö£¬¶øpollº¯Êý¶ÔÎļþÃèÊö·ûµÄÊýÁ¿Ã»ÓÐÏÞÖÆ¡£

epoll£º

¼àÊÓµÄÃèÊö·ûÊýÁ¿²»ÊÜÏÞÖÆ£¬ËùÖ§³ÖµÄFDÉÏÏÞÊÇLinuxϵͳ×î´ó¿ÉÒÔ´ò¿ªÎļþµÄÊýÄ¿£»

I/OЧÂʲ»»áËæ×żàÊÓfdµÄÊýÁ¿Ôö³¤¶øÏ½µ¡£epoll²»Í¬ÓÚselectºÍpollÂÖѯµÄ·½Ê½£¬¶øÊÇͨ¹ýÿ¸öfd¶¨ÒåµÄ»Øµ÷º¯ÊýÀ´ÊµÏֵģ¬Ö»ÓоÍÐ÷µÄfd²Å»áÖ´Ðлص÷º¯Êý¡£

ReactorÈýÖÖÏß³ÌÄ£ÐÍ

1. Reactorµ¥Ïß³ÌÄ£ÐÍ

ÊÇÖ¸ËùÓеÄI/O²Ù×÷¶¼ÔÚͬһ¸öNIOÏß³ÌÉÏÍê³É£¬Ö°ÔðÈçÏÂ

×÷ΪNIO·þÎñ¶Ë£¬½ÓÊÕ¿Í»§¶ËTCPÁ¬½Ó

×÷ΪNIO¿Í»§¶Ë£¬Ïò·þÎñ¶Ë·¢ÆðTCPÁ¬½Ó

¶ÁÈ¡¶Ô¶ËÇëÇó»òÕßÓ¦´ðÏûÏ¢

Ïò¶Ô¶Ë·¢ËÍÇëÇó»òÕßÓ¦´ðÏûÏ¢

ÔÚһЩСÈÝÁ¿³¡¾°Ï£¬¿ÉÒÔʹÓöàÏß³ÌÄ£ÐÍ£¬µ«¶ÔÓڸ߸ºÔس¡¾°Ï²¢²»ÊÊÓã¬Ô­ÒòÈçÏ£º

Ò»¸öNIOÏß³Ìͬʱ´¦Àí³É°ÙÉÏǧµÄÁ¬½Ó£¬ÐÔÄÜÉÏÎÞ·¨±£Ö¤¡£

NIOÏ̸߳ºÔعýÖØ£¬´¦ÀíËÙ¶È»áÔ½À´Ô½Âý£¬»áµ¼Ö´óÁ¿¿Í»§¶ËÁ¬½Ó³¬Ê±

Ò»µ©NIOÏß³ÌÅÜ·É£¬»òÕßËÀÑ­»·£¬»áµ¼ÖÂÕû¸öϵͳµÄ²»¿ÉÓÃ

2. Reactor¶àÏß³ÌÄ£ÐÍ

Óëµ¥Ïß³ÌÄ£ÐÍ×î´óµÄÇø±ðÊÇ£¬ÓÐÒ»×éNIOÀ´´¦ÀíI/OÇëÇó£¬ÌصãÈçÏÂ

ÓÐÒ»¸öNIOÏ̡߳ª¡ªAcceptorÏß³ÌÓû§¼àÌý¿Í»§¶ËµÄÁ¬½Ó

ÓÐÒ»¸öNIOÏ̳߳ظºÔðI/OµÄ¶Áд²Ù×÷£¬¸ÃÏ̳߳ؿÉÒÔÊÇ»ùÓÚJDKµÄÏ̳߳ء£

3. Ö÷´ÓReactor¶àÏß³ÌÄ£ÐÍ

Èç¹û²¢·¢°ÙÍòµÄ¿Í»§¶ËÁ¬½Ó£¬ÔÚReactor¶àÏß³ÌÄ£ÐÍÏÂÖ»ÓÐÒ»¸öNIOµÄAcceptorÏ̴߳¦Àí¿Í»§¶ËÁ¬½Ó»áÓÐÐÔÄÜÎÊÌâ¡£Ö÷´ÓReactorÏß³ÌÄ£Ð͵ÄÌØµãÊÇ£º·þÎñ¶ËÓÃÓÚ½ÓÊÕ¿Í»§¶ËµÄÁ¬½Ó²»ÔÙÊÇÒ»¸öµ¥¶ÀµÄNIOỊ̈߳¬¶øÊÇÒ»¸öNIOµÄAcceptorÏ̳߳ء£Acceptor½ÓÊÕµ½¿Í»§¶ËµÄTCPÁ¬½ÓÇëÇó´¦ÀíÍê³Éºó£¬½«Ð´´½¨µÄChannelSocket×¢²áµ½I/OÏ̳߳Ø(sub reactorÏ̳߳Ø)ÉϵÄijһ¸öÏß³ÌÉÏ£¬ÓÉI/O¸ºÔðºóÐøµÄI/O¶Áд²Ù×÷¡£

4. NettyÏß³ÌÄ£ÐÍ

»¹¼ÇµÃNetty·þÎñ¶ËÆô¶¯Ê±µÄ´úÂëÂ𣿣¿

EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();

·þÎñ¶ËÆô¶¯Ê±´´½¨ÁËÁ½¸öNioEventLoopGroup£¬ËûÃÇʵ¼ÊÉÏʱÁ½¸ö¶ÀÁ¢µÄReactorÏ̳߳أ¬Ò»¸ö¸ºÔð½ÓÊÕ¿Í»§¶ËµÄTCPÁ¬½Ó£¬ÁíÒ»¸öÓÃÓÚ´¦ÀíI/O²Ù×÷£¬»òÖ´ÐÐϵͳTask¡¢¶¨Ê±ÈÎÎñTaskµÈ£¬ÈçÉÏͼËùʾµÄÁ½¸ö·½·¨£º

NioEventLoop.execute(Runnable task)
NioEventLoop.schedule(Runnable task)

NioEventLoopÔ´Âë·ÖÎö

ÏÈÈÃÎÒÃÇÀ´¿´¿´NioEventLoopµÄ¼Ì³Ð¹ØÏµÍ¼

NioEventLoopÐèÒª´¦ÀíÍøÂçI/O²Ù×÷£¬Ê×ÏȾۺÏÁËÒ»¸ö¶à·¸´ÓÃÆ÷Selector,²¢ÇÒNioEventLoopµÄ¹¹Ôì·½·¨ÖÐÖ±½Óµ÷ÓÃopenSelector()·½·¨Íê³É³õʼ»¯¡£

´úÂëÖг£Á¿DISABLE_KEYSET_OPTIMIZATION(selectedKeysÓÅ»¯¿ª¹Ø)ĬÈÏΪfalse£¬Ôòͨ¹ý·´ÉäµÄ·½Ê½»ñµÃSelector£¬·ñÔòÖ±½Ó·µ»Ø¡£

½ÓÏÂÀ´Öص㿴һÏÂrun·½·¨

Õû¸örun·½·¨ÓÃÒ»¸öwhileÑ­»·°üΧ£¬Ê×ÏȽ«wakenUp²ÎÊýÉèÖÃΪfalse²¢½«¾ÉÖµ±£´æÔÚoldWakenUpÖС£

1¡¢µ÷ÓÃhasTask()Åж϶ÓÁÐÖÐÊÇ·ñÓÐÈÎÎñ£¬Èç¹ûÓÐÔòÖ´ÐÐselectNow()·½·¨£¬¸Ã·½·¨»áÁ¢¼´³ö·¢SelectµÄÑ¡Ôñ²Ù×÷ÅжÏÊÇ·ñÓÐ×¼±¸¾ÍÐ÷µÄChannel£¬Èç¹ûÓÐÔò·µ»ØChannelµÄ¼¯ºÏ£¬·ñÔò·µ»Ø0¡£

2¡¢Èç¹ûûÓÐÈÎÎñ£¬Ôòµ÷ÓÃselect()·½·¨ÂÖѯ,¿´ÊÇ·ñÓÐ×¼±¸¾ÍÐ÷µÄChannel£¬select()´úÂëÈçÏ£º

Åж϶ÓÁÐÖÐÊÇ·ñÓÐÒѳ¬Ê±»ò¼´½«Ö´ÐеĶ¨Ê±ÈÎÎñ£¬ÈçÓУ¬Ôòµ÷ÓÃselectNow()·½·¨²¢½«selectCntÖÃΪ1£¬²¢Í˳öµ±Ç°Ñ­»··µ»Ørun()·½·¨¡£·ñÔò½«³¬Ê±Ê±¼ä×÷Ϊ²ÎÊý½øÐÐselect()£¬Ã¿´Îselectºó¶¼Òª½«selectCnt++£¬Èç¹ûÂú×ãÈçÏÂÌõ¼þÔòÍ˳öÑ­»·¼ÌÐørun()·½·¨µÄºóÃæµÄÂß¼­¡£

if (selectedKeys != 0 || this.oldWakenUp || this.wakenUp.get() || this.hasTasks()) {
break;
}

Èç¹û±¾´ÎSelectorµÄÂÖѯ½á¹ûΪ¿Õ£¬ËµÃ÷ÕâÊÇÒ»¸ö¿ÕÂÖѯ£¬ÓпÉÄܳö·¢ÁËJDKµÄepoll bug£¬Õâ¸öbug»áµ¼ÖÂÒ»Ö±¿ÕÂÖѯʹI/OÏß³ÌÒ»Ö±´¦ÓÚ100%µÄ״̬£¬´Ëʱ¾ÍÐèÒªÖØ½¨SelectorÀ´±ÜÃâ·¢ÉúÕâÀàÎÊÌ⣬rebuildSelector()´úÂëÈçÏ£º

rebuildSelectorµÄÖ÷ÒªÂß¼­ÊÇ£ºÊ×ÏÈÅжÏÊÇ·ñÓÐÆäËûÏß³ÌÔÚ½øÐÐrebuild£¬ÈçÓÐÔò½«±¾´Î²Ù×÷·â×°³ÉÒ»¸ötask·ÅÈë¶ÓÁУ¬±ÜÃâ¶àÏß³Ìͬʱrebuild¡£È»ºó´´½¨ÐµÄSelector£¬Í¨¹ýÑ­»·½«×¢²áÔھɵÄSelectorÉϵÄSocketChannel×¢²áÔÚеÄSelectorÉϲ¢¹Ø±Õ¾ÉµÄSelector¡£

ÈÃÎÒÃÇÔÙ·µ»Ørun()·½·¨¿´¿´ºóÃæµÄÂß¼­¡£

ÔÚopenSelector()·½·¨ÖÐÎÒÃǵÃÖª£¬Èç¹ûDISABLE_KEYSET_OPTIMIZTIONΪfalseʱ£¬Í¨¹ý·´Éä»ñµÃ¶à·¸´ÓÃÆ÷selector£¬ºÍselectedKeys£¬ËùÒÔrun·½·¨½ÓÏÂÀ´»áµ÷processSelectedKeysPlain()·½·¨

if (this.selectedKeys != null) {
this.processSelectedKeysOptimized (this.selectedKeys.flip());
} else {
this.processSelectedKeysPlain (this.selector.selectedKeys());
}

Ñ­»·selectedKeys£¬»ñÈ¡sekectionKeyºÍËüµÄ¸½¼þÐÅÏ¢k.attachment()£¬

Èç¹ûËüÊÇÒ»¸öAbstractnioChannelµÄʵÀý£¬ËµÃ÷ËüÊÇÒ»¸öNioServerSocketChannel»òNioSocketChannel£¬ÐèÒª½øÐÐI/O²Ù×÷£¬·ñÔòËüÊǸö¶¨Ê±ÈÎÎñ¡£

I/O²Ù×÷ʱµÄÔ´ÂëÈçÏ£º

NioUnsafeÀàÊÇÖ÷Òª¶ÔByteBuf½øÐжÁдµÄÀ࣬Ê×ÏÈÅжÏreadyOps×ֶΣ¬Èç¹ûÊǶÁÇëÇó£¬Ôòµ÷ÓÃunsafe.read()·½·¨£¬Ð´ÇëÇóµ÷ÓÃunsafe.forceFlush()·½·¨£¬Á¬½ÓÇëÇóµ÷ÓÃunsafe.finishConnect()·½·¨¡£

JDK epoll bug

¹Ù·½Á¬½Ó

https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6670302

¹Ù·½¸ø³öµÄ²âÊÔ´úÂëÈçÏ£º

ÖØµãÔÚwhile(true)Ñ­»·Àï±ß£¬Ò²¾ÍÊÇ˵

int numKeys = selector.select();

ÕâÐдúÂëÈç¹ûûÓÐÂÖѯµ½×¼±¸¾ÍÐ÷µÄChannel£¬±¾¸Ã×èÈû£¬µ«JDK epoll²¢Ã»ÓÐ×èÈû·µ»ØÒ»¸ö¿ÕµÄ¼¯ºÏ£¬µ¼ÖÂwhileÏÝÈëËÀÑ­»·ÖС£ºÜ¶à·þÎñÆ÷Ó¦Ó㬱ÈÈçÉÏÎĵÄNetty£¬JettyµÈ¶ÔÆä×÷ÁËÐÞ¸´£¬rebuildSelector¡£

 
   
7373 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

Java΢·þÎñÐÂÉú´úÖ®Nacos
ÉîÈëÀí½âJavaÖеÄÈÝÆ÷
JavaÈÝÆ÷Ïê½â
Java´úÂëÖÊÁ¿¼ì²é¹¤¾ß¼°Ê¹Óð¸Àý
Ïà¹ØÎĵµ

JavaÐÔÄÜÓÅ»¯
Spring¿ò¼Ü
SSM¿ò¼Ü¼òµ¥¼òÉÜ
´ÓÁ㿪ʼѧjava±à³Ì¾­µä
Ïà¹Ø¿Î³Ì

¸ßÐÔÄÜJava±à³ÌÓëϵͳÐÔÄÜÓÅ»¯
JavaEE¼Ü¹¹¡¢ Éè¼ÆÄ£Ê½¼°ÐÔÄܵ÷ÓÅ
Java±à³Ì»ù´¡µ½Ó¦Óÿª·¢
JAVAÐéÄâ»úÔ­ÀíÆÊÎö