RPC(Remote Procedure Call) - 远程过程调用,是一个计算机通信协议,它允许运行于一台计算机的程序调用另一台计算机的子程序,而无需额外地为这个交互作用编程。RPC主要应用在分布式系统架构中不同的系统之间的远程通信和相互调用。

举个例子:正常中午做饭我们需要把电饭锅插上电然后按开关开始煲饭,这相当于本地调用,而有时候我们正在外面,但我们想要到家的时候煲饭就已经完成,这时候就需要一个智能的电饭煲,我们可以通过远程打开煲饭开关,这就是远程调用。

RPC调用的流程:

  1. 客户端(client)以本地调用方式调用服务;

  2. client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;

  3. client stub找到服务地址,并将消息发送到服务端 ------ 序列化

  4. 服务端(server) 收到消息后进行解码  ------------- 反序列化

  5. server stub根据解码结果调用本地的服务

  6. 本地服务执行并将结果返回给server

  7. server stub将返回结果打包成消息并发送至client ------- 序列化

  8. client 接收到消息,并进行解码 ------  反序列化

  9. client 得到最终结果。

序列化/反序列化
只有二进制数据才能在网络中传输,序列化和反序列化的定义是:

将对象转换成二进制流的过程叫做序列化,

将二进制流转换成对象的过程叫做反序列化。

简单实例代码:

客户端:

package RPC.Client;

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

import java.io.IOException;
import java.net.InetSocketAddress;
import RPC.LoginProtocol;
/**
 * @author 江冷易水寒
 * @data 2019/7/31 10:29
 */
public class LoginClient {
    public static void main(String[] args) throws IOException {
       LoginProtocol proxt =  RPC.getProxy(LoginProtocol.class,1L,new InetSocketAddress("localhost",10000),new Configuration());
        String rs = proxt.login("迪丽热巴","迪丽,热吧?");
        System.out.println(rs);
    }

}

服务端:

package RPC.Server;
/**
 * @author 江冷易水寒
 * @data 2019/7/31 10:07
 */
public class LoginServiceImpl implements RPC.LoginProtocol{

    public String login(String username, String password) {
        return username + " logged in succeefully!";
    }
}
package RPC.Server;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;
import org.apache.hadoop.ipc.Server;
import java.io.IOException;
import RPC.LoginProtocol;
/**
 * @author 江冷易水寒
 * @data 2019/7/31 10:10
 */
public class Starter {
    public static void main(String[] args) throws IOException {
        //创建一个RPC的创建器
        RPC.Builder builder = new RPC.Builder(new Configuration());
        //设置客户端要访问的IP
        builder.setBindAddress("localhost");
        //设置客户端要访问的端口
        builder.setPort(10000);
        //设置客户端实现RPC时的协议类
        builder.setProtocol(LoginProtocol.class);
        //设置客户端要访问的实例
        builder.setInstance(new LoginServiceImpl());
        Server server = builder.build();
        System.out.println("服务器启动了....");
        //启动服务器端
        server.start();
    }
}

客户端与服务端协议

package RPC;

/**
 * @author 江冷易水寒
 * @data 2019/7/31 14:51
 */
public interface LoginProtocol {
        public static final long versionID=1L;
        public String login(String username,String password);
}

代码目录结构

运行结果:

Logo

开源、云原生的融合云平台

更多推荐