2021-06-20

Java进程之间通信有多少种方式?
由于内存管理的一些机制,导致两个进程间并不能直接的进行通信 (在独立的用户空间), 因此我们需要利用一些介质来完成两个进程之间的通信。以下是常用的进程间通信方式。


管道(Pipe):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信。(半双工:数据传输指数据可以在一个信号载体的两个方向上传输,但是不能同时传输。)

有名管道(named pipe): 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。命名管道在文件系统中有对应的文件名。命名管道通过命令 mkfifo 或系统调用 mkfifo 来创建。

信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生。

消息(Message)队列:消息队列是消息的链接表。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。

共享内存:使得多个进程可以访问同一块内存空间,是最快的可用 IPC 形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。

内存映射(mapped memory):内存映射允许任何多个进程间通信,每一个使用该机制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它。

信号量(semaphore):信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

套接口(Socket):更为一般的进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。可用于不同机器之间的进程间通信。


可以把 java 进程理解为 jvm 进程,至于通讯方式处理 Socket 以外 我们还可以用 RPC,Webservice,RMI,JMS 等,当然,JAVA 进程间通信的最基本手段大都也是 Socket。

RPC
远程过程调用(Remote Procedure Call,缩写为 RPC),是一种用于构建基于 C/S(客户端 / 服务器)的分布式应用程序技术。调用者与被调用者可能在同一台服务器上,也可能在由网络连接的不同服务器上,对于他们来说,网络通信是透明的,就是像调用本地方法一样调用远程方法。

RPC 框架要做到的最基本的三件事:


1、服务端如何确定客户端要调用的函数?

在远程调用中,客户端和服务端分别维护一个【ID-> 函数】的对应表, ID 在所有进程中都是唯一确定的。客户端在做远程过程调用时,附上这个 ID,服务端通过查表,来确定客户端需要调用的函数,然后执行相应函数的代码。

2、如何进行序列化和反序列化?

客户端和服务端交互时将参数或结果转化为字节流在网络中传输,那么数据转化为字节流的或者将字节流转换成能读取的固定格式时就需要进行序列化和反序列化,序列化和反序列化的速度也会影响远程调用的效率。

3、如何进行网络传输?(选择何种网络协议?)

多数 RPC 框架选择 TCP 作为传输协议,也有部分选择 HTTP。如 gRPC 使用 HTTP2。不同的协议各有利弊。TCP 更加高效,而 HTTP 在实际应用中更加的灵活。


RPC 框架作为架构微服务化的基础组件,它能大大降低架构微服务化的成本,提高调用方与服务提供方的研发效率,屏蔽跨进程调用函数(服务)的各类复杂细节。让调用方感觉就像调用本地函数一样调用远端函数、让服务提供方感觉就像实现一个本地函数一样来实现服务。

请注意,RPC 只是一种编程模型而非一种规范或协议,并没有规定你具体要怎样实现,你甚至都可以在你的 RPC 框架里面使用 RMI 来实现数据的传输!!!

成熟 RPC 框架:
dubbo:阿里开源的一款高性能 RPC 框架,在国内应用广泛,期间停止维护过一段时间,如今又开始了更新,并且捐献给 Apache 基金会。

gRPC:Google 开源,具有平台无关性,基于 http/2 协议,支持服务追踪、负载均衡、健康检查等功能;RPC 框架是基于 HTTP 协议实现的,底层使用到了 Netty 框架的支持。

Thrift:可伸缩的跨语言服务的 RPC 软件框架,最早由 Facebook 开发,2007 年捐献给了 Apache 基金会管理,现在是 Apache 的顶级项目;

Finagle:Twitter 基于 Netty 开发的支持容错的、协议无关的 RPC 框架,支撑了 Twitter 的核心服务。

Web Service
WebService 是一种跨编程语言和跨操作系统平台的远程调用技术。Web Service 提供的服务是基于 web 容器的,底层使用 http 协议,类似一个远程的服务提供者,比如天气预报服务,对各地客户端提供天气预报,是一种请求应答的机制,是跨系统跨平台的。就是通过一个 servlet,提供服务给其他应用请求。

WebService 采用 HTTP 协议传输数据,采用 XML 格式封装数据(即 XML 中说明调用远程服务对象的哪个方法,传递的参数是什么,以及服务对象的返回结果是什么)。XML 是 WebService 平台中表示数据的格式。除了易于建立和易于分析外,XML 主要的优点在于它既是平台无关的,又是厂商无关的。无关性是比技术优越性更重要的:软件厂商是不会选择一个由竞争对手所发明的技术的。但是 XML 虽然解决了数据表达问题,却留下了数据格式类型问题,XSD(XML Schema) 就是专门解决这个问题的一套标准。它定义了一套标准的数据类型,并给出了一种语言来扩展这套数据类型。

Web Service 的标准

Web Service 通过标准的 Web 协议向 Web 用户提供有用的功能。多数情况下使用 SOAP 协议。

Web Service 可以非常详细地说明其接口,这使用户能够创建客户端应用程序与它们进行通信。这种说明通常包含在称为 Web 服务说明语言 (WSDL) 文档的 XML 文档中。

