Skip to content

网络通信 ​

深入理解Dubbo网络通信的实现,掌握Netty集成、连接管理、线程模型等核心机制,理解消息传输、心跳机制、连接复用的实现原理。

📋 网络通信概览 ​

Dubbo使用Netty作为网络通信框架,实现了高性能的异步非阻塞网络通信。

🎯 一、Netty集成 ​

1.1 NettyServer ​

NettyServer是Dubbo的服务端实现:

java
public class NettyServer extends AbstractServer implements Server {
    
    private ServerBootstrap bootstrap;
    private EventLoopGroup bossGroup;
    private EventLoopGroup workerGroup;
    
    @Override
    protected void doOpen() throws Throwable {
        bootstrap = new ServerBootstrap();
        bossGroup = NettyEventLoopFactory.eventLoopGroup(1, "NettyServerBoss");
        workerGroup = NettyEventLoopFactory.eventLoopGroup(
                getUrl().getPositiveParameter(IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS),
                "NettyServerWorker");
        
        final NettyServerHandler nettyServerHandler = new NettyServerHandler(
                getUrl(), this);
        channels = nettyServerHandler.getChannels();
        
        bootstrap.group(bossGroup, workerGroup)
                .channel(NettyEventLoopFactory.serverSocketChannelClass())
                .option(ChannelOption.SO_REUSEADDR, Boolean.TRUE)
                .childOption(ChannelOption.TCP_NODELAY, Boolean.TRUE)
                .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        NettyCodecAdapter adapter = new NettyCodecAdapter(
                                getCodec(), getUrl(), NettyServer.this);
                        ch.pipeline()
                                .addLast("decoder", adapter.getDecoder())
                                .addLast("encoder", adapter.getEncoder())
                                .addLast("server-idle-handler", new IdleStateHandler(
                                        0, 0, AbstractConfig.getServerIdleTimeout(),
                                        TimeUnit.MILLISECONDS))
                                .addLast("handler", nettyServerHandler);
                    }
                });
        
        ChannelFuture channelFuture = bootstrap.bind(getBindAddress());
        channelFuture.syncUninterruptibly();
        channel = channelFuture.channel();
    }
}

1.2 NettyClient ​

NettyClient是Dubbo的客户端实现:

java
public class NettyClient extends AbstractClient {
    
    private static final EventLoopGroup eventLoopGroup = 
            NettyEventLoopFactory.eventLoopGroup(
                    Constants.DEFAULT_IO_THREADS, "NettyClientWorker");
    
    private Bootstrap bootstrap;
    
    @Override
    protected void doOpen() throws Throwable {
        final NettyClientHandler nettyClientHandler = new NettyClientHandler(
                getUrl(), this);
        bootstrap = new Bootstrap();
        bootstrap.group(eventLoopGroup)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .option(ChannelOption.TCP_NODELAY, true)
                .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
                .channel(NettyEventLoopFactory.socketChannelClass())
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        NettyCodecAdapter adapter = new NettyCodecAdapter(
                                getCodec(), getUrl(), NettyClient.this);
                        ch.pipeline().addLast("decoder", adapter.getDecoder())
                                .addLast("encoder", adapter.getEncoder())
                                .addLast("client-idle-handler", new IdleStateHandler(
                                        AbstractConfig.getClientIdleTimeout(),
                                        0, 0, TimeUnit.MILLISECONDS))
                                .addLast("handler", nettyClientHandler);
                    }
                });
    }
}

🎯 二、连接管理 ​

2.1 连接创建 ​

Dubbo使用连接池管理连接,支持连接复用:

AbstractClient.connect:

java
@Override
public void connect() throws RemotingException {
    connectLock.lock();
    try {
        if (isConnected()) {
            return;
        }
        initConnectStatusCheckCommand();
        doConnect();
        if (!isConnected()) {
            throw new RemotingException(this, "Failed connect to server ...");
        }
    } catch (RemotingException e) {
        throw e;
    } catch (Throwable e) {
        throw new RemotingException(this, "Failed connect to server ...", e);
    } finally {
        connectLock.unlock();
    }
}

2.2 连接复用 ​

Dubbo支持连接复用,多个请求共享同一个连接:

连接复用流程:

🎯 三、心跳机制 ​

3.1 心跳检测 ​

Dubbo通过心跳机制检测连接是否正常:

IdleStateHandler:

java
ch.pipeline().addLast("server-idle-handler", new IdleStateHandler(
        0, 0, AbstractConfig.getServerIdleTimeout(),
        TimeUnit.MILLISECONDS));

3.2 心跳处理 ​

HeartbeatHandler:

java
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) 
        throws Exception {
    if (evt instanceof IdleStateEvent) {
        IdleStateEvent e = (IdleStateEvent) evt;
        if (e.state() == IdleState.READER_IDLE) {
            ctx.close();
        } else if (e.state() == IdleState.WRITER_IDLE) {
            ctx.writeAndFlush(HEARTBEAT_EVENT);
        }
    } else {
        super.userEventTriggered(ctx, evt);
    }
}

📖 学习资源 ​

视频教程 ​

书籍推荐 ​

  • 《深度剖析Apache Dubbo核心技术内幕》 - 华仔
  • 《Netty实战》 - Norman Maurer

网站资源 ​

✅ 学习检查清单 ​

  • [ ] 已理解Netty集成方式
  • [ ] 已理解连接管理机制
  • [ ] 已理解连接复用原理
  • [ ] 已理解心跳机制
  • [ ] 已理解线程模型
  • [ ] 已绘制网络通信流程图
  • [ ] 已总结核心知识点

上一章节:序列化协议
下一章节:服务治理
返回目录:Dubbo源码深度解析