Hadoop中的RPC机制

1.  RPC——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。

2.  RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息的到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。

3.  hadoop的整个体系结构就是构建在RPC之上的(见org.apache.hadoop.ipc)。

下面来看一张RPC调用关系的图:

我们假设loginController和loginService分别在客户端和服务端,它们之间的调用需要通过socket通信实现。RPC机制就是利用了动态代理、反射以及socket通信。通过该机制,我们在客户端只需要写红色框内的两行代码,即可以实现我们需要的功能。即得到代理对象,然后调用该对象的login()方法。接下来,我们把过程详细化:

客户端和服务端需要实现相同的业务接口,整个流程如图所示。

我们写一个简单的Demo来演示一下:

之前的jar包和配置文件需要提前准备好。

客户端代码:

LoginService接口:

package cn.darrenchan.hadoop.rpc;

public interface LoginService {
    public static final long versionID = 1L;
    public String login(String username, String password);
}

LoginController代码:

package cn.darrenchan.hadoop.rpc;

import java.io.IOException;
import java.net.InetSocketAddress;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;

public class LoginController {
    public static void main(String[] args) throws IOException {
        // 这一行是在windows下运行才用到的
        System.setProperty("hadoop.home.dir", "E:\大数据教程Hadoop8天\hadoop-2.4.1");
        LoginService proxy = RPC
                .getProxy(LoginService.class, 1L, new InetSocketAddress(
                        "weekend110", 10000), new Configuration());
        String result = proxy.login("陈驰", "123456");
        System.out.println(result);
    }
}

服务端代码:

LoginService接口:

package cn.darrenchan.hadoop.rpc;

public interface LoginService {
    public static final long versionID = 1L;
    public String login(String username, String password);
}

LoginServiceImpl实现类:

package cn.darrenchan.hadoop.rpc;

public class LoginServiceImpl implements LoginService {

    @Override
    public String login(String username, String password) {
        return username + " logged in successfully";
    }
}

Starter启动类:

package cn.darrenchan.hadoop.rpc;

import java.io.IOException;

import org.apache.hadoop.HadoopIllegalArgumentException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;
import org.apache.hadoop.ipc.RPC.Builder;
import org.apache.hadoop.ipc.RPC.Server;

public class Starter {
    public static void main(String[] args) throws HadoopIllegalArgumentException, IOException {
        Builder builder = new RPC.Builder(new Configuration());
        //port is random
        builder.setBindAddress("weekend110").setPort(10000)
                .setProtocol(LoginService.class)
                .setInstance(new LoginServiceImpl());

        Server server = builder.build();

        server.start();

    }
}

运行先启动服务端,然后运行客户端去连接,最后的运行效果如图:

原文地址:https://www.cnblogs.com/DarrenChan/p/6430419.html