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

EJB 基石技術深度解析(二):RMI-IIOP 與 JNDI 核心機制

     編輯:Java 相關知識

RMI-IIOP:Java 分布式計算的網絡總線

RMI-IIOP (Remote Method Invocation over Internet Inter-ORB Protocol) 融合了 **Java RMI 易用性** 與 **CORBA 互操作性**,是 J2EE 容器間通信、EJB 遠程調用的標準協議棧。

核心架構三層模型

  1. Stub (客戶端代理):本地代表遠程對象,實現遠程介面,封裝網絡通信細節 (連接建立、參數編組、結果解組)。
  2. Skeleton (服務端分發器,JDK 1.2+ 內建):接收網絡請求,解組參數,分發至真實遠程對象實現,編組返回值/異常。
  3. ORB (Object Request Broker):底層通信引擎,處理 GIOP/IIOP 協議、連接管理、線程池、安全上下文傳播。

遠程介面契約:java.rmi.Remote 標記介面

public interface Remote { } // 無方法,純標記

強制規則:

  • 遠程介面必須繼承 Remote (直接或間接)
  • 所有方法必須在 throws 中聲明 RemoteException (或其父類 IOException, Exception)
  • 參數/返回值若為遠程對象,必須聲明為遠程介面類型,而非實現類

參數傳遞語義深度解析

類型傳遞方式序列化要求遠程修改可見性
基本類型按值 (複製)無不可見
可序列化對象 (Serializable)按值 (深拷貝)實現 Serializable,建議显式 serialVersionUID不可見 (各持副本)
遠程對象 (Remote)按引用 (傳遞 Stub)無需序列化,Stub 可序列化可見 (操作同一遠程實例)
外部化對象 (Externalizable)按值 (自定義格式)實現 writeExternal/readExternal不可見

引用完整性保證

單次遠程調用中,同一對象的多個引用 (參數圖中) 在遠端將映射為 **同一 Stub 實例**,保持對象圖拓撲結構不變。

動態類加載:annotateClass 機制

  • 序列化流中嵌入類的 codebase URL (HTTP/FTP/file)
  • 接收端類加載器解析 URL,動態下載類字節碼
  • 安全策略控制下載權限 (SocketPermission、FilePermission)

JNDI:分布式命名與目錄服務的統一介面

核心抽象:Context 與 Name

  • Context:命名上下文,提供 bind/rebind/unbind/lookup/list 操作
  • Name:複合名稱 (如 java:comp/env/jdbc/MyDS),支援複合命名規則
  • InitialContext:進入點,根據環境屬性 (java.naming.factory.initial, provider.url) 連接具體命名服務

J2EE 標準命名子上下文

子上下文用途示例
java:comp/env組件環境項目 (ENC)jdbc/MyDS, ejb/MyBean, jms/MyQueue
java:global應用級全域綁定 (EJB 3.1+)java:global/app/module/BeanName!Interface
java:app模組級共享綁定java:app/module/BeanName
java:module當前模組綁定java:module/BeanName

EJB 客戶端查找模式演進

<!-- EJB 2.x: Home 介面查找 -->
Context ctx = new InitialContext();
Object ref = ctx.lookup("java:comp/env/ejb/MyBean");
MyHome home = (MyHome) PortableRemoteObject.narrow(ref, MyHome.class);
MyRemote remote = home.create();

// EJB 3.x: 無 Home 介面,直接查找業務介面 (可攜帶全域 JNDI 名)
@EJB // 依賴注入 (容器管理環境)
MyBusinessInterface ejb;

// 或 程式化查找
Context ctx = new InitialContext();
MyBusinessInterface ejb = (MyBusinessInterface) ctx.lookup("java:global/myApp/myModule/MyBean!com.demo.MyBusinessInterface");

RMI-IIOP + JNDI = EJB 遠程調用完整鏈路

  1. **部署時**:容器生成 Stub/Skeleton,將遠程業務介面綁定至 JNDI (全域/ENC)
  2. **客戶端啟動**:獲取 InitialContext (配置 Provider URL 指向目標服務器)
  3. **查找**:lookup(jndiName) 返回 Stub 序列化形式,經反序列化還原為本地 Stub
  4. **調用**:客戶端調用 Stub 方法 → 編組參數 → IIOP 請求 → 服務端 Skeleton → 分發實現 → 編組結果 → IIOP 回應 → Stub 解組返回
  5. **上下文傳播**:安全主體、事務上下文、呼叫鏈 ID 隨 IIOP 服務上下文 (Service Context) 流轉

常見故障診斷矩陣

異常典型原因排查方向
ClassNotFoundException: Stub客戶端缺少 Stub 類、codebase 未配置/不可達檢查 java.rmi.server.codebase、HTTP 類服務器、防火牆
NoSuchObjectException遠程對象已失效、容器重啟、租約過期檢查 EJB 生命週期、@Remove 調用、容器閒置超時配置
MarshalException參數/返回值不可序列化、serialVersionUID 不匹配實現 Serializable、显式 serialVersionUID、檢查傳遞對象圖
CommunicationException網絡不通、防火牆攔截 IIOP 端口 (默認 3700/3500)、ORB 端點配置錯誤Telnet 端口、檢查 ORBListenPort、ORBInitialHost
NamingExceptionJNDI 名稱錯誤、Provider URL 錯誤、命名服務未啟動驗證 java.naming.provider.url、list() 瀏覽命名樹

現代替代方案與遷移路徑

  • gRPC + Protobuf:高效二進制協議、跨語言、HTTP/2、流式 RPC、契約優先
  • REST/JSON + OpenAPI:通用性最強、防火牆友好、人類可讀、生態最豐
  • Spring Cloud OpenFeign / Dubbo:聲明式 HTTP/RPC、服務發現、負載均衡、熔斷限流

遷移策略:**Strangler Fig 模式** —— 新服務採用現代協議,舊 EJB 通過適配器/網關暴露為 REST/gRPC,逐步剝離 RMI-IIOP 依賴。

結語

RMI-IIOP 與 JNDI 共同構建了 J2EE 時代分布式計算的「網絡層」與「地址簿」。理解其 **Stub/Skeleton 代理機制、參數傳遞語義、動態類加載、命名上下文層級、遠程引用生命週期**,不僅是維護遺產系統的必備技能,更是掌握現代微服務通信本質 (服務發現、負載均衡、序列化、超時重試、熔斷) 的認知基石。技術棧更迭,分布式核心難題永恆不變。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved