首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2EE

RMI 規範第三章深度解析:Stub/Skeleton、線程模型、分布式 GC 與防火牆穿透

     編輯:J2EE

Stub 與 Skeleton:RMI 通訊的雙邊代理

RMI 採用經典 RPC 機制——Stub(存根)與Skeleton(骨架)實現遠程通訊。

Stub(客戶端代理)職責

  • 初始化與遠程 JVM 的連接
  • 參數編組(序列化與傳輸)
  • 等待調用結果
  • 解編返回值或異常
  • 將結果返還調用者

Stub 實現了遠程對象的所有遠程接口,對調用者隱藏了序列化與網絡通訊細節,呈現簡單的本地調用體驗。

Skeleton(服務端分發器)職責 (JDK 1.2+ 純環境不再需要)

  • 解編遠程方法參數
  • 調用實際遠程對象實現
  • 編組返回值或異常發回調用者

JDK 1.2 引入新 Stub 協議,通用代碼取代 Skeleton,由 rmic 編譯器生成 Stub/Skeleton。

遠程方法調用中的線程使用

RMI 運行時不保證遠程對象與線程的映射關係。同一遠程對象的多個調用可能並發執行,因此遠程對象實現必須確保線程安全。

遠程對象的分布式垃圾收集(DGC)

RMI 採用引用計數算法(類似 Modula-3 Network Objects)自動回收無客戶端引用的遠程對象,釋放程序員手動追蹤負擔。

核心機制

  • 運行時追蹤每個 JVM 內的活動引用計數
  • 引用進入 JVM 計數 +1,發送 "referenced" 消息
  • 引用失效計數 -1,最後一個引用釋放發送 "unreferenced" 消息
  • 協議維護消息順序防止過早回收

弱引用與回收條件

  • 無客戶端引用時,RMI 對遠程對象持有弱引用
  • 無本地引用時,JVM GC 可回收該對象
  • 存在本地引用時不可回收,且可繼續傳遞/返回
  • 需通知的遠程對象實現 java.rmi.server.Unreferenced 接口,引用集為空時調用 unreferenced()

網絡分區風險

若客戶端與服務器發生網絡分區,傳輸層可能誤判客戶端失效導致過早回收。此時遠程引用可能指向不存在對象,調用將拋出 RemoteException,應用程序必須處理。

動態類加載:實現代碼移動性

RMI 允許傳遞任意可序列化對象,使用對象序列化傳輸數據,並用 codebase URL 註解調用流,接收端據此加載類定義。

加載流程

  1. 解編時優先嘗試本地類加載器(當前線程上下文類加載器)按名稱解析
  2. 失敗則使用動態加載:從發送端指定的網絡位置(codebase)下載類文件
  3. 包括 Stub 類、參數聲明類型的子類等

關鍵實現類

  • RMIClassLoader:提供靜態方法支持網絡類加載,供內部編組流調用
  • ObjectOutputStream 子類覆蓋 annotateClass 寫入 codebase
  • ObjectInputStream 子類覆蓋 resolveClass 讀取 codebase 並加載

通過代理服務器穿透防火牆的 RMI

默認 RMI 嘗試直接 Socket 連接,但許多防火牆禁止。RMI 提供兩種基於 HTTP 的穿透機制:

HTTP 封裝兩種模式

  1. 直接轉發:代理可轉發至任意端口 → HTTP POST 直接發送至 RMI 服務器監聽端口,服務器 Socket 識別並解碼 RMI 調用
  2. CGI 轉發:代理僅允許 80 端口 → 請求轉發至 HTTP 服務器,執行 CGI 腳本再轉發至 RMI 服務器端口

默認 Socket 工廠自動處理

  • 客戶端 Socket 自動嘗試 HTTP 連接無法直連的主機
  • 服務端 Socket 自動檢測 HTTP POST 請求,提取主體交給傳輸層,輸出格式化為 HTTP 響應
  • 無需特殊配置即可啟用;可設置 java.rmi.server.disableHttp=true 禁用

服務器配置要點

  • 主機名必須使用全限定域名(非 IP),啟動時指定 -Djava.rmi.server.hostname=FQDN
  • 若需支持防火牆外客戶端:HTTP 服務器監聽 80 端口,CGI 腳本路徑 /cgi-bin/java-rmi.cgi,腳本調用本地 Java 解釋器轉發請求

性能與限制

  • HTTP 封裝調用比直接 Socket 慢至少一個數量級
  • 防火牆外主機無法回調客戶端導出的遠程對象(單向初始化限制)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved