一、基础概念
概念:
RPC(Remote Procedure Call)–远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
它允许一台计算机程序远程调用另外一台计算机的子程序,而不用去关心底层的网络通信细节,对我们来说是透明的。因此,它经常用于分布式网络通信中。
Hadoop的进程间交互都是通过RPC来进行的,比如Namenode与Datanode之间,Jobtracker与Tasktracker之间等。可以说,Hadoop的运行就是建立在RPC基础之上的。
特点:
(1)透明性:远程调用其他机器上的程序,对用户来说就像是调用本地方法一样;
(2)高性能:RPC Server能够并发处理多个来自Client的请求;
(3)可控性:jdk中已经提供了一个RPC框架—RMI,但是该RPC框架过于重量级并且可控之处比较少,所以Hadoop RPC实现了自定义的RPC框架。
基本流程
(1)RPC采用了C/S的模式;
(2)Client端发送一个带有参数的请求信息到Server;
(3)Server接收到这个请求以后,根据发送过来的参数调用相应的程序,然后把自己计算好的结果发送给Client端;
(4)Client端接收到结果后继续运行;
二、程序实现
程序清单:
- UserService.java(接口)
- UserServiceImpl.java
- Server.java --客户端程序
- Client.java --服务端程序
1.UserService.java
public interface UserService {
public static final long versionID=8888;
public void addUser(String name,int age);
}
2.UserServiceImpl.java
public class UserServiceImpl implements UserService{
@Override
public void addUser(String name, int age) {
System.out.println("姓名:"+name+" "+"年龄"+age);
}
}
3.Server.java
public class Server {
public static void main(String[] args) throws HadoopIllegalArgumentException, IOException {
Configuration config = new Configuration();
RPC.Builder builder = new RPC.Builder(config);
RPC.Server server = builder.setProtocol(UserService.class)
.setInstance(new UserServiceImpl())
.setBindAddress("localhost")
.setPort(9999)
.build();
//启动服务
server.start();
}
}
4.Client.java
import java.io.IOException;
import java.net.InetSocketAddress;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;
public class Client {
public static void main(String[] args) throws IOException {
Configuration config = new Configuration();
long clientVersion = 8888;
UserService proxy = RPC.getProxy(UserService.class, clientVersion, new InetSocketAddress("localhost", 9998), config);
proxy.addUser("zhangsan", 22);
System.out.println("添加成功");
}
}
三、运行
首先运行Server程序,然后运行Client
我为了方便截图,把这两个程序放入线程中执行了
结果:
附录
这里我把刚才做的多线程程序实验也贴过来
import java.io.IOException;
import java.net.InetSocketAddress;
import org.apache.hadoop.HadoopIllegalArgumentException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;
import com.css.test.rpc.UserService;
import com.css.test.rpc.UserServiceImpl;
class ThreadDemo extends Thread {
private Thread t;
private String threadName;
ThreadDemo( String name) {
threadName = name;
System.out.println("Creating " + threadName );
}
public void run() {
Configuration config = new Configuration();
RPC.Builder builder = new RPC.Builder(config);
RPC.Server server;
try {
server = builder.setProtocol(UserService.class)
.setInstance(new UserServiceImpl())
.setBindAddress("localhost")
.setPort(9998)
.build();
server.start();
} catch (HadoopIllegalArgumentException | IOException e) {
e.printStackTrace();
}
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
}
class ThreadDemo2 extends Thread {
private Thread t;
private String threadName;
ThreadDemo2(String name) {
threadName = name;
System.out.println("Creating " + threadName );
}
public void run() {
Configuration config = new Configuration();
long clientVersion = 8888;
UserService proxy;
try {
proxy = RPC.getProxy(UserService.class, clientVersion, new InetSocketAddress("localhost", 9998), config);
proxy.addUser("zhangsan", 22);
System.out.println("添加成功");
} catch (IOException e) {
e.printStackTrace();
}
}
public void start () {
System.out.println("Starting " + threadName );
if (t == null) {
t = new Thread (this, threadName);
t.start ();
}
}
}
public class TestThread {
public static void main(String args[]) throws InterruptedException {
// 运行服务端程序
ThreadDemo T1 = new ThreadDemo( "Thread-1");
T1.start();
// 运行客户端程序
ThreadDemo2 T2 = new ThreadDemo2( "Thread-2");
T2.start();
}
}