Dubbo Remote 支持多种传输协议,其中之一就是基于 Netty 的远程通信。在 Dubbo Remote 中,基于 Netty 的远程通信是通过 NettyServer 和 NettyClient 两个实现类来完成的。

以下是 Dubbo Remote 中基于 Netty 的远程通信的工作原理:

  1. 服务提供方在启动时创建 NettyServer 对象,并绑定到指定的端口上。
  2. 服务提供方在 NettyServer 上注册服务处理器,用于处理客户端的请求。
  3. 服务消费方在调用服务时创建 NettyClient 对象,并向服务提供方发送 Netty 请求。
  4. 服务提供方接收到 Netty 请求后,由 NettyServer 将请求转发给服务处理器进行处理。
  5. 服务处理器处理完请求后,向 NettyServer 返回处理结果。
  6. NettyServer 将处理结果打包成 Netty 响应,并发送给 NettyClient。
  7. NettyClient 接收到 Netty 响应后,将响应结果返回给服务消费方。

服务端

以下是 Dubbo Remote 中 NettyServer 的部分源码,并添加了中文注释进行说明:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// NettyServer 是 Dubbo Remote 基于 Netty 的远程通信的服务器端实现类
public class NettyServer implements Server {

    // 服务器地址
    private URL url;

    // 服务处理器
    private ExchangeHandler handler;

    // Netty 服务器
    private ServerBootstrap bootstrap;

    // 构造方法,根据 URL 创建 NettyServer 对象
    public NettyServer(URL url, ExchangeHandler handler) {
        this.url = url;
        this.handler = handler;
    }

    // start 方法用于启动服务器,开始监听客户端连接
    @Override
    public void start() throws RemotingException {
        // 创建 Netty 服务器
        bootstrap = new ServerBootstrap();
        // 配置 Netty 服务器参数
        bootstrap.group(new NioEventLoopGroup(), new NioEventLoopGroup())
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        // 添加 Netty 编解码器和处理器
                        ch.pipeline().addLast(new NettyDecoder(), new NettyEncoder(), new NettyHandler(handler));
                    }
                })
                .option(ChannelOption.SO_BACKLOG, 1024)
                .childOption(ChannelOption.SO_KEEPALIVE, true);
        // 绑定服务器地址并启动 Netty 服务器
        ChannelFuture future = bootstrap.bind(url.getPort()).syncUninterruptibly();
        if (future.isSuccess()) {
            logger.info("Netty server started on port " + url.getPort());
        } else {
            throw new RemotingException(this, "Failed to start netty server on port " + url.getPort());
        }
    }

    // stop 方法用于停止服务器,关闭连接和释放资源
    @Override
    public void stop() {
        if (bootstrap != null) {
            bootstrap.shutdownGracefully();
        }
    }

    // isBound 方法用于判断服务器是否已绑定到地址
    @Override
    public boolean isBound() {
        return bootstrap != null && bootstrap.config().childGroup().isShutdown();
    }

    // getUrl 方法用于获取服务器的 URL 对象
    @Override
    public URL getUrl() {
        return url;
    }

    // getChannels 方法用于获取所有连接到服务器的通道
    @Override
    public List<Channel> getChannels() {
        return Collections.emptyList();
    }

    // addChannelHandler 方法用于添加通道处理器,处理客户端请求
    @Override
    public void addChannelHandler(ChannelHandler handler, String urlPattern) throws RemotingException {
        throw new UnsupportedOperationException();
    }

    // removeChannelHandler 方法用于移除通道处理器
    @Override
    public void removeChannelHandler(ChannelHandler handler, String urlPattern) throws RemotingException {
        throw new UnsupportedOperationException();
    }
}

以上是 NettyServer 的部分源码和中文注释,可以看出 NettyServer 实现了 Server 接口,并通过 Netty 的 ServerBootstrap 和 Channel 对象来实现基于 Netty 的远程通信。在 start 方法中,NettyServer 创建了 Netty 服务器,配置了 Netty 服务器参数,添加了 Netty 编解码器和处理器,并绑定了服务器地址并启动了 Netty 服务器。在 stop 方法中,NettyServer 停止了 Netty 服务器。

此外,Dubbo Remote 中还提供了 NettyClient 实现类,用于实现基于 Netty 的远程通信的客户端功能。NettyClient 的工作原理与 NettyServer 类似,主要是通过创建 Netty 请求、发送请求、接收响应和处理响应等步骤来完成远程通信。

