第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进行基础的网络编程。