In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly introduces the relevant knowledge of NioEventLoop's run method case analysis, the content is detailed and easy to understand, the operation is simple and fast, and it has a certain reference value. I believe you will have something to gain after reading this NioEventLoop run method case analysis article. Let's take a look.
Netty event loop main logic
The main logic of Netty event loop is in the processSelectedKeys function in NioEventLoop.run.
The protected void run () {/ / main loop keeps reading IO events and task, because EventLoop is also juc's ScheduledExecutorService implementation for (;;) {try {switch (selectStrategy.calculateStrategy (selectNowSupplier, hasTasks () {case SelectStrategy.CONTINUE: continue Case SelectStrategy.SELECT: select (wakenUp.getAndSet (false)); if (wakenUp.get ()) {selector.wakeup () } / / fall through default:} cancelledKeys = 0; needsToSelectAgain = false; / / IO event as a percentage of total execution time * / final int ioRatio = this.ioRatio If (ioRatio = = 100) {try {processSelectedKeys ();} finally {/ / Ensure we always run tasks. RunAllTasks ();}} else {final long ioStartTime = System.nanoTime (); try {processSelectedKeys ();} finally {/ / Ensure we always run tasks. Final long ioTime = System.nanoTime ()-ioStartTime; runAllTasks (ioTime * (100-ioRatio) / ioRatio);} catch (Throwable t) {handleLoopException (t);} / / Always handle shutdown even if the loop processing threw an exception. Try {if (isShuttingDown ()) {closeAll (); if (confirmShutdown ()) {return;} catch (Throwable t) {handleLoopException (t);}
When the processSelectedKeys function executes, it determines whether to perform the optimized version, that is, to determine whether the SelectedSelectionKeySet is empty.
Whether optimization is enabled depends on whether the environment variable io.netty.noKeySetOptimization is set. False means to enable it by default.
Private static final boolean DISABLE_KEYSET_OPTIMIZATION = SystemPropertyUtil.getBoolean ("io.netty.noKeySetOptimization", false)
The principle is to set the selectKeys property in the selector bound by eventLoop to SelectedSelectionKeySet by reflection. The advantage is that there is no need to iterate through selector.selectedKeys ().
Initialize EventLoop
When the injection timing is to initialize the EventLoop
Private SelectorTuple openSelector () {12 / / injection logic 40 Object maybeException = AccessController.doPrivileged (new PrivilegedAction () {@ Override public Object run () {try {Field selectedKeysField = selectorImplClass.getDeclaredField ("selectedKeys"); Field publicSelectedKeysField = selectorImplClass.getDeclaredField ("publicSelectedKeys") Throwable cause = ReflectionUtil.trySetAccessible (selectedKeysField); if (cause! = null) {return cause;} cause = ReflectionUtil.trySetAccessible (publicSelectedKeysField); if (cause! = null) {return cause } selectedKeysField.set (unwrappedSelector, selectedKeySet); publicSelectedKeysField.set (unwrappedSelector, selectedKeySet); return null;} catch (NoSuchFieldException e) {return e;} catch (IllegalAccessException e) {return e }); .78} handle read events
The processing of read events is mainly in processSelectedKey, which deals with read, write and connection events respectively.
Private void processSelectedKeysOptimized () {for (int I = 0; I)
< selectedKeys.size; ++i) { final SelectionKey k = selectedKeys.keys[i]; // null out entry in the array to allow to have it GC'ed once the Channel close // See https://github.com/netty/netty/issues/2363 selectedKeys.keys[i] = null; final Object a = k.attachment(); if (a instanceof AbstractNioChannel) { //分别处理每个channel的事件 processSelectedKey(k, (AbstractNioChannel) a); } else { @SuppressWarnings("unchecked") NioTask task = (NioTask) a; processSelectedKey(k, task); } if (needsToSelectAgain) { // null out entries in the array to allow to have it GC'ed once the Channel close // See https://github.com/netty/netty/issues/2363 selectedKeys.reset(i + 1); selectAgain(); i = -1; } } } private void processSelectedKey(SelectionKey k, AbstractNioChannel ch) { final AbstractNioChannel.NioUnsafe unsafe = ch.unsafe(); if (!k.isValid()) { final EventLoop eventLoop; try { eventLoop = ch.eventLoop(); } catch (Throwable ignored) { // If the channel implementation throws an exception because there is no event loop, we ignore this // because we are only trying to determine if ch is registered to this event loop and thus has authority // to close ch. return; } // Only close ch if ch is still registered to this EventLoop. ch could have deregistered from the event loop // and thus the SelectionKey could be cancelled as part of the deregistration process, but the channel is // still healthy and should not be closed. // See https://github.com/netty/netty/issues/5125 if (eventLoop != this || eventLoop == null) { return; } // close the channel if the key is not valid anymore unsafe.close(unsafe.voidPromise()); return; } try { int readyOps = k.readyOps(); // We first need to call finishConnect() before try to trigger a read(...) or write(...) as otherwise // the NIO JDK channel implementation may throw a NotYetConnectedException. if ((readyOps & SelectionKey.OP_CONNECT) != 0) { // remove OP_CONNECT as otherwise Selector.select(..) will always return without blocking // See https://github.com/netty/netty/issues/924 int ops = k.interestOps(); ops &= ~SelectionKey.OP_CONNECT; k.interestOps(ops); //处理了连接事件 unsafe.finishConnect(); } // Process OP_WRITE first as we may be able to write some queued buffers and so free memory. if ((readyOps & SelectionKey.OP_WRITE) != 0) { // Call forceFlush which will also take care of clear the OP_WRITE once there is nothing left to write //将要写入的buffer flush掉 ch.unsafe().forceFlush(); } // Also check for readOps of 0 to workaround possible JDK bug which may otherwise lead // to a spin loop if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0 || readyOps == 0) { //回调 pipeline 上所有的 ChannelInboundHandler 的 fireChannelRead 和 channelReadComplete 函数 unsafe.read(); } } catch (CancelledKeyException ignored) { unsafe.close(unsafe.voidPromise()); } }注意 NioServerSocketChannel 和 NioSocketChannel 都是 同样的 处理逻辑, 不同的是 前者 只关注 OP_ACCEPT 和 OP_READ事件, 后者 关注 OP_READ、OP_WRITE、OP_CONNECT事件 当NioServerSocketChannel 发生 OP_ACCEPT事件时 会 触发 AbstractNioChannel.NioUnsafe.read ->NioSctpServerChannel.doReadMessages (List)-> ServerBootstrapAcceptor.channelRead
Register the received NioSocketChannel with childEventLoop.
This is the end of the article on "run method example Analysis of NioEventLoop". Thank you for reading! I believe you all have a certain understanding of the knowledge of "run method case Analysis of NioEventLoop". If you want to learn more, you are welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.