《分佈式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 甚至是跨語言的遠程調用。