Netty入门 - Netty三大核心组件源码剖析

Netty入门 - Netty三大核心组件源码剖析

Netty 是一个高性能的异步事件驱动网络应用框架,具有很高的可扩展性和灵活性。本文将深入剖析 Netty 的三大核心组件:ChannelEventLoopChannelPipeline,通过源码分析,帮助大家更好地理解 Netty 的工作原理。

1. Channel

Channel 是 Netty 的核心抽象,代表一个打开的连接(如一个网络 socket)。

1.1 Channel 接口
public interface Channel extends AttributeMap, ChannelOutboundInvoker, Comparable<Channel> {
    EventLoop eventLoop();
    ChannelPipeline pipeline();
    ByteBufAllocator alloc();
    ChannelConfig config();
    boolean isOpen();
    boolean isRegistered();
    boolean isActive();
    ChannelMetadata metadata();
    SocketAddress localAddress();
    SocketAddress remoteAddress();
    ChannelFuture closeFuture();
    Unsafe unsafe();
    Channel parent();
}
1.2 NioSocketChannel 类

NioSocketChannelChannel 的一个实现,基于 Java NIO 实现。

public class NioSocketChannel extends AbstractNioByteChannel implements SocketChannel {
    private final SocketChannelConfig config;

    public NioSocketChannel() {
        this(SocketChannel.open());
    }

    public NioSocketChannel(SocketChannel socket) {
        super(null, socket);
        config = new DefaultSocketChannelConfig(this, socket.socket());
    }

    @Override
    public SocketChannelConfig config() {
        return config;
    }

    @Override
    protected SocketAddress localAddress0() {
        return javaChannel().socket().getLocalSocketAddress();
    }

    @Override
    protected SocketAddress remoteAddress0() {
        return javaChannel().socket().getRemoteSocketAddress();
    }

    @Override
    protected void doClose() throws Exception {
        javaChannel().close();
    }

    @Override
    protected int doReadBytes(ByteBuf byteBuf) throws Exception {
        return byteBuf.writeBytes(javaChannel(), byteBuf.writableBytes());
    }

    @Override
    protected int doWriteBytes(ByteBuf buf) throws Exception {
        return buf.readBytes(javaChannel(), buf.readableBytes());
    }
}

2. EventLoop

EventLoop 是 Netty 的事件循环,负责处理 Channel 的 I/O 操作和任务调度。

2.1 EventLoop 接口
public interface EventLoop extends OrderedEventExecutor, EventLoopGroup {
    @Override
    EventLoopGroup parent();
    @Override
    EventLoop next();
    @Override
    ChannelFuture register(Channel channel);
    ChannelFuture register(ChannelPromise promise);
    @Deprecated
    ChannelFuture register(Channel channel, ChannelPromise promise);
}
2.2 NioEventLoop 类

NioEventLoopEventLoop 的一个实现,基于 Java NIO 实现。

public final class NioEventLoop extends SingleThreadEventLoop {
    private final Selector selector;
    private final SelectorProvider provider;
    private final SelectStrategy selectStrategy;
    private final SelectedSelectionKeySet selectedKeys;

    public NioEventLoop(NioEventLoopGroup parent, Executor executor, SelectorProvider selectorProvider, SelectStrategy strategy, RejectedExecutionHandler rejectedExecutionHandler) {
        super(parent, executor, false, DEFAULT_MAX_PENDING_TASKS, rejectedExecutionHandler);
        provider = selectorProvider;
        selectStrategy = strategy;
        selector = openSelector();
        selectedKeys = new SelectedSelectionKeySet();
        Selector unwrappedSelector = selector;
        try {
            unwrappedSelector = Selector.open();
        } catch (IOException e) {
            throw new ChannelException("failed to open a new selector", e);
        }
    }

    @Override
    protected void run() {
        for (;;) {
            try {
                int strategy = selectStrategy.calculateStrategy(selectNowSupplier, hasTasks());
                switch (strategy) {
                    case SelectStrategy.CONTINUE:
                        continue;
                    case SelectStrategy.BUSY_WAIT:
                    case SelectStrategy.SELECT:
                        select(wakenUp.getAndSet(false));
                        if (wakenUp.get()) {
                            selector.wakeup();
                        }
                        break;
                }
                cancelledKeys = 0;
                needsToSelectAgain = false;
                final int ioRatio = this.ioRatio;
                if (ioRatio == 100) {
                    processSelectedKeys();
                    runAllTasks();
                } else {
                    final long ioStartTime = System.nanoTime();
                    processSelectedKeys();
                    final long ioTime = System.nanoTime() - ioStartTime;
                    runAllTasks(ioTime * (100 - ioRatio) / ioRatio);
                }
                if (isShutdown()) {
                    closeAll();
                    if (confirmShutdown()) {
                        return;
                    }
                }
            } catch (Throwable t) {
                handleLoopException(t);
            }
        }
    }
}

