P8架構師教你如何認識,Mina

認識 Mina

Apache Mina Server 是一個網絡通信應用框架,與 Netty 出自同一作者,Netty 借鑑了部分 Mina 的設計思路。

 

Mina 主要是對基於 TCP/IP、UDP/IP 協議棧的通信框架,Mina 可以幫助我們快速開發高性能、高擴展性的網絡通信應用,Mina 提供了事件驅動、異步操作的編程模型,Mina 的異步 IO 默認使用的是 JAVA NIO(New IO)作爲底層支持,基於 Channel 的雙向通道。Mina 主要有1.x 和2.x 兩個分支。Mina 同時提供了網絡通信的 Server 端、Client 端的封裝,無論是哪端,Mina 在整個網通通信結構中提供了一系列接口 API,Mina 的 API 將真正的網絡通信與我們的應用程序隔離開來。Java學習圈子

 

Mina 的底層依賴的主要是 Java NIO 庫,上層提供的是基於事件的異步接口。其整體的結構如下:

 

  • IoService:最底層的是 IOService,負責具體的 IO 相關工作。這一層的典型代表有 IOSocketAcceptor 和 IOSocketChannel,分別對應 TCP 協議下的服務端和客戶端的 IOService。IOService 的意義在於隱藏底層 IO 的細節,對上提供統一的基於事件的異步 IO 接口。每當有數據到達時,IOService 會先調用底層 IO 接口讀取數據,封裝成 IoBuffer,之後以事件的形式通知上層代碼,從而將 Java NIO 的同步 IO 接口轉化成了異步 IO。所以從圖上看,進來的 low-level IO 經過 IOService 層後變成 IO Event。具體的代碼可以參考 org.apache.mina.core.polling.AbstractPollingIoProcessor 的私有內部類 Processor。
  • IoProcessor:這個接口在另一個線程上,負責檢查是否有數據在通道上讀寫,也就是說它也擁有自己的 Selector,這是與我們使用 JAVA NIO 編碼時的一個不同之處,通常在 JAVA NIO 編碼中,我們都是使用一個 Selector,也就是不區分 IoService 與 IoProcessor 兩個功能接口。另外,IoProcessor 負責調用註冊在 IoService 上的過濾器,並在過濾器鏈之後調用 IoHandler。
  • IoFilter:這個接口定義一組攔截器,這些攔截器可以包括日誌輸出、黑名單過濾、數據的編碼(write 方向)與解碼(read 方向)等功能,其中數據的 encode 與decode 是最爲重要的、也是你在使用 Mina 時最主要關注的地方。
  • IoHandler:這個接口負責編寫業務邏輯,也就是接收、發送數據的地方。需要有開發者自己來實現這個接口。IoHandler 可以看成是 Mina 處理流程的終點,每個 IoService 都需要指定一個 IoHandler。
  • IoSession:是對底層連接(服務器與客戶端的特定連接,該連接由服務器地址、端口以及客戶端地址、端口來決定)的封裝,一個 IoSession 對應於一個底層的 IO 連接(在 Mina 中 UDP 也被抽象成了連接)。通過 IoSession,可以獲取當前連接相關的上下文信息,以及向遠程 peer 發送數據。發送數據其實也是個異步的過程。發送的操作首先會逆向穿過 IoFilterChain,到達 IoService。但 IoService 上並不會直接調用底層 IO 接口來將數據發送出去,而是會將該次調用封裝成一個 WriteRequest,放入 session 的 writeRequestQueue 中,最後由 IoProcessor 線程統一調度 flush 出去。所以發送操作並不會引起上層調用線程的阻塞。具體代碼可以參考 org.apache.mina.core.filterchain.DefaultIoFilterChain 的內部類 HeadFilter 的 filterWrite 方法。

服務端流程:

  • 通過 SocketAcceptor 同客戶端建立連接
  • 連接建立之後 I/O 的讀寫交給了 I/O Processor 線程,I/O Processor 是多線程的
  • 通過 I/O Processor 讀取的數據經過 IoFilterChain 裏所有配置的 IoFilter,IoFilter 進行消息的過濾,格式的轉換,在這個層面可以制定一些自定義的協議
  • 最後 IoFilter 將數據交給 Handler 進行業務處理,完成了整個讀取的過程

寫入過程也是類似,只是剛好倒過來,通過 IoSession.write 寫出數據,然後 Handler 進行寫入的業務處理,處理完成後交給 IoFilterChain,進行消息過濾和協議的轉換,最後通過 I/O Processor 將數據寫出到 socket 通道。

簡單的 TCPServer

第一步:編寫 IoService

 

第二步:編寫過濾器

 

第三步:編寫 IoHandler

 

把這個 IoHandler 註冊到 IoService:

 

當然這段代碼也要在 acceptor.bind() 方法之前執行。完成的代碼:

 

簡單的 TCPClient

第一步:編寫 IoService 並註冊過濾器

 

第三步:編寫 IoHandler

 

註冊 IoHandler:


 
connector.setHandler(new ClientHandler("你好!\r\n 大家好!")); 

粉絲福利

Java架構進階資源

 

分析源碼

 

分佈式架構

 

性能優化

 

Java面試避坑指南

 

Java面試題集錦

上圖中的資料都是我精心錄製視頻,感興趣的可以到我的Java學習圈子:免費獲取。希望能夠在你接下來即

將應對的的面試過程中能夠盡到一份綿薄之力。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章