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

RPC 核心原理深度剖析(一):從 TCP Socket 到序列化,手寫 HSF/Dubbo 雛形

     編輯:Java 綜合教學

RPC 核心原理深度剖析系列(一)

在大型系統演進中,業務拆分為多個子系統(用戶、交易、商品等)勢在必行。早期各子系統采用 Hessian、WebService、Socket、HTTP 等異構協議互調,導致整合困難、超時/加密/參數傳遞等問題頻發。高性能 RPC 中間件(HSF、Dubbo)應運而生。本文從零開始,通過代碼實現最簡單的 RPC 調用雛形。

為什麼選擇 TCP 作為傳輸協議?

HTTP 位於應用層(第 7 層),TCP 位於傳輸層(第 4 層)。越靠近底層,協議開銷越小,傳輸效率越高。RPC 追求極致性能,直接基于 TCP 構建自定義協議是標準選擇。

階段一:阻塞式 Socket 通信(BIO)

服務端

public class SocketServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(9999);
        while (true) {
            Socket socket = serverSocket.accept(); // 阻塞等待連接
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
            String line = in.readLine(); // 阻塞讀取
            System.out.println("收到: " + line);
            out.println("Echo: " + line);
            in.close(); out.close(); socket.close();
        }
    }
}

客戶端

public class SocketClient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1", 9999);
        PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
        out.println(console.readLine());
        System.out.println("服務端回應: " + in.readLine());
        console.close(); in.close(); out.close(); socket.close();
    }
}

痛點:accept()、read() 均為阻塞。併發多客戶端需為每個連接創建線程,線程開銷大,易導致服務器崩潰。

階段二:對象傳輸與 Java 序列化

實際業務傳輸的是領域對象而非字符串。需實現 Serializable 接口,使用 ObjectOutputStream/ObjectInputStream 進行序列化/反序列化。

public class Student implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name; private int age;
    // 構造器、toString 省略
}

服務端用 ObjectInputStream.readObject() 接收,客戶端用 ObjectOutputStream.writeObject() 發送。測試成功輸出:Server: name=chengwei.lcw, age=28。

局限:Java 原生序列化體積大、速度慢、不支持跨語言。生產環境通常采用 Hessian、Protobuf、Kryo 等高性能序列化框架。

下一步演進方向

  • NIO 非阻塞 I/O:JDK 1.4+ 引入,單線程處理海量連接。Netty 是基于 NIO 的工業級封裝,修復了 JDK NIO 的空輪詢 Bug 等缺陷。
  • 協議設計:定義魔數、版本號、序列化類型、消息長度、消息體等自定義協議格式。
  • 服務發現與註冊中心:Zookeeper/Nacos 管理服務元數據。
  • 負載均衡、容錯、超時重試:完善 RPC 治理能力。

本系列將逐步拆解上述核心模塊,敬請期待後續文章。

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