Hadoop3.2.1 【 HDFS 】源码分析 : RPC原理 [六] ProtobufRpcEngine 使用

ProtobufRpcEngine 目前是作为Hadoop RPC 引擎唯一的实现方式.

WritableRpcEngine 在3.2.1版本已经标识为废弃,但依旧是默认实现的RPC引擎.

接下来,我们说一下如何使用, 过程比WritableRpcEngine 的使用要麻烦很多.

主要是在接口的定义和实现的写法上有区别.

1. 定义协议

1.1.定义proto协议

根据Protocol的语法, 定义一个服务MetaInfo, 通过该服务的getMetaInfo接口,可以获取到元数据的信息.

/**
 * 生成java代码指令
 * protoc --java_out=. CustomProtocol.proto
 *
 */

option java_package = "org.apache.hadoop.rpc.protobuf";
option java_outer_classname = "CustomProtos";
option java_generic_services = true;
option java_generate_equals_and_hash = true;

package hadoop.common;

service MetaInfo {
  rpc getMetaInfo(GetMetaInfoRequestProto) returns (GetMetaInfoResponseProto);
}

message GetMetaInfoRequestProto {
  required string path = 1;
}

message GetMetaInfoResponseProto {
  required string info = 1;
}

1.2.根据定义好的proto协议生成java类,导入项目.

将定义好的协议保存成文件,命名为CustomProtocol.proto. 在该文件的目录下,执行命令

MacBook-Pro:proto sysadmin$ ls -l
total 8
-rw-r--r--@ 1 sysadmin  staff  526  4 20 09:56 CustomProtocol.proto
MacBook-Pro:proto sysadmin$
MacBook-Pro:proto sysadmin$
MacBook-Pro:proto sysadmin$ protoc --java_out=. CustomProtocol.proto
MacBook-Pro:proto sysadmin$
MacBook-Pro:proto sysadmin$
MacBook-Pro:proto sysadmin$ ls -l
total 8
-rw-r--r--@ 1 sysadmin  staff  526  4 20 09:56 CustomProtocol.proto
drwxr-xr-x  3 sysadmin  staff   96  4 20 11:53 org
MacBook-Pro:proto sysadmin$
MacBook-Pro:proto sysadmin$
MacBook-Pro:proto sysadmin$
MacBook-Pro:proto sysadmin$ cd org/apache/hadoop/rpc/protobuf
MacBook-Pro:protobuf sysadmin$
MacBook-Pro:protobuf sysadmin$ ls -l
total 104
-rw-r--r--  1 sysadmin  staff  49880  4 20 11:53 CustomProtos.java
MacBook-Pro:protobuf sysadmin$
MacBook-Pro:protobuf sysadmin$

这是在该目录下, 会有一个文件目录生成, 层级为我们定义好的org.apache.hadoop.rpc.protobuf 路径.

将里面生成的java文件CustomProtos.java导入到项目中, 存放路径与定义好的路径一样.

2.根据定义好的proto协议定义接口

创建一个接口,集成生成JAVA类中的CustomProtos.MetaInfo.BlockingInterface接口.

    // 接口信息 供server 和client 端使用
    @ProtocolInfo(
            protocolName = "org.apache.hadoop.rpc.CustomProtos$MetaInfoProtocol",
            protocolVersion = 1)
    public interface MetaInfoProtocol
            extends CustomProtos.MetaInfo.BlockingInterface {
    }

3.实现接口协议

创建一个类,实现刚刚定义好的MetaInfoProtocol 接口, 并且实现里面的方法. 这个需要自己去写代码逻辑.

注意返回值和返回对象的写法不太一样.

 // 实现类
    public static class MetaInfoServer implements MetaInfoProtocol {

        @Override
        public CustomProtos.GetMetaInfoResponseProto getMetaInfo(RpcController controller,
                CustomProtos.GetMetaInfoRequestProto request) throws
                ServiceException {

            //获取请求参数
            final String path = request.getPath();

            return CustomProtos.GetMetaInfoResponseProto.newBuilder().setInfo(path + ":3 - {BLOCK_1,BLOCK_2,BLOCK_3....").build();
        }
    }

4.创建Server服务, 并注册协议.启动RPC服务.

     public static void main(String[] args) throws  Exception{


        //1. 构建配置对象
        Configuration conf = new Configuration();

        //2. 协议对象的实例
        MetaInfoServer serverImpl =  new MetaInfoServer();
        BlockingService blockingService =
                CustomProtos.MetaInfo.newReflectiveBlockingService(serverImpl);

        //3. 设置协议的RpcEngine为ProtobufRpcEngine .
        RPC.setProtocolEngine(conf, MetaInfoProtocol.class,
                ProtobufRpcEngine.class);
        
        //4. 构建RPC框架
        RPC.Builder builder = new RPC.Builder(conf);
        //5. 绑定地址
        builder.setBindAddress("localhost");
        //6. 绑定端口
        builder.setPort(7777);
        //7. 绑定协议
        builder.setProtocol(MetaInfoProtocol.class);
        //8. 调用协议实现类
        builder.setInstance(blockingService);
        //9. 创建服务
        RPC.Server server = builder.build();
        //10. 启动服务
        server.start();
        
    }

5.创建Client服务,请求数据接口

    public static void main(String[] args) throws Exception {

        //1. 构建配置对象
        Configuration conf = new Configuration();

        //2. 设置协议的RpcEngine为ProtobufRpcEngine .
        RPC.setProtocolEngine(conf, Server.MetaInfoProtocol.class,
                ProtobufRpcEngine.class);


        //3. 拿到RPC协议
        Server.MetaInfoProtocol proxy = RPC.getProxy(Server.MetaInfoProtocol.class, 1L,
                new InetSocketAddress("localhost", 7777), conf);

        //4. 发送请求
        CustomProtos.GetMetaInfoRequestProto obj =  CustomProtos.GetMetaInfoRequestProto.newBuilder().setPath("/meta").build();

        CustomProtos.GetMetaInfoResponseProto metaData = proxy.getMetaInfo(null, obj);

        //5. 打印元数据
        System.out.println(metaData.getInfo());

    }

6.测试结果

发布了336 篇原创文章 · 获赞 846 · 访问量 41万+

猜你喜欢

转载自blog.csdn.net/zhanglong_4444/article/details/105630023
今日推荐