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

基於 Thrift 的輕量級 Java RPC 框架設計與實踐

     編輯:Java 綜合教學

前言:為什麼要造輪子?

在微服務架構盛行的今天,RPC 框架早已不是新鮮事物。Dubbo、gRPC、Spring Cloud 等成熟方案琳瑯滿目,但並非所有場景都需要重型武器。本文分享一個基於 Apache Thrift 自研的輕量級 Java RPC 框架 —— java-rpc-thrift,它專為中小型集群(50 節點以內)設計,追求極致簡單、高性能、低依賴,適合不想引入 Zookeeper 等重組件、又想擺脫 HTTP/REST 性能瓶頸的團隊。

專案背景與痛點

故事始於一次系統模塊拆分:原有單體應用需抽離服務,尋找遠程調用方案時發現兩難:

  • HTTP/REST/WebService:組裝請求繁瑣、難以規範、高並發性能差,直接 Pass。
  • 原生 Thrift:雖性能優異,但開發體驗極差 —— 頻繁生成代碼、需自行實現連接池/負載均衡/容錯、服務端業務邏輯強綁定單一接口(一接口佔一線程池),維護成本高,同樣 Pass。

核心需求很明確:簡單、依賴少、高性能、高並發、支持集群/負載均衡/容錯、零學習成本、源碼可定制。既然市面上沒有完美契合的,那就自己寫一個。

架構設計亮點

核心原理:透明代理 + 序列化傳輸

框架在 Client 端為服務接口生成動態代理,方法調用自動轉為遠程請求:參數經 Kryo 序列化 → Thrift 協議傳輸 → Server 端反序列化執行業務邏輯 → 結果原路返回。對業務代碼完全透明,體驗如同本地調用。

技術選型理由

組件選型理由
網絡層Apache Thrift利用其成熟的 Server 模型(ThreadPool/ThreadedSelector)支撐高並發低延遲;代碼極輕量,僅是 Socket 封裝,性能接近原生 Socket,比 Netty 更適合同步 RPC 調用
序列化Kryo序列化體積小、速度極快,可換裝其他實現
連接池Commons Pool成熟穩定,支援最大/最小閒置、等待超時、存活時間等精細控制
配置管理Spring Beans複用 Spring 容器生命周期,XML 配置直觀

集群與容錯能力

  • 負載均衡:內置隨機、輪詢策略,支援自定義擴展
  • 優雅停機:kill PID(非 -9)觸發關閉鉤子,等待進行中請求完成
  • 故障隔離:心跳檢測 + 連接池狀態管理,單節點故障不影響整體服務

實戰:五分鐘接入指南

服務端配置

<bean id="servicePublisher" class="com.appchina.rpc.thrift.remote.base.ThriftServicePublisher">
  <property name="definitions">
    <array>
      <bean class="com.appchina.rpc.remote.ServiceDefinition">
        <property name="serviceName" value="addServiceImpl"/>
        <property name="interfaceClass" value="com.appchina.rpc.test.api.AddService"/>
        <property name="implInstance">
          <bean class="com.appchina.rpc.test.impl.AddServiceImpl"/>
        </property>
      </bean>
    </array>
  </property>
</bean>

<bean class="com.appchina.rpc.thrift.server.ThriftThreadPoolServer">
  <property name="processor" ref="servicePublisher"/>
  <property name="port" value="9090"/>
  <property name="minWorkerThreads" value="100"/>
  <property name="workerThreads" value="500"/>
  <property name="security" value="true"/>
  <property name="stopTimeoutVal" value="3000"/>
  <property name="clientTimeout" value="10000"/>
  <property name="allowedFromTokens">
    <map>
      <entry key="DONGJIAN" value="DSIksduiKIOYUIOkYIOhIOUIOhjklYUI"/>
    </map>
  </property>
</bean>

啟動類僅需加載 Spring 上下文並註冊關閉鉤子:

ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("/application-server.xml");
ctx.registerShutdownHook();
ctx.start();

客戶端配置

<bean id="factoryProvider" class="com.appchina.rpc.thrift.cluster.ThriftClientFactoryProvider">
  <property name="hostPorts">
    <list>
      <value>127.0.0.1:9090</value>
      <value>127.0.0.1:9191</value>
    </list>
  </property>
  <property name="timeout" value="60000"/>
  <property name="connectionTimeout" value="10000"/>
  <property name="framed" value="false"/>
  <property name="from" value="DONGJIAN"/>
  <property name="token" value="DSIksduiKIOYUIOkYIOhIOUIOhjklYUI"/>
</bean>

<bean id="client" class="com.appchina.rpc.base.cluster.client.DistributeClient">
  <property name="factoryProvider" ref="factoryProvider"/>
  <property name="loadBalance">
    <bean class="com.appchina.rpc.base.cluster.RoundrobinLoadBalance"/>
  </property>
  <property name="heartbeat" value="1000"/>
  <property name="maxHeartbeatThread" value="1"/>
  <property name="retry" value="3"/>
  <property name="maxActive" value="300"/>
  <property name="maxIdle" value="200"/>
  <property name="minIdle" value="5"/>
  <property name="maxWait" value="1000"/>
  <property name="maxKeepMillis" value="-1"/>
  <property name="maxSendCount" value="-1"/>
</bean>

<bean id="addService" class="com.appchina.rpc.thrift.remote.base.ThriftRemoteProxyFactory">
  <property name="serviceName" value="addService"/>
  <property name="proxyInterface" value="com.appchina.rpc.test.api.AddService"/>
  <property name="client" ref="client"/>
</bean>

業務調用極簡:

ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("/application-client.xml");
AddService addService = (AddService) ctx.getBean("addService");
addService.add(100); // 透明遠程調用

項目地址與避坑指南

🔗 GitHub:https://github.com/dongjian1029/java-rpc-thrift.git

適用場景:節點數 < 50、追求極致輕量、團隊有能力維護源碼、不需要服務治理儀表盤。
不適用場景:大規模集群、需服務發現/熔斷/鏈路追蹤、團隊偏好開箱即用成熟框架(請直接用 Dubbo)。

總結

造輪子不是為了炫技,而是為了在特定約束下找到最優解。java-rpc-thrift 證明了:拒絕過度設計,專注核心價值,小而美同樣有力量。若你正為 RPC 選型糾結,不妨克隆源碼跑通 Demo,或許它就是你要的那把「輕劍」。

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