Web Service 已经过注册,以便潜在用户能够轻易地找到这些服务,这是通过通用发现、说明和集成 (UDDI) 来完成的。

Web Service 体系结构的主要优点之一是: 允许在不同平台上、以不同语言编写的各种程序以基于标准的方式相互通信。

我们将 Web Service 定义为: 通过 SOAP 在 Web 上提供的软件服务,使用 WSDL 文件进行说明,并通过 UDDI 进行注册。


SOAP:
WebService 通过 HTTP 协议发送请求和接收结果时,发送的请求内容和结果内容都采用 XML 格式封装,并增加了一些特定的 HTTP 消息头,以说明 HTTP 消息的内容格式,这些特定的 HTTP 消息头和 XML 内容格式就是 SOAP 协议。SOAP 提供了标准 RPC 方法来调用 Web Service。


SOAP 协议 = HTTP 协议 + XML 数据格式

Soap 是 XML Web Service 的通信协议。

SOAP 是一种规范,用来定义消息的 XML 格式 。包含在一对 SOAP 元素中的、结构正确的 XML 段就是 SOAP 消息。


WSDL:
好比我们去商店买东西,首先要知道商店里有什么东西可买,然后再来购买,商家的做法就是张贴广告海报。WebService 也一样,WebService 客户端要调用一个 WebService 服务,首先要知道这个服务的地址在哪,以及这个服务里有什么方法可以调用,所以,WebService 务器端首先要通过一个 WSDL 文件来说明自己家里有啥服务可以对外调用,服务是什么(服务中有哪些方法,方法接受的参数是什么,返回值是什么),服务的网络地址用哪个 url 地址表示,服务通过什么方式来调用。

WSDL(Web Services Description Language) 就是这样一个基于 XML 的语言,用于描述 Web Service 及其函数、参数和返回值。它是 WebService 客户端和服务器端都能理解的标准格式。因为是基于 XML 的,所以 WSDL 既是机器可阅读的,又是人可阅读的,这将是一个很大的好处。一些最新的开发工具既能根据你的 Web service 生成 WSDL 文档,又能导入 WSDL 文档,生成调用相应 WebService 的代理类代码。

WSDL 文件保存在 Web 服务器上,通过一个 url 地址就可以访问到它。客户端要调用一个 WebService 服务之前,要知道该服务的 WSDL 文件的地址。WebService 服务提供商可以通过两种方式来暴露它的 WSDL 文件地址:

注册到 UDDI 服务器,以便被人查找;

直接告诉给客户端调用者。

UDDI:
UDDI 目录条目是介绍所提供的业务和服务的 XML 文件。UDDI 目录条目包括三个部分。

“白页” 介绍提供服务的公司: 名称、地址、联系方式等等;

“黄页” 包括基于标准分类法的行业类别;

“绿页” 详细介绍了访问服务的接口,以便用户能够编写应用程序以使用 Web 服务。

服务的定义是通过一个称为类型模型 (或 tModel) 的 UDDI 文档来完成的。多数情况下,tModel 包含一个 WSDL 文件,用于说明访问 XMLWeb Service 的 SOAP 接口,但是 tModel 非常灵活,可以说明几乎所有类型的服务。

RMI
Java RMI,即 远程方法调用 (Remote Method Invocation),一种用于实现远程过程调用 (RPC) 的 Java API, 能直接传输序列化后的 Java 对象和分布式垃圾收集。它的实现依赖于 Java 虚拟机 (JVM),因此它仅支持从一个 JVM 到另一个 JVM 的调用。甚至,它可以直接看成 RPC 的 java 版本。

RMI 采用 **stubs(占位程序)**和 skeletons 来进行远程对象 (remote object) 的通讯。

stub 充当远程对象的客户端代理,有着和远程对象相同的远程接口,远程对象的调用实际是通过调用该对象的客户端代理对象 stub 来完成的,通过该机制 RMI 就好比它是本地工作,采用 tcp/ip 协议,客户端直接调用服务端上的一些方法。优点是强类型,编译期可检查错误,缺点是只能基于 JAVA 语言,客户机与服务器紧耦合,缺点是只能使用 java。

总结起来,RMI 的工作原理大致可以理解为:


服务器端提供服务,服务中要暴露可以调用的远程方法,以接口的形式表现,这样在客户端可以通过服务接口来调用远程方法,实现复杂的业务逻辑。在服务器端,首先要对接口中提供的方法实现,以便客户端调用能够完成一定的业务逻辑;接着需要生成 Skeleton,在 Skeleton 中真正地实现了对商业方法的调用,完成了客户请求的调用的过程,将获取到的调用方法的结果通过序列化机制返回给客户端,进行应答。

在客户端,通过 Stub 来接收服务器返回的数据(对象),即在这里进行了反序列化,也就是读取网络传输的字节流,进而进行重构。在 Skeleton 和 Stub 中,都对网络通信进行了处理,例如建立套接字,建立网络连接,为实际的业务需要做好准备。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值