《分布式java应用基础与实践 读后感》

消息方式的系统间通信,通常基于网络协议来实现,常用的实现系统间通信的协议有:TCP/IP 和 UDP/IP。

TCP/IP: 是一种可靠的网络数据传输的协议,TCP/IP 要求通信双方首先建立连接,之后再进行数据的传输。TCP/IP负载保证数据传输的可靠性,包括数据的可到达,数据到达的顺序等,但由于TCP/IP 需要保证连接及数据传输的可靠性,因此可能会牺牲一些性能。

UDP/IP:  是一种不保证数据一定到达的网络数据传输协议。UDP/IP 并不直接给通信的双方建立连接,而是发送到网络上进行传输。由于UDP/IP 不建立连接,并且不能保证数据传输的可靠,因此性能上表现相对较好,但可能会出现数据丢失以及数据乱序的现象。

TCP/IP 和 UDP/IP 可用于完成数据的传输,但完成系统间通信,还需要对数据进行处理,例如读取和写入数据,按照posix 标准分为同步IO 和异步IO 两种。其中同步IO 最常用的是BIO(blocking io) 和 NIO(non-blocking io)。

从程序角度而言,BIO 就是当发起IO 的读或写操作时,均为阻塞方式,只有当程序读到了流或将流写入操作系统后,才会释放资源。

NIO 是基于事件驱动思想的,实现上通常采用reactor模式,从程序角度而言,当发起IO的读或写操作时,是非阻塞的;当socket有流可读或可写入socket时,操作系统会相应的通知应用程序进行处理,应用再将流读取到缓冲区或写入操作系统。对于网络IO 而言,主要有连接建立,流读取及流写入三种时间,linux2.6以后的版本采用epoll 方式实现NIO。

AIO :异步IO 方式,基于事件驱动思想,实现上采用proactor 模式,从程序角度而言,和NIO 不同,当进行读写操作时,只需要直接调用API 的read 或 write 方法即可。NIO 和 AIO 均为异步,对于读操作,当有流可读取时,操作系统会将可读的流传入read 方法的缓冲区,并通知应用程序;对于写操作,当操作系统将write 方法传递的流写入完毕时,操作系统主动通知应用程序。两者比较,AIO 一方面简化了程序的编写,流的读取和写入都由操作系统代替完成;另一方面省去了NIO 中程序要遍历事件通知队列的代价。windows基于IOCP5 实现了AIO,linux 目前只有基于epoll 模拟实现了AIO。

java对于TCP/IP & UDP/IP 都支持,在网络IO的操作上,jdk7 之前的版本只支持BIO 和 NIO。

基于远程调用方式实现系统间的通信: 当系统之间要通信时,可通过调用本地的一个java接口的方法,透明的调用远程的java 实现。这种方式在java中主要用来实现基于RMI 和 webService 的应用。

基于java自身技术实现消息方式的系统间通信有四种方式: TCP/IP+BIO ,TCP/IP+NIO,UDP/IP+BIO,UDP/IP+NIO 。

TCP/IP+BIO: 在java中可基于socket,serverSocket 来实现TCP/IP+BIO的系统间通信。socket主要用于实现建立连接及网络IO的操作,serverSocket 主要用于实现服务器端端口的监听及socket对象的获取。

TCP/IP+NIO : 在java 中可基于java.io.channels 中的channel 和 selector 的相关类来实现TCP/IP+NIO方式的系统间通信,channel 有socketChannel和serverSocketChannel 两种,socketChannel用于建立连接,监听事件及操作读写,serverSocketChannel 用于监听端口连接事件;程序通过selector 来获取是否有要处理的事件。

UDP/IP+BIO : java 对UDP/IP 方式的网络数据传输同样采用socket 机制,只是UDP/IP 下的socket 没有建立连接的要求。由于UDP/IP 是无连接的,因此无法进行双向的通信。如果要双向通信,必须两端都称为UDPServer。

在java中可基于datagramSocket 和 datagramPacket 实现UDP/IP+BIO 方式的系统间通信,datagramSocket负责监听端口及读写数据。 datagramPacket作为数据流对象进行传输。

UDP/IP+NIO: 在java 中可通过datagramChannel 和byteBuffer来实现UDP/IP+NIO 方式系统间通信,datagramChannel负责监听端口和进行读写,byteBuffer 则用于数据流传输。

Mina 是Apache 的项目,基于java NIO构建,同时支持TCP/IP 和 UDP/IP 两种协议。Mina 对外屏蔽了java NIO 使用的复杂性,并在性能上做了不少的优化。在使用Mina时,关键的类为IoConnector,IoAcceptor,IoHandler 及IoSession,Mina 采用Filter Chain的方式封装消息发送和接收的流程,在这个Filter Chain 过程中可进行消息的处理,消息的发送和接受等。

IoConnector 负责配置客户端的消息处理器,IO事件处理线程池,消息发送、接受的Filter Chain等。

IoAcceptor 负责配置服务器端的IO事件处理线程池,消息发送、接受的Filter Chain等。

IoHandler 作为Mina 和应用的接口,当发生了连接事件,IO 事件或异常事件时,Mina都会通知应用所实现的IoHandler。

IoSession类似socketChannel 的封装,不过Mina 对连接做了进一步的抽象,因此可进行更多连接的控制及流信息的输出。

远程调用方式主要有RMI & webservice。

RMI(remote method invocation) 是java用于实现透明远程调用的重要机制。在远程调用中,客户端仅有服务器端提供的接口,通过此接口实现对远程服务器端的调用。

webService : 是一种跨语言的系统间交互标准。在这个标准中,对外提供功能的一方以http的方式提供服务,该服务采用wsdl(web service description language)描述,在这个文件中描述服务所使用的协议,所期望的参数,返回的参数格式等。调用端和服务端通过SOAP(simple object access protocol) 方式来进行交互。

在java 中使用webservice 首先将服务端的服务根据描述生成对应的WSDL文件,并将应用及此wsdl 文件放入http 服务器中,借助java 辅助工具根据wsdl文件生成客户端stub 代码。此代码的作用是将产生的对象请求信息封装为标准的SOAP 格式数据,并发送请求到服务器端,服务器端在接手到soap 格式数据时进行转化,反射调用相应的java类。

spring RMI : 是spring remoting 中的一个子框架,基于spring RMI 可以很简单的实现RMI 方式的java 远程调用。

CXF: 是Apache 的项目,也是目前java 社区中用来实现webservice 流行的一个开源框架,基于CXF 可以非常简单的以webservice 的方式来实现java 甚至是跨语言的远程调用。