第2部分:Netty核心架构与原理解析

第2部分:Netty核心架构与原理解析

2.1 Reactor模型演进

单Reactor单线程模型

复制代码
┌─────────────────┐
│   Reactor       │
│   (Selector)    │
└─────────┬───────┘
          │
    ┌─────▼─────┐
    │  Acceptor │
    └─────┬─────┘
          │
    ┌─────▼─────┐
    │  Handler  │
    │ (业务处理) │
    └───────────┘

特点:

  • 所有I/O操作和业务处理都在一个线程中
  • 简单但性能有限
  • 适合连接数少、业务处理快的场景

代码示例:

java 复制代码
public class SingleReactorServer {
    private Selector selector;
    private ServerSocketChannel serverChannel;
    
    public void start() throws IOException {
        selector = Selector.open();
        serverChannel = ServerSocketChannel.open();
        serverChannel.configureBlocking(false);
        serverChannel.socket().bind(new InetSocketAddress(8080));
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);
        
        while (true) {
            selector.select();
            Set<SelectionKey> keys = selector.selectedKeys();
            Iterator<SelectionKey> it = keys.iterator();
            
            while (it.hasNext()) {
                SelectionKey key = it.next();
                it.remove();
                
                if (key.isAcceptable()) {
                    handleAccept(key);
                } else if (key.isReadable()) {
                    handleRead(key);
                }
            }
        }
    }
}

单Reactor多线程模型

复制代码
┌─────────────────┐
│   Reactor       │
│   (Selector)    │
└─────────┬───────┘
          │
    ┌─────▼─────┐
    │  Acceptor │
    └─────┬─────┘
          │
    ┌─────▼─────┐
    │  Handler  │
    │ (I/O处理) │
    └─────┬─────┘
          │
    ┌─────▼─────┐
    │ 线程池     │
    │ (业务处理) │
    └───────────┘

特点:

  • I/O操作在Reactor线程中
  • 业务处理在线程池中
  • 提高了并发处理能力

多Reactor多线程模型(Netty采用)

复制代码
┌─────────────────┐
│  Main Reactor   │
│  (Boss Group)   │
└─────────┬───────┘
          │
    ┌─────▼─────┐
    │  Acceptor │
    └─────┬─────┘
          │
    ┌─────▼─────┐
    │Sub Reactor│
    │(Worker Grp)│
    └─────┬─────┘
          │
    ┌─────▼─────┐
    │  Handler  │
    │ (业务处理) │
    └───────────┘

特点:

  • 主Reactor负责连接建立
  • 子Reactor负责I/O读写
  • 每个Reactor运行在独立线程中
  • 充分利用多核CPU

2.2 EventLoop与Selector的内部实现机制

EventLoop的核心实现

java 复制代码
public final class NioEventLoop extends SingleThreadEventLoop {
    private Selector selector;
    private Selector unwrappedSelector;
    private SelectedSelectionKeySet selectedKeys;
    
    @Override
    protected void run() {
        for (;;) {
            try {
                switch (selectStrategy.calculateStrategy(selectNowSupplier, hasTasks())) {
                    case SelectStrategy.CONTINUE:
                        continue;
                    case SelectStrategy.SELECT:
                        select(wakenUp.getAndSet(false));
                        if (wakenUp.get()) {
                            selector.wakeup();
                        }
                    default:
                }
                
                cancelledKeys = 0;
                needsToSelectAgain = false;
                final int ioRatio = this.ioRatio;
                if (ioRatio == 100) {
                    try {
                        processSelectedKeys();
                    } finally {
                        runAllTasks();
                    }
                } else {
                    final long ioStartTime = System.nanoTime();
                    try {
                        processSelectedKeys();
                    } finally {
                        final long ioTime = System.nanoTime() - ioStartTime;
                        runAllTasks(ioTime * (100 - ioRatio) / ioRatio);
                    }
                }
            } catch (Throwable t) {
                handleLoopException(t);
            }
        }
    }
}

Selector优化策略

1. SelectedSelectionKeySet优化
java 复制代码
// 使用数组替代HashSet,提高性能
final class SelectedSelectionKeySet extends AbstractSet<SelectionKey> {
    private SelectionKey[] keys;
    private int size;
    
