兩個獨立 Java 進程 (JVM) 需要通信,除了 Socket,還有哪些方案?本地通信安全性如何?本文系統梳理 Java IPC 技術棧,對比優劣與適用場景。
| 方案 | 傳輸層 | 跨主機 | 效能 | 複雜度 | 適用場景 |
|---|---|---|---|---|---|
| Socket (TCP) | 網路 | ✅ | 高 | 中 | 分散式服務、跨語言、標準化協議 |
| HTTP/REST (HttpClient) | HTTP over TCP | ✅ | 中 (文本開銷) | 低 (成熟框架) | 微服務、Web 整合、防火牆友善 |
| Unix Domain Socket | 核心管道 (檔案系統) | ❌ 僅本機 | 極高 (無網路棧) | 中 (JNI/Netty/JEP 415) | 本機高效能微服務、Container 通信 |
| Named Pipe (Windows) | 核心管道 | ❌ 僅本機 | 高 | 中 (JNA/JNI) | Windows 本機進程通信 |
| Memory Mapped File (Mmap) | 共享記憶體 | ❌ 僅本機 | 極高 (零拷貝) | 高 (同步複雜) | 大數據交換、高頻低延遲 |
| Java Pipe (PipedInputStream) | JVM 內記憶體緩衝 | ❌ 僅同 JVM 線程 | 高 | 低 | 同進程線程間,非進程間 |
| RMI | JRMP/IIOP over TCP | ✅ | 中 (序列化開銷) | 高 (Stub/Skeleton) | 傳統 Java 分散式、EJB |
| gRPC | HTTP/2 + Protobuf | ✅ | 極高 | 中 (IDL 編譯) | 現代微服務、跨語言、強契約 |
| Message Queue (Kafka/RabbitMQ) | Broker 中轉 | ✅ | 高 (異步) | 中 | 解耦、削峰、事件驅動架構 |
tcpdump -i lo 抓包分析明文協議。serverSocket.bind(new InetSocketAddress("127.0.0.1", port)),拒絕外部介面連接。SSLServerSocket / Netty SSL,防竊聽與偽造。chmod 600,僅擁有者可讀寫,OS 層面隔離。iptables -A INPUT -i lo -p tcp --dport PORT -j ACCEPT 明確允許,其餘拒絕。需要跨主機?
├─ 是 → 需要強契約/跨語言/高效能? → gRPC
│ ├─ 簡單 REST 整合? → HTTP/REST (Spring Cloud OpenFeign / HttpClient)
│ └─ 傳統 Java 體系? → RMI (不推薦新專案)
└─ 否 (本機) → 極致效能/大數據/零拷貝? → Memory Mapped File (Chronicle Queue / Aeron)
├─ 高效能、成熟生態? → Unix Domain Socket (Netty/JDK 16+ JEP 415)
├─ Windows 環境? → Named Pipe (JNA)
└─ 簡單、開發快? → localhost Socket + TLS + Token (最通用、除錯易)
// Server
SSLServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket server = (SSLServerSocket) ssf.createServerSocket(8443);
server.setNeedClientAuth(true); // 雙向認證
server.setEnabledCipherSuites(new String[]{"TLS_AES_256_GCM_SHA384"});
// Client
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket socket = (SSLSocket) sf.createSocket("127.0.0.1", 8443);
// 通信邏輯...
憑證生成:keytool -genkeypair -alias server -keyalg RSA -keysize 2048 -keystore server.jks 等。
根據「跨主機否、效能要求、安全等級、團隊技術棧」四維度選型,避免過度設計或安全缺失。