RPC概念

RPC不是一门技术,而是框架思想(就如MVC一样),简单可总结为远程方法调用,在不同的内存堆中,实现方法的调用,就如在本地调用一样。 一般使用代理模式将需要使用的方法封装暴露出来。 阿里的Dubbo对RPC做了很好的封装,功能非常强大。

RPC一般用在集群部署上,不同的机器间进行访问,如今微服务较为热门,我们将一个需要进行高消耗的计算模块,独立部署并部署多个节点,此时使用RPC跨内存调用、负载均衡、服务注册等。

实现RPC可使用Socket协议、http协议、甚至webservice的sop协议。socket是jdk自带的协议,本身进行了很好的封装,调用起来比较方便,但只能用在java平台,其它平台如需使用则需要适配器包装。 Dubbo是使用socket实现,并封装了对注册、负载均衡等处理。

以下依次了解各个相关知识点。

构造ServerSocket (创建服务端)

java.net.* 包中有ServerSocket 类,此类有4个构造方法。用来创建socket服务,指定socket服务端口、和连接配置。

ServerSocket()

ServerSocket(int port)

ServerSocket(int port, int backlog)
 
ServerSocket(int port, int backlog, InetAddress bindAddr)

参数port指定服务器需要绑定的端口(监听端口),参数backlog指定客户连接请求队列的长度,参数bindAddr指定服务器需要绑定的IP地址。

参数port设为0时,由系统自动分配端口。

当队列中的连接请求达到了队列的最大容量时,服务器进程所在的主机会拒绝新的连接请求。当服务器通过ServerSocket.accept()方法从队列取出连接请求时,队列腾出空位,新的连接请求加入队列。

对于客户机进程,如果他发出的连接请求被加入到服务器队列,则说明连接成功,客户机Socket正常返回,否则抛出ConnectionException异常。

//socket在java.net 包下
import java.net.ServerSocket;
import java.net.Socket;



//建立服务、并打开监听,此处指定了端口
ServerSocket listener = new ServerSocket(9090);

//令该线程一直运行,只在测试时使用,实际开发中可将该server到注册中心管理
while (true) {
     //这个监控锁死了该线程,等待客户端访问
     Socket socket = listener.accept();

     //客户端传过来的是序列化的对象
     ObjectInputStream ois= new ObjectInputStream(socket.getInputStream());
     Object object = ois.readObject();
     
     //object为约定的对象,客户端和服务端使用的是相同的对象
     //进行逻辑处理后可向客户端返回一个序列化的对象

     ObjectOutputStream oos= new ObjectOutputStream(socket.getOutputStream());
     oos.writeObject(result);
}

相对于http、webservice 而言, socket的代码简洁明了。 传递也是对象。

构建客户端(使用socket访问服务端)

//指定访问的socket的地址及端口
String address = "127.0.0.1";
String PORT = "9090";
Socket socket = new Socket(address, PORT);

RequestObjectVo roVo = new RequestObjectVo();  //这个对象是与服务端约定的对象,一般是实体类

//把对象通过socket发给服务端
ObjectOutputStream oos= new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(roVo );

//线程等待,直到得到了返回对象
ObjectInputStream ois= new ObjectInputStream(socket.getInputStream());
Object object= ois.readObject();

同样,客户端的代码也比较简洁,jdk对socket连接、发送、接收过程进行了完整的封装。

使用的时候只需要new一个Socket对象,指定地址即可

 

更深层次的内容

一个简单的基于socket协议RPC就如上,开发中可以这样来做内部两个系统之间的交互。替代内部还需要使用http、webservice笨重的开发方式。

但真正能施展RPC才华的,更多的是用在多服务负载、微服务拆分部署的应用上。这时候就是要考虑服务注册、负载、服务端停机等问题。