分布式的基础问题是远程服务是怎么通讯的。
java领域有很多可实现远程通讯的技术,例如:RMI、Hessian、SOAP、ESB和JMS等。
从网络通信的底层去看,通信要做的事情就是把流从一台计算机传输到另外一台计算机。使用传输协议和网络IO实现,传输协议比较知名的如TCP、UDP等。
TCP和UDP都是在基于socket的概念上为某类应用场景扩展出来的传输层协议。
网络IO主要由bio、nio、aio,所有的分布式都是基于这个原理实现的。
rpc全称是 remote procedure call
,既远程过程调用。借助RPC可以做到像本地调用一样调用远程服务,是一种进程间的通信方式。
RPC不是一个具体的技术,而是指整个网络调用的过程。
下面展示的是本地调用和远程调用的示例:
例如有A服务器部署了一个应用,B服务器也部署了一个应用,现在A服务器上的应用想要调用B服务器上的应用的方法,由于,两个应用不在同一个服务器,因此不在同一个内存空间,无法实现直接调用,需要通过网络来表达调用的语义和传达调用的数据。
一个完整的RPC架构包含四个完整的组件,分表是Client,Client Stub,Server和Server Stub。Stub可以理解为存根。
1、客户端以本地方式调用服务
2、客户端存根接收到调用之后,将方法参数组装成能进行网络传输的消息体,消息体序列化为二进制
3、客户端通过socket将消息发送到服务端
4、服务端存根接收到消息之后进行解码,将消息对象反序列化
5、服务端存根根据解码结果调用本地服务
6、服务处理
7、本地服务执行并将结果返回给服务端存根
8、服务端存根将返回结果打包成消息,将结果消息对象序列化
9、服务端通过socket将消息发送到客户端
10、客户端存根接收到消息并进行解码,将消息对象反序列化
11、客户端得到最终结果
RPC的额目标是只保留1、6、11,将其他的细节全部封装起来。
注意:不管是什么类型的数据,在输出过程中都要转换成二进制流,而接收方需要将二进制流恢复为对象。
Java中常见的RPC框架有Hessian、gRPC、Dubbo等,核心模块都是通讯和序列化
Java的RMI指的是 Remote Method Invocation
,一种实现远程过程调用(RPC)的API,能直接传输序列化后的Java对象。它的实现依赖于JVM,因此它能支撑一个JVM到另外一个JVM的调用。
1、客户端从远程服务器的注册表中查询并获取远程对象的引用。
2、桩对象与远程对象有相同的接口和方法列表,当客户端调用远程对象时候,实际上是由桩对象代理完成。
3、远程引用层将桩的本地引用转换为服务器上对象的远程引用,再将调用层传递给传输层,由传输层通过TCP协议发起调用。
4、在服务端,传输层监听入站链接,收到客户端的远程调用之后,将引用转发到上层的远程引用层;
服务端的远程引用层将客户端发送的远程引用转换为本地虚拟机的引用,再将请求传递给骨架;
骨架读取参数,将请求传递给服务器,由服务器进行实际的方法调用。
5、如果远程方法调用之后有返回值,服务器将结果沿着 "骨架->远程引用层->传输层" 向下传递。
6、客户端的传输层接收到返回值之后,又沿着 "传输层->远程引用层->桩" 向上传递,并最终将结果传递给客户端程序。
1、服务端提供根据ID查询用户的方法
2、客户端调用服务端方法,并返回用户对象
3、要求使用RMI进行远程通讯