未完待續》》》
目錄:
一)同步、異步、阻塞、非阻塞
二)Java中的NIO
三)Mina 異步請求
四)Mina 同步請求
五)Mina 核心類及處理流程
六)Mina 線程模型
七)Mina 通用通訊框架(協議:ProtoBuf)
八)Mina 其他
(注:部分內容整理來自網絡資源!)
一)同步、異步、阻塞、非阻塞
1)同步阻塞
2)同步非阻塞
3)異步阻塞
4)異步非阻塞
阻塞與非阻塞是一個相對的問題——誰阻塞了誰?是兩個“事物”的交互問題。
同步與異步通俗的來說是指——完成一件事的過程是“從頭到尾”還是“多線操作”。
大多數認為阻塞就同步,非阻塞就異步。但是上文提到的“同步非阻塞”怎么理解呢?——同步非阻塞中的“非阻塞”是指不阻塞應用線程,如果kernel沒有准備好會返回應用線程一個狀態,但是應用線程會不停的“主動”檢查這個狀態,一直等到返回ok狀態,因此說他還是個“同步”的操作。
link:
http://www.ibm.com/developerworks/cn/linux/l-async/
http://blog.csdn.net/historyasamirror/article/details/5778378
二)Java中的NIO
NIO主要關鍵點:
- buffer
- channel
- selector
三)Mina 異步請求
四)Mina 同步請求
例如Mina的NioSocketConnector建立連接的過程如下(同步):
ConnectFuture connectF = connector.connect(new InetSocketAddress(ip, port)); connectF.awaitUninterruptibly(); session = connectF.getSession();
ConnectFuture調用awaitUninterruptibly方法后,將阻塞應用線程直到連接建立完成。此時將獲得session對象。(如果不awaitUninterruptibly,從ConnectFuture中獲取的session極有可能為null。)
因此這里的awaitUninterruptibly方法 將一個異步請求“活生生的”轉變成一個同步請求。同理,write、read動作類似處理(同步):
write
WriteFuture writeF = session.write(msg); writeF.awaitUninterruptibly(); if (writeF.getException() != null) { //異常處理 } else if (writeF.isWritten()) { //准備讀操作 }
read
ReadFuture readF = session.read(); readF.awaitUninterruptibly(); if (readF.getException() != null) { //異常處理 } else { //接收到消息,進行業務處理 }
具體參見實例:
http://www.cnblogs.com/huangfox/p/3461839.html
五)Mina 核心類及處理流程
從上圖可以關鍵的類包括:
IoService,IoFilterChain,IoHandler,IoSession
1)IoService
IoService負責底層IO操作,他的好處主要在於隱藏底層IO操作,方便使用;基於事件機制將同步IO轉化成異步IO。
最常用的接口是SocketAcceptor、SocketConnector,用做TCP協議通訊下的服務端和客戶端。
2)IoFilterChain
IoFilterChain主要負責數據包的處理工作,包括編碼、解碼等功能。其主要思想是——與業務邏輯代碼分離。當然IofilterChain也是處理流程的擴展點,包括為處理流程添加線程池。
3)IoHandler
IoHandler主要實現業務邏輯(調用業務邏輯接口)。
4)IoSession
IoSession是對底層連接的封裝,一個IoSession對應一個底層的IO連接。
發送數據其實是個異步的過程。發送的操作首先會逆向穿過IoFilterChain,到達IoService。但IoService上並不會直接調用底層IO接口來將數據發送出去,而是會將該次調用封裝成一個WriteRequest,放入session的writeRequestQueue中,最后由IoProcessor線程統一調度flush出去。所以發送操作並不會引起上層調用線程的阻塞。
處理流程
1)建立連接
開啟一個SocketAcceptor(服務端),會創建一個acceptor線程,他負責監聽指定端口上的connect事件(維護一個selector)。獲取新建的連接后封裝成IoSession交由IoProcessor線程處理。
SocketConnector(客戶端)類似會創建一個connector線程。
這類acceptor、connector線程可以生動的理解為“前台線程”,負責“接待工作”(connector),有客戶來訪將其登記(標示成一個業務需求-IoSession)交由具體的業務員(IoProcessor)處理。
2)processor處理
Processor線程主要負責具體的IO操作、filterChain、IoHandler執行。Processor線程的數量默認為cpu數量+1,主要是為了充分利用多核的處理能力。Processor線程的數量可以根據實際情況進行配置。
多個IoSession會被分配到多個Processor線程中,可以理解為一個Processor線程“服務”一個或多個IoSession對象。值得一提的是,N個IoProcessor形成一個處理池(SimpleIoProcessorPoll),分配Processor的時候根據IoSession的id絕對值模N進行分配。
具體代碼如下:
private IoProcessor<S> getProcessor(S session) { IoProcessor<S> processor = (IoProcessor<S>) session.getAttribute(PROCESSOR); if (processor == null) { if (disposed || disposing) { throw new IllegalStateException("A disposed processor cannot be accessed."); } //取模分配 processor = pool[Math.abs((int) session.getId()) % pool.length]; if (processor == null) { throw new IllegalStateException("A disposed processor cannot be accessed."); } //session保定具體的processor線程 session.setAttributeIfAbsent(PROCESSOR, processor); } return processor; }
在默認情況下filterChain、IoHandler的操作都是有IoProcessor順序執行(執行完一個再執行下一個),如果IoHandler中的業務處理比較耗時,那么Processor線程將阻塞,后續的請求將得不到處理。即同時處理的請求數最多只有N個(N為Processor線程數量)。在高並發的情況下這種模式有待改進。(六 Mina線程模型 中將解答該問題)
接着上面的類比,前台(acceptor、connector)接待客戶(session)分配給業務員(IoProcessor)進行服務, 業務員對客戶進行交流(IO操作、編碼、解碼等)並執行相應的業務服務(IoHandler)。同理業務員每次只能服務一個客戶,其他客戶只能等待(假設其他業務員都有自己的客戶)。
六)Mina 線程模型
接上文,上文提到“若IoHandler中的業務處理比較耗時,將阻塞當前Processor線程”,那么可以通過添加線程池處理這個問題。
Mina提供了一個很好的擴展點,可以在FilterChain添加線程池,讓“下面”的業務處理過程並行起來。如圖:
第一種模式:Mina默認的模式,IoProcessor全程服務。(One by one)
第二種模式:在FilterChain中加入ThreadPoolFilter,此時的處理流程變為Processor線程讀取完數據后,執行IoFilterChain的邏輯。當執行到Thread Pool Filter的時候,該Filter會將后續的處理流程封裝到一個Runnable對象中,並交由Filter自身的線程池來執行,而Processor線程則能立即返回來處理下一個IO請求。這樣如果后面的IoFilter或IoHandler中有阻塞操作,只會引起Filter線程池里的線程阻塞,而不會阻塞住Processor線程,從而提高了服務器的處理能力。Mina提供了Thread Pool Filter的一個實現:ExecutorFilter。(本段內容為轉載)
第三種模式:在合適的環節添加多個線程池,這種適合於FilterChain、IoHandler過程中存在多個計算密集型的任務。一般不需要使用,加大了代碼復雜程度。
接着上面的類比,如果公司業務發展很好,客戶增多,那么一個業務員(Processor)將很難及時服務到眾多客戶。於是公司決定業務員只負責與客戶交流,具體的業務操作交由專門的業務服務團隊(ThreadPool)。大家意會一下即可!
七)Mina 通用通訊框架(協議:ProtoBuf)
八)Mina 其他