    @Override
    public boolean add(SelectionKey o) {
        if (o == null) {
            return false;
        }
        keys[size++] = o;
        if (size == keys.length) {
            doubleCapacity();
        }
        return true;
    }
}
2. 空轮询检测
java 复制代码
// 检测空轮询,避免CPU 100%
private void select(boolean oldWakenUp) throws IOException {
    Selector selector = this.selector;
    try {
        int selectCnt = 0;
        long currentTimeNanos = System.nanoTime();
        long selectDeadLineNanos = currentTimeNanos + delayNanos(currentTimeNanos);
        
        for (;;) {
            long timeoutMillis = (selectDeadLineNanos - currentTimeNanos + 500000L) / 1000000L;
            if (timeoutMillis <= 0) {
                if (selectCnt == 0) {
                    selector.selectNow();
                    selectCnt = 1;
                }
                break;
            }
            
            int selectedKeys = selector.select(timeoutMillis);
            selectCnt++;
            
            if (selectedKeys != 0 || oldWakenUp || wakenUp.get() || hasTasks() || hasScheduledTasks()) {
                break;
            }
            
            // 检测空轮询
            if (SELECTOR_AUTO_REBUILD_THRESHOLD > 0 && selectCnt >= SELECTOR_AUTO_REBUILD_THRESHOLD) {
                rebuildSelector();
                selector = this.selector;
                selectCnt = 1;
                break;
            }
        }
    } catch (CancelledKeyException e) {
        // 处理取消的键
    }
}

2.3 Channel、Unsafe、Pipeline、Handler的关系

核心组件关系图

复制代码
┌─────────────────────────────────────────────────────────────┐
│                        Channel                              │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────────┐  │
│  │   Unsafe    │  │  Pipeline   │  │    AttributeMap     │  │
│  │             │  │             │  │                     │  │
│  │ - connect() │  │ - addLast() │  │ - attr()            │  │
│  │ - write()   │  │ - remove()  │  │ - hasAttr()         │  │
│  │ - flush()   │  │ - fireXXX() │  │                     │  │
│  └─────────────┘  └─────────────┘  └─────────────────────┘  │
└─────────────────────────────────────────────────────────────┘

Channel接口层次

java 复制代码
public interface Channel extends AttributeMap, ChannelOutboundInvoker, 
    Comparable<Channel> {
    
    // 基本属性
    ChannelId id();
    EventLoop eventLoop();
    Channel parent();
    ChannelConfig config();
    boolean isOpen();
    boolean isRegistered();
    boolean isActive();
    ChannelMetadata metadata();
    
    // 地址信息
    SocketAddress localAddress();
    SocketAddress remoteAddress();
    
    // 关闭操作
    ChannelFuture closeFuture();
    boolean isWritable();
    long bytesBeforeUnwritable();
    long bytesBeforeWritable();
    Unsafe unsafe();
    ChannelPipeline pipeline();
    ByteBufAllocator alloc();
    Channel read();
    Channel flush();
}

Unsafe接口

java 复制代码
interface Unsafe {
    // 注册相关
    RecvByteBufAllocator.Handle recvBufAllocHandle();
    void register(EventLoop eventLoop, ChannelPromise promise);
    void bind(SocketAddress localAddress, ChannelPromise promise);
    void disconnect(ChannelPromise promise);
    void close(ChannelPromise promise);
    void closeForcibly();
    void deregister(ChannelPromise promise);
    void beginRead();
    void write(Object msg, ChannelPromise promise);
    void flush();
    
    // 属性相关
    ChannelPromise voidPromise();
    ChannelOutboundBuffer outboundBuffer();
}

Pipeline机制

java 复制代码
public class DefaultChannelPipeline implements ChannelPipeline {
    final AbstractChannelHandlerContext head;
    final AbstractChannelHandlerContext tail;
    
    public final ChannelPipeline addLast(String name, ChannelHandler handler) {
        return addLast(null, name, handler);
    }
    
    public final ChannelPipeline addLast(EventExecutorGroup group, String name, 
                                       ChannelHandler handler) {
        final AbstractChannelHandlerContext newCtx;
        synchronized (this) {
            checkMultiplicity(handler);
            newCtx = newContext(group, filterName(name, handler), handler);
            addLast0(newCtx);
        }
        
        if (registered) {
            callHandlerAdded0(newCtx);
        }
        return this;
    }
    
