学完了Java接口后,本节学习RPC(remote procedure call)远程过程调用协议。就是——不同进程之间的方法调用
webservice是什么:HTML+xml
假设我们有一个OA项目,用Java语言写的,另外有一个项目,CRM项目,用.NET语言写的。
现在我要在两个系统之间整合起来:OA想要CRM项目的一些信息。【当然,可以连接到CRM的数据库,可是这样,太暴力了,容易干掉对方的数据库】
因此我是怎么做的?用webservice,即:我(CRM)向你暴露一个地址,你(OA)一访问可以得到一个xml,你通过这个xml可以得到一个方法,
CRM暴露了一个接口【wsdl地址】,我(OA)一访问可以生成一个xml,得到一个类。我生成类之后我可以调用CRM类里面的方法。【图左框调用图右框】
不同"类"直接的方法调用——调用OA方框里的方法,实际上是CRM框里的method()方法将被调用:OA传参数到CRM,CRM方法有返回值,就是OA方法的返回值
为什么OA方法能调用CRM方法?因为你OA里的类其实是CRM的一个借口。【得到代理对象就可以得到目标函数的方法了】
其实,我们在OA端得到了CRM端的代理对象
左边里有一个代理对象,代理对象里面定义了一个方法,而目标对象里面也定义了一个方法,
因此,我们一调用代理对象,其实是在目标类里面【右边】 调用了目标方法
RPC是一样的,【是不同进程】。
OA运行在一台机器上,CRM运行在一台机器上,这是两个不同的进程,可以通过网络进行通信了。就是RPC通信——不同进程之间的方法调用(一个进程的一个类,可以调用另外一个进程的类的方法)
现在要通过hadoop来实现“不同进程的方法调用” 因为hadoop对RPC提供了支持【因为有一些工具类】
客户端跟namenode通信,datanode跟namenode通信,都要用到RPC协议。所以,想要看懂源码,就一定要会RPC
我RPCServer里的方法将被调用,将在客户端被调用
服务端server的代码如下: 名称RPCServer.java
package cn.itcast.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.Server;
public class RPCServer implements Bizable{ //定义了一个接口叫Bizable
//RPC里面应该有一个方法,我的客户端【不同进程】可以调用我这里的方法,于是我写一个方法
public String sayHi(String name){
return "HI~ " + name;
}
public static void main(String[] args) throws Exception {
//我现在要使用Hadoop提供的工具类来完成RPC通信,【如果不用工具类,自己写底层很麻烦】
Configuration conf = new Configuration();
Server server= new RPC.Builder(conf).setProtocol(Bizable.class).setInstance(new RPCServer()).setBindAddress("192.168.8.100").setPort(9527).build(); //每个都set一下,暂时还没有完全看懂。待2刷
server.start();
}
}
那么,我客户端【左边】得到了服务端server的一个“代理对象”,那么,我客户端和服务端要同时实现一个接口,比如,我的RPC 接着implement Bizable,然后报错,我们点击“创建接口”
创建接口之后,我们得到了一个接口
在接口里面定义一个方法,定义的还是 Bizable.java
package cn.itcast.hadoop.rpc;
public interface Bizable {
public static final long versionID = 100000;
public String sayHi(String name);
}
几点说明:1.versionID=10010这个,好像是Hadoop2.0里面的东西,RPC里必须加上versionID 跟前面的version必须相同
2.在接口里的bizable,里面的函数不需要再写一遍,只需要写
public String sayHi(String name);
后面加分号即可。不需要大括号或什么
客户端client的代码如下:名称RPCClient.java
package cn.itcast.hadoop.rpc;
import java.io.IOException;
import java.net.InetSocketAddress;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;
public class RPCClient {
public static void main(String[] args) throws Exception {
//client的目的:得到server的代理对象,就可以调用目标对象的方法
Bizable proxy = RPC.getProxy(Bizable.class, 10010, new InetSocketAddress("192.168.8.100",9527), new Configuration());
String result = proxy.sayHi("tomcat");
System.out.println(result);
RPC.stopProxy(proxy);
//打印是在客户端打印的,但是,拼接字符串是在服务端【的方法】里拼接的
}
}
在这里插一句:有关源码的问题
正常情况下,我们写的东西是.java的程序,这个就是源码,编译器(compiler)把我们编译成.class的【二进制字节码文件】文件,然后解释器进行解释,翻译,才能运行。
因此,我们平常直接使用的类,是直接使用class,是看不到它的源码的,除非你关联源码
关联源码之后,可以按住Ctrl【或者鼠标点那个位置,然后按住F3】,然后点击那个class类,之后便可以打开这个类的源码,可以看到它的具体东西。
如何关联源码?Java自己的源码,在安装的C盘C:\Program Files\Java\jdk1.7.0_21 这里面的一个src解压文件,之后关联进去即可。
具体如何做,有一篇文章,讲述得比较详细:
http://wenku.baidu.com/link?url=boCg7Q8RxRGUBqNzayZjOVm3paDbVP0bZECNsuP8w3qdgqxzsZ_5tOyjxmVAr6G9BJjLrcdl8BrBJLGlS5tJvmf-HdS76SkLA0kBZIsQsHC
我们使用hadoop,还要关联hadoop的一些源码,否则,hadoop里的一些类,我们能用,但是看不了源码。
比如说,我的datanode和namenode他们俩之间要通信,他俩要定义一个接口,他们俩都是我hadoop项目组的类,定义的接口是我们俩都能使用这个接口
总结:不同进程之间的方法调用。