分布式应用概述二
1、概述
1.1 大型应用通常会拆分为多个子系统来实现;
对于java来说,这些子系统可能部署在同一台机器的多个不同的JVM中,也可能部署在不同的机器上;
但这些子系统又不是完全独立的,要相互通信来共同实现业务功能;
1.2 对于分布式java应用,通常有2种典型的方法来是实现:
1.1.1 基于消息方式
当系统之间要通信时,就向外发送消息,消息可以是字节流、字节数组、甚至是java对象,其他系统接收到消息后则进行相应的业务处理;
消息方式的系统间通信,通常基于网络协议来实现,常用的实现系统间通信的协议有:TCP/IP、UDP/IP;
TCP、UDP可用于完成数据的传输,但要完成系统间通信,还需要对数据进行处理。例如,读取、写入数据,按照POSIX标准分为同步IO、异步IO;
1.1.1.1 BIO
当发起IO的读或写操作时,均为阻塞方式,只有当程序读到了流或者将流写入OS后,才会释放资源;
1.1.1.2 NIO
基于事件驱动的思想,通常采用Reactor模式,当发起IO的读或写操作时,是非阻塞的;
只有当Socket有流可读或可写入Socket时,OS会相应地通知应用程序进行处理,应用再将流读取到缓冲区或写入OS;
对于网络IO而言,主要有3种事件:连接建立、流读取、流写入;
1.1.1.3 AIO
基于事件驱动思想,通常采用Proactor模式;
和NIO不同,当进行读写操作时,只须调用API的read、write即可,这2种方法均为异步;
对于read操作而言,当有流可读取时,OS会将可读的流传入read方法的缓冲区,并通知应用程序;
对于write操作而言,当OS将write方法传递的流写入完毕时,OS主动通知应用程序;
较之NIO而言,AIO一方面简化了程序的编写,流的读写都由OS来代替完成;另一方面省去了NIO中程序要遍历事件通知队列的代价;
1.1.2 基于远程调用方式
当系统之间要通信时,可通过调用本地的一个java接口的方法,透明地调用远程的java实现,具体的实现细节由java或框架完成,这种方式在java中主要用来实现基于RMI、WebService的应用;
2、分布式java应用实现:
1.1 消息方式
1.1.1 基于java自身技术实现消息方式的系统间通信:
TCP+BIO;
TCP+NIO;
UDP+BIO;
UDP+NIO;
1.1.2 基于开源框架实现消息方式的系统间通信:
Mina
Apache的顶级项目,基于java NIO实现,同时支持TCP、UDP协议;
Mina对外屏蔽了java NIO使用的复杂性,并在性能上做了很多优化;
1.2 远程调用
远程调用基于网络通信实现;
远程调用方式就是尽可能使系统间的通信和系统内一样,让调用者调用远程同调用本地一样;
但其实并没有办法做到完全透明:例如由于远程调用带来的网络问题、超时问题、序列化/反序列化问题、调试复杂的问题等,在远程调用时都需要处理;
1.1.1 基于java自身技术实现远程调用方式的系统间通信:
RMI(Remote Method Invocation)
RMI是java用于实现透明远程调用的重要机制;
远程调用中,客户端仅有服务器端提供的接口,通过此接口实现对远程服务器端的调用;
WebService
WebService是一种跨语言的系统间交互标准;
对外提供功能的一方以HTTP的方式提供服务,该服务采用WSDL(Web Service Description Language)描述,在这个文件中描述服务所用的协议、所期望的参数、返回的参数格式等;
调用端和服务端通过SOAP(Simple Object Access Protocol)方式进行交互;
1.1.2 基于开源框架实现远程调用方式的系统间通信:
Spring RMI
Spring RMI是Spring Remoting中的一个子框架;
基于Spring RMI可以很简单实现RMI方式的java远程调用;
CXF
CXF是Apache的顶级项目;
基于CXF可以非常简单地以WebService方式来实现java甚至是跨语言的远程调用;