RPC&Netty|青训营笔记

105 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的的第6天

一、RPC

在实现分布式存储系统项目的过程中,为了实现Client、NameNode和DataNode三个模块之间的通信,需要使用RPC来进行远程调用。目前典型的RPC实现包括:Dubbo、Thrift、GRPC、Hetty等。

RPC(Remote Procedure Call Protocol)远程过程调用协议。一个通俗的描述是:客户端在不知道调用细节的情况下,调用存在于远程计算机上的某个对象,就像调用本地应用程序中的对象一样。

不过,为了实现不同模块之间的统一的网络请求方式(因为DataNode与Client之间传输文件时需要使用Java NIO),因此我们采用Netty作为网络通信框架。

二、Netty

Netty是一个高性能、异步事件驱动的NIO框架,基于Java NIO提供的API实现。它提供了对TCP、UDP和文件传输的支持,作为一个异步NIO框架,Netty的所有IO操作都是异步非阻塞的,通过Future-Listener机制,用户可以方便地主动获取或通过通知机制获得IO操作结果。

Netty的核心部件有如下4个:

1、Channels

Channel的定义如下:

An open connection to an entity such as a hardware device, a file, a network socket, or a program component that is capable of performing one or more distinct I/O operations, for example reading or writing.

Client端可以通过channel把数据发送给Server端,Server端也可以通过channel把处理结果返回给Client端。

2、Callbacks

Callback也就是回调函数,由于Netty是事件驱动的,Callback定义的就是触发了某一个事件后所需要做的操作。比如,channelActive表示的就是当channel被激活时需要执行的操作,示例代码如下:

public class ConnectHandler extend ChannelInboundHandlerAdapter {
    @Override
    public void channelActive(ChannelHandlerContext ctx)
        throws Exception {
        Systems.out.println(
            "Client " + ctx.channel().remoteAddress() + " connected");
    }
}

3、Futures

Future对象可以帮助我们异步获取操作的结果。比如我们执行了Server端的bind操作,我们就可以获得一个Future对象,在这个Future对象中我们可以进一步定义监听函数来帮助我们处理返回结果。

4、Events和Handlers

在Netty中,Events主要分为Inbound eventsOutbound events两种。Inbound可以理解为数据流入,Outbound可以理解为数据流出。

image.png

从上图可以看出,当我们连接到远程socket时,从socket流入channel的方向记为Inbound,从channel流向socket的方向记为Outbound。Channel Pipeline会根据事件的类型,使用不同的Handler对数据进行处理。

三、总结

我们使用Netty来实现分布式存储中的不同模块之间的RPC,目的是为了统一不同模块之间的通信实现。下一步,我们需要根据项目的要求进一步地设计不同模块间的通信(比如传输什么数据包),Client和Server端的具体处理逻辑,以及如何设计通用的NetClient和NetServer,使得不同的模块在NetClient和NetServer的基础上十分方便地实现不同的处理逻辑。