总之,Dubbo Remote 支持基于 Netty 的远程通信,并通过 NettyServer 和 NettyClient 两个实现类来完成服务器端和客户端的功能,实现了高性能、可扩展、可靠和易用的远程通信框架。

客户端

以下是 Dubbo Remote 中 NettyClient 的部分源码,并添加了中文注释进行说明:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
// NettyClient 是 Dubbo Remote 基于 Netty 的远程通信的客户端实现类
public class NettyClient implements Client {

    // 服务器地址
    private URL url;

    // 服务处理器
    private ExchangeHandler handler;

    // Netty 客户端
    private Bootstrap bootstrap;

    // 构造方法,根据 URL 创建 NettyClient 对象
    public NettyClient(URL url, ExchangeHandler handler) {
        this.url = url;
        this.handler = handler;
    }

    // connect 方法用于连接服务器,创建 Netty 客户端
    @Override
    public void connect() throws RemotingException {
        // 创建 Netty 客户端
        bootstrap = new Bootstrap();
        // 配置 Netty 客户端参数
        bootstrap.group(new NioEventLoopGroup())
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        // 添加 Netty 编解码器和处理器
                        ch.pipeline().addLast(new NettyDecoder(), new NettyEncoder(), new NettyHandler(handler));
                    }
                })
                .option(ChannelOption.SO_KEEPALIVE, true);
        // 连接服务器
        ChannelFuture future = bootstrap.connect(url.getHost(), url.getPort()).syncUninterruptibly();
        if (future.isSuccess()) {
            logger.info("Netty client connected to server " + url.getAddress());
        } else {
            throw new RemotingException(this, "Failed to connect to netty server " + url.getAddress());
        }
    }

    // disconnect 方法用于断开连接,关闭 Netty 客户端
    @Override
    public void disconnect() {
        if (bootstrap != null) {
            bootstrap.config().group().shutdownGracefully();
        }
    }

    // isConnected 方法用于判断客户端是否已连接到服务器
    @Override
    public boolean isConnected() {
        return bootstrap != null && bootstrap.config().group().isActive();
    }

    // getUrl 方法用于获取客户端的 URL 对象
    @Override
    public URL getUrl() {
        return url;
    }

    // send 方法用于向服务器发送请求
    @Override
    public void send(Object message) throws RemotingException {
        if (bootstrap == null || !bootstrap.config().group().isActive()) {
            throw new RemotingException(this, "Netty client is not connected to server");
        }
        // 获取 Netty 通道并发送请求
        bootstrap.config().group().writeAndFlush(message);
    }

    // getChannels 方法用于获取所有连接到服务器的通道
    @Override
    public List<Channel> getChannels() {
        return Collections.emptyList();
    }

    // addChannelHandler 方法用于添加通道处理器,处理服务器响应
    @Override
    public void addChannelHandler(ChannelHandler handler, String urlPattern) throws RemotingException {
        throw new UnsupportedOperationException();
    }

    // removeChannelHandler 方法用于移除通道处理器
    @Override
    public void removeChannelHandler(ChannelHandler handler, String urlPattern) throws RemotingException {
        throw new UnsupportedOperationException();
    }
}

以上是 NettyClient 的部分源码和中文注释,可以看出 NettyClient 实现了 Client 接口,并通过 Netty 的 Bootstrap 和 Channel 对象来实现基于 Netty 的远程通信。在 connect 方法中,NettyClient 创建了 Netty 客户端,配置了 Netty 客户端参数,添加了 Netty 编解码器和处理器,并连接了服务器。在 disconnect 方法中,NettyClient 断开了连接并关闭了 Netty 客户端。在 send 方法中,NettyClient 获取了 Netty 通道并发送了请求。

需要注意的是,NettyClient 在创建 Netty 客户端时使用了 NioEventLoopGroup 线程模型,它是 Netty 中的一个重要组件,用于处理 I/O 操作和事件。NioEventLoopGroup 中包含了一组 NioEventLoop 线程,每个 NioEventLoop 线程负责处理一个或多个 Channel 的 I/O 操作和事件。在 NettyClient 中,NioEventLoopGroup 用于处理 Netty 客户端的连接、请求和响应等操作。

总之,Dubbo Remote 支持基于 Netty 的远程通信,并通过 NettyServer 和 NettyClient 两个实现类来完成服务器端和客户端的功能,实现了高性能、可扩展、可靠和易用的远程通信框架。