    private void addLast0(AbstractChannelHandlerContext newCtx) {
        AbstractChannelHandlerContext prev = tail.prev;
        newCtx.prev = prev;
        newCtx.next = tail;
        prev.next = newCtx;
        tail.prev = newCtx;
    }
}

Handler执行流程

java 复制代码
// Inbound事件传播
public class DefaultChannelPipeline implements ChannelPipeline {
    public final ChannelPipeline fireChannelRead(Object msg) {
        AbstractChannelHandlerContext.invokeChannelRead(head, msg);
        return this;
    }
    
    static void invokeChannelRead(final AbstractChannelHandlerContext next, 
                                 Object msg) {
        final Object m = next.pipeline.touch(ObjectUtil.checkNotNull(msg, "msg"), next);
        EventExecutor executor = next.executor();
        if (executor.inEventLoop()) {
            next.invokeChannelRead(m);
        } else {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    next.invokeChannelRead(m);
                }
            });
        }
    }
}

2.4 ByteBuf内存管理与零拷贝机制

ByteBuf结构

复制代码
┌─────────────────┬─────────────────┬─────────────────┐
│   Discardable   │    Readable     │    Writable     │
│                 │                 │                 │
│ 0      readerIndex    writerIndex      capacity     │
└─────────────────┴─────────────────┴─────────────────┘

内存分配策略

1. PooledByteBufAllocator
java 复制代码
public class PooledByteBufAllocator extends AbstractByteBufAllocator {
    private final PoolArena<byte[]>[] heapArenas;
    private final PoolArena<ByteBuffer>[] directArenas;
    
    @Override
    protected ByteBuf newHeapBuffer(int initialCapacity, int maxCapacity) {
        PoolThreadCache cache = threadCache.get();
        PoolArena<byte[]> heapArena = cache.heapArena;
        
        ByteBuf buf;
        if (heapArena != null) {
            buf = heapArena.allocate(cache, initialCapacity, maxCapacity);
        } else {
            buf = new UnpooledHeapByteBuf(this, initialCapacity, maxCapacity);
        }
        
        return toLeakAwareBuffer(buf);
    }
}
2. 内存池结构
复制代码
┌─────────────────────────────────────────────────────────┐
│                  PoolArena                              │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────────┐  │
│  │   Tiny      │  │   Small     │  │     Normal      │  │
│  │  (0-512B)   │  │ (512B-8KB)  │  │    (8KB-16MB)   │  │
│  └─────────────┘  └─────────────┘  └─────────────────┘  │
│  ┌─────────────────────────────────────────────────────┐  │
│  │                Huge (>16MB)                        │  │
│  └─────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────┘

零拷贝实现

1. CompositeByteBuf
java 复制代码
// 组合多个ByteBuf,避免数据拷贝
public class CompositeByteBuf extends AbstractReferenceCountedByteBuf 
    implements Iterable<ByteBuf> {
    
    private Component[] components;
    private int componentCount;
    
    public CompositeByteBuf addComponent(ByteBuf buffer) {
        addComponent0(componentCount, buffer);
        consolidateIfNeeded();
        return this;
    }
    
    private void addComponent0(int cIndex, ByteBuf buffer) {
        Component c = newComponent(buffer, 0);
        if (cIndex == componentCount) {
            components[componentCount++] = c;
        } else {
            System.arraycopy(components, cIndex, components, cIndex + 1, 
                           componentCount - cIndex);
            components[cIndex] = c;
            componentCount++;
        }
    }
}
2. FileChannel.transferTo()
java 复制代码
// 使用操作系统的零拷贝功能
public class FileRegion implements FileRegion {
    @Override
    public long transferTo(WritableByteChannel target, long position) 
        throws IOException {
        long count = this.count - position;
        if (count < 0) {
            throw new IllegalArgumentException("position out of range");
        }
        if (count == 0) {
            return 0L;
        }
        if (count > this.count) {
            count = this.count;
        }
        
        return file.transferTo(this.position + position, count, target);
    }
}

2.5 Future & Promise:异步回调模型

Future接口层次