3. ChannelPipeline

ChannelPipeline 是 Netty 的责任链模式实现,包含多个 ChannelHandler 处理 I/O 事件。

3.1 ChannelPipeline 接口
public interface ChannelPipeline extends ChannelInboundInvoker, ChannelOutboundInvoker, Iterable<Map.Entry<String, ChannelHandler>> {
    ChannelPipeline addFirst(String name, ChannelHandler handler);
    ChannelPipeline addLast(String name, ChannelHandler handler);
    ChannelPipeline remove(ChannelHandler handler);
    ChannelPipeline remove(String name);
    ChannelHandler first();
    ChannelHandler last();
    ChannelHandlerContext context(ChannelHandler handler);
    ChannelHandlerContext context(String name);
    ChannelHandlerContext firstContext();
    ChannelHandlerContext lastContext();
}
3.2 DefaultChannelPipeline 类

DefaultChannelPipelineChannelPipeline 的一个实现,负责维护 ChannelHandler 链。

public class DefaultChannelPipeline implements ChannelPipeline {
    final AbstractChannelHandlerContext head;
    final AbstractChannelHandlerContext tail;

    protected DefaultChannelPipeline(Channel channel) {
        head = new HeadContext(this);
        tail = new TailContext(this);
        head.next = tail;
        tail.prev = head;
    }

    @Override
    public ChannelPipeline addFirst(String name, ChannelHandler handler) {
        final AbstractChannelHandlerContext newCtx;
        synchronized (this) {
            checkDuplicateName(name);
            newCtx = newContext(null, name, handler);
            addFirst0(newCtx);
        }
        return this;
    }

    private void addFirst0(AbstractChannelHandlerContext newCtx) {
        AbstractChannelHandlerContext nextCtx = head.next;
        newCtx.prev = head;
        newCtx.next = nextCtx;
        head.next = newCtx;
        nextCtx.prev = newCtx;
    }

    @Override
    public ChannelPipeline addLast(String name, ChannelHandler handler) {
        final AbstractChannelHandlerContext newCtx;
        synchronized (this) {
            checkDuplicateName(name);
            newCtx = newContext(null, name, handler);
            addLast0(newCtx);
        }
        return this;
    }

    private void addLast0(AbstractChannelHandlerContext newCtx) {
        AbstractChannelHandlerContext prev = tail.prev;
        newCtx.prev = prev;
        newCtx.next = tail;
        prev.next = newCtx;
        tail.prev = newCtx;
    }

    @Override
    public ChannelHandler first() {
        ChannelHandlerContext first = firstContext();
        return first == null ? null : first.handler();
    }

    @Override
    public ChannelHandler last() {
        ChannelHandlerContext last = lastContext();
        return last == null ? null : last.handler();
    }
    
    @Override
    public ChannelHandlerContext firstContext() {
        AbstractChannelHandlerContext first = head.next;
        return first == tail ? null : first;
    }

    @Override
    public ChannelHandlerContext lastContext() {
        AbstractChannelHandlerContext last = tail.prev;
        return last == head ? null : last;
    }

    @Override
    public ChannelHandlerContext context(ChannelHandler handler) {
        return context0(handler);
    }

    @Override
    public ChannelHandlerContext context(String name) {
        return context0(name);
    }

    private AbstractChannelHandlerContext context0(Object nameOrHandler) {
        AbstractChannelHandlerContext ctx = head.next;
        if (nameOrHandler instanceof String) {
            while (ctx != null) {
                if (ctx.name().equals(nameOrHandler)) {
                    return ctx;
                }
                ctx = ctx.next;
            }
        } else {
            while (ctx != null) {
                if (ctx.handler() == nameOrHandler) {
                    return ctx;
                }
                ctx = ctx.next;
            }
        }
        return null;
    }
}

总结

Netty 的三大核心组件 ChannelEventLoopChannelPipeline 共同构成了其高性能网络通信框架的基石:

  1. Channel 代表一个连接,封装了底层 I/O 操作。
  2. EventLoop 是事件循环,负责处理 I/O 操作和任务调度。
  3. ChannelPipeline 维护处理器链,处理 I/O 事件。

通过源码分析,我们可以深入理解 Netty 的内部实现,为开发高性能网络应用打下坚实基础。

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值