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

RMI 入門實戰:手把手構建分布式計算服務

     編輯:Java 相關知識

RMI 架構核心:介面與實現分離

Java RMI(Remote Method Invocation)是分布式 Java 應用的基石,核心原則:**遠程介面定義契約,本地實現履行契約,Stub/Skeleton 透明代理網絡通信**。完整 RMI 系統包含七大組件:

  1. 遠程服務介面(extends Remote)
  2. 遠程服務實現(extends UnicastRemoteObject)
  3. Stub/Skeleton 類(rmic 生成)
  4. RMI Registry 命名服務
  5. 服務端啟動類
  6. 客戶端調用類
  7. 類文件分發機制(HTTP/FTP/本地)

六步構建簡易計算服務

步驟 1:定義遠程介面 Calculator.java

package rmi.demo;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Calculator extends Remote {
    long add(long a, long b) throws RemoteException;
    long sub(long a, long b) throws RemoteException;
    long mul(long a, long b) throws RemoteException;
    long div(long a, long b) throws RemoteException;
}

鐵律:介面必須 extends Remote;所有方法必須拋出 RemoteException。

步驟 2:實現業務邏輯 CalculatorImpl.java

package rmi.demo;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class CalculatorImpl extends UnicastRemoteObject implements Calculator {
    protected CalculatorImpl() throws RemoteException { super(); }

    public long add(long a, long b) { return a + b; }
    public long sub(long a, long b) { return a - b; }
    public long mul(long a, long b) { return a * b; }
    public long div(long a, long b) { return a / b; }
}

關鍵點:繼承 UnicastRemoteObject 自動啟用 RMI 遠程能力;必須提供拋出 RemoteException 的構造器並調用 super()。

步驟 3:生成 Stub/Skeleton

> rmic rmi.demo.CalculatorImpl
// 生成 CalculatorImpl_Stub.class (客戶端代理)
// JDK 1.2+ 無需 Skeleton,直接由 Stub 與遠程對象通信

步驟 4:編寫服務端啟動類 CalculatorServer.java

package rmi.demo;

import java.rmi.Naming;
import java.rmi.RemoteException;

public class CalculatorServer {
    public static void main(String[] args) {
        try {
            Calculator calc = new CalculatorImpl();
            // 綁定至 RMI Registry:rmi://host:port/name
            Naming.rebind("rmi://localhost:1099/CalculatorService", calc);
            System.out.println("CalculatorService 已就緒...");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

步驟 5:編寫客戶端 CalculatorClient.java

package rmi.demo;

import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.net.MalformedURLException;

public class CalculatorClient {
    public static void main(String[] args) {
        try {
            Calculator calc = (Calculator) Naming.lookup("rmi://localhost:1099/CalculatorService");
            System.out.println("4 - 3 = " + calc.sub(4, 3));
            System.out.println("4 + 5 = " + calc.add(4, 5));
            System.out.println("3 * 6 = " + calc.mul(3, 6));
            System.out.println("9 / 3 = " + calc.div(9, 3));
        } catch (MalformedURLException | RemoteException | NotBoundException e) {
            e.printStackTrace();
        }
    }
}

步驟 6:三終端啟動驗證

終端命令關鍵點
1. Registryrmiregistry需在類文件根目錄執行,確保 Stub 類可被動態下載
2. Serverjava -Djava.security.policy=policy.txt rmi.demo.CalculatorServer需安全策略文件授權 permission java.security.AllPermission
3. Clientjava -Djava.security.policy=policy.txt rmi.demo.CalculatorClient需遠程介面類與 Stub 類

核心機制深度解析

參數傳遞語義

  • 基本類型/可序列化對象:按值傳遞(深拷貝),客戶端修改不影響服務端。
  • 遠程對象:按引用傳遞(傳遞 Stub),雙端操作同一遠程實例。
  • 引用完整性:單次調用中同一對象的多個引用,在遠端映射為同一 Stub。

動態類加載

RMI 透過 annotateClass 在序列化流中嵌入類 URL(HTTP/FTP/file),客戶端/服務端自動下載缺失類。生產環境建議部署專用 HTTP 類服務器,避免 codebase 配置錯誤導致 ClassNotFoundException。

安全策略最小權限原則

// policy.txt - 僅示範,生產嚴禁 AllPermission
grant {
    permission java.security.AllPermission;
};

實際部署應限制 SocketPermission、PropertyPermission、RuntimePermission 至最小集合。

常見坑與避坑指南

  1. ClassNotFoundException: CalculatorImpl_Stub → 確保 rmic 生成的 Stub 類在客戶端 classpath 或可經 codebase 下載。
  2. ConnectException: Connection refused → 檢查 Registry 是否啟動、端口 1099 是否被佔用、防火牆規則。
  3. UnmarshalException: Class not found → 服務端缺少客戶端傳遞的可序列化類,需同步部署共享類庫。
  4. 序列化版本不一致 → 共享類實現 serialVersionUID 显式聲明。

現代視角:RMI 的歷史定位與替代方案

RMI 是 Java 早期分布式標準,但存在序列化效能低、防火牆穿透難、僅限 Java 生態等短板。現代架構多遷移至:

  • gRPC / Protobuf:跨語言、高效能、HTTP/2 傳輸
  • Spring Cloud / Dubbo:服務治理、負載均衡、熔斷限流
  • REST/JSON:通用性最強、防火牆友好

理解 RMI 原理有助於掌握「代理模式、序列化、命名服務、安全沙箱」等分布式核心概念,是進階微服務架構的基石。

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