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

RMI 與 CORBA 分散式 Java 程式設計:從理論到檔案下載實戰

     編輯:Java 相關知識

Java RMI (Remote Method Invocation) 與 CORBA (Common Object Request Broker Architecture) 是分散式物件系統的兩大支柱。本文不僅對比兩者架構特性,更以完整的「遠端檔案下載系統」為例,手把手帶你實作 RMI 分散式應用的完整生命週期。

分散式運算模型演進

傳統 Client/Server 模型

雙方協定共同通訊協定(如 HTTP GET),透過 Socket 交換訊息。缺點:協定設計複雜、緊耦合、擴充性差。

分散式物件模型

核心概念:以明確定義的介面隔離服務請求端(Client)與提供端(Server)。Client 僅持有介面參考,呼叫遠端方法如同呼叫本地方法,實作細節完全封裝。RMI 與 CORBA 皆屬此模型。

RMI 架構優勢

  • 純 Java 實作:無需學習 IDL (Interface Definition Language)
  • 物件序列化傳遞:支援任意可序列化物件跨 JVM 傳輸
  • 動態類別載入:透過 Codebase 機制自動下載 Stub/介面類別
  • 垃圾回收整合:分散式 GC 自動管理遠端物件生命週期

RMI 應用開發五步驟

  1. 定義遠端介面 (extends Remote)
  2. 實作遠端介面 (extends UnicastRemoteObject)
  3. 開發 Server 啟動與註冊邏輯
  4. 開發 Client 查找與呼叫邏輯
  5. 產生 Stub/Skeleton、啟動 Registry、部署執行

實戰專案:遠端檔案下載系統

步驟 1:定義遠端介面 FileInterface.java

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

public interface FileInterface extends Remote {
    // 遠端方法:接收檔名,回傳位元組陣列
    public byte[] downloadFile(String fileName) throws RemoteException;
}

三大鐵律:public 介面、extends Remote、所有方法 throws RemoteException

步驟 2:實作遠端介面 FileImpl.java

import java.io.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;

public class FileImpl extends UnicastRemoteObject implements FileInterface {
    private String name;

    public FileImpl(String s) throws RemoteException {
        super(); // 啟動 RMI 連結
        name = s;
    }

    public byte[] downloadFile(String fileName) {
        try {
            File file = new File(fileName);
            byte[] buffer = new byte[(int) file.length()];
            
            try (BufferedInputStream input = new BufferedInputStream(
                    new FileInputStream(fileName))) {
                input.read(buffer, 0, buffer.length);
            }
            return buffer;
        } catch (Exception e) {
            System.out.println("FileImpl: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }
}

關鍵點:繼承 UnicastRemoteObject 表示單一、不可複寫的遠端物件,使用預設 TCP 通道。

步驟 3:開發 Server FileServer.java

import java.rmi.*;

public class FileServer {
    public static void main(String[] args) {
        // 安裝安全管理員(RMI 必須)
        if (System.getSecurityManager() == null) {
            System.setSecurityManager(new RMISecurityManager());
        }
        
        try {
            FileInterface fi = new FileImpl("FileServer");
            // 註冊到 RMI Registry (預設 port 1099)
            Naming.rebind("//127.0.0.1/FileServer", fi);
            System.out.println("FileServer ready...");
        } catch (Exception e) {
            System.out.println("FileServer: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

進階配置:若 Registry 非預設埠,使用 //host:port/name 格式;跨機器部署時修改 IP 位址即可。

步驟 4:開發 Client FileClient.java

import java.io.*;
import java.rmi.*;

public class FileClient {
    public static void main(String[] args) {
        if (args.length != 2) {
            System.out.println("Usage: java FileClient fileName machineName");
            System.exit(0);
        }
        
        try {
            String name = "//" + args[1] + "/FileServer";
            FileInterface fi = (FileInterface) Naming.lookup(name);
            byte[] fileData = fi.downloadFile(args[0]);
            
            // 儲存到本地
            try (BufferedOutputStream out = new BufferedOutputStream(
                    new FileOutputStream(new File(args[0]).getName()))) {
                out.write(fileData, 0, fileData.length);
                out.flush();
            }
            System.out.println("Download complete: " + args[0]);
        } catch (Exception e) {
            System.err.println("FileClient exception: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

部署執行完整流程

1. 編譯與產生 Stub/Skeleton

javac *.java
rmic FileImpl  # 產生 FileImpl_Stub.class, FileImpl_Skel.class

2. 啟動 RMI Registry

# Windows
start rmiregistry
# 或指定埠
rmiregistry 4500

3. 準備安全策略檔 policy.txt

grant {
    permission java.security.AllPermission "", "";
};

警告:生產環境必須制定嚴格權限策略,絕不可使用 AllPermission。

4. 啟動 Server (需複製所有類別含 Stub/Skeleton)

java -Djava.security.policy=policy.txt FileServer

5. 啟動 Client (需複製介面與 Stub)

java FileClient test.txt 192.168.1.100

進階優化:RMI 動態類別載入

避免手動複製介面/Stub 類別,啟動 HTTP 伺服器托管類別檔案:

# Server 端啟動參數
java -Djava.rmi.server.codebase=https://serverhost/classes/ FileServer

# Client 端自動從 codebase 下載所需類別
java -Djava.rmi.server.codebase=https://serverhost/classes/ FileClient ...

RMI vs CORBA 核心對比

維度RMICORBA
語言綁定純 Java多語言 (IDL 映射)
介面定義Java 介面IDL
物件傳遞序列化 (Pass-by-value)VALUETYPE / 遠端參考
防火牆穿透困難 (隨機埠)IIOP 固定埠較易
效能Java 環境極佳跨語言有序列化開銷
成熟度Java 生態整合度高企業級異構系統標準

總結

RMI 以其簡潔的 Java 原生特性,成為 Java 分散式開發的首選。本文檔案下載範例完整展示了「介面定義 → 實作 → 註冊 → 查找 → 呼叫」的標準流程。掌握安全策略、Stub 產生、動態類別載入等關鍵環節,即可構建健壯的分散式 Java 系統。對於異構語言整合需求,CORBA/IIOP 則提供標準化解決方案。

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