java 复制代码
public interface Future<V> extends java.util.concurrent.Future<V> {
    boolean isSuccess();
    boolean isCancellable();
    Throwable cause();
    Future<V> addListener(GenericFutureListener<? extends Future<? super V>> listener);
    Future<V> addListeners(GenericFutureListener<? extends Future<? super V>>... listeners);
    Future<V> removeListener(GenericFutureListener<? extends Future<? super V>> listener);
    Future<V> removeListeners(GenericFutureListener<? extends Future<? super V>>... listeners);
    Future<V> sync() throws InterruptedException;
    Future<V> syncUninterruptibly();
    Future<V> await() throws InterruptedException;
    Future<V> awaitUninterruptibly();
    boolean await(long timeout, TimeUnit unit) throws InterruptedException;
    boolean awaitUninterruptibly(long timeout, TimeUnit unit);
    V getNow();
    boolean cancel(boolean mayInterruptIfRunning);
}

Promise接口

java 复制代码
public interface Promise<V> extends Future<V> {
    Promise<V> setSuccess(V result);
    boolean trySuccess(V result);
    Promise<V> setFailure(Throwable cause);
    boolean tryFailure(Throwable cause);
    boolean setUncancellable();
    Promise<V> addListener(GenericFutureListener<? extends Future<? super V>> listener);
    Promise<V> addListeners(GenericFutureListener<? extends Future<? super V>>... listeners);
    Promise<V> removeListener(GenericFutureListener<? extends Future<? super V>> listener);
    Promise<V> removeListeners(GenericFutureListener<? extends Future<? super V>>... listeners);
    Promise<V> await() throws InterruptedException;
    Promise<V> awaitUninterruptibly();
    Promise<V> sync() throws InterruptedException;
    Promise<V> syncUninterruptibly();
}

异步操作示例

java 复制代码
public class AsyncOperationExample {
    public void demonstrateAsync() {
        Channel channel = ...;
        
        // 异步写入
        ChannelFuture writeFuture = channel.writeAndFlush("Hello World");
        
        // 添加监听器
        writeFuture.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) {
                if (future.isSuccess()) {
                    System.out.println("写入成功");
                } else {
                    System.err.println("写入失败: " + future.cause());
                }
            }
        });
        
        // 链式调用
        channel.writeAndFlush("Message")
               .addListener(ChannelFutureListener.CLOSE_ON_FAILURE)
               .addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
    }
}

2.6 高性能的关键设计点

1. 无锁化设计

  • 单线程处理I/O事件
  • 使用CAS操作避免锁竞争
  • 无锁队列传递任务

2. 内存管理优化

  • 对象池化减少GC压力
  • 直接内存使用减少拷贝
  • 内存对齐提高访问效率

3. 批量操作

java 复制代码
// 批量处理I/O事件
private void processSelectedKeys() {
    if (selectedKeys != null) {
        processSelectedKeysOptimized(selectedKeys.flip());
    } else {
        processSelectedKeysPlain(selector.selectedKeys());
    }
}

4. 事件驱动模型

  • 基于回调的异步处理
  • 避免线程阻塞
  • 提高并发处理能力

2.7 总结

Netty的核心架构通过Reactor模式、事件驱动、内存池化等技术,实现了高性能的网络通信框架。其设计充分考虑了并发性能、内存效率和代码可维护性,为上层应用提供了简洁而强大的API。

在下一部分中,我们将学习如何使用Netty进行基础的网络编程。

相关推荐
若尘拂风4 小时前
centos 7.9 编译安装 freeswitch 1.10.12
服务器·udp·freeswitch·sip
小蜜蜂爱编程4 小时前
gerrit的部署与配置关联到不同服务器上的git仓库
运维·服务器·git·gerrit
心灵宝贝5 小时前
申威(sw_64)架构下如何安装java-1.8.0-swjdk的rpm包?
linux·运维·服务器
好记忆不如烂笔头abc5 小时前
linux系统记录登录用户的所有操作
java·linux·服务器
王嘉祥5 小时前
Pangolin:基于零信任理念的反向代理
后端·架构
野犬寒鸦6 小时前
从零起步学习MySQL || 第五章:select语句的执行过程是怎么样的?(结合源码深度解析)
java·服务器·数据库·后端·mysql·adb
半梦半醒*6 小时前
搭建Jenkins
linux·运维·centos·tomcat·jenkins·运维开发
Wang's Blog6 小时前
Linux小课堂: 系统监控与进程管理之深入解析 w、ps 与 top 命令
linux·运维·服务器
安卓开发者7 小时前
Docker常用镜像使用指南:从入门到实战
运维·docker·容器