Apache Thrift - 跨語言相容性



Thrift 中的跨語言相容性

Apache Thrift 旨在實現跨語言相容性,使不同程式語言編寫的服務之間能夠無縫通訊。

Apache Thrift 提供了一個框架,用於以與語言無關的方式定義資料型別和服務介面。然後,它會生成多種程式語言的程式碼,從而允許用不同語言編寫的服務有效地通訊。

此功能對於構建分散式系統非常重要,在分散式系統中,不同的元件可能使用不同的語言實現。

定義 Thrift IDL

Thrift IDL 允許您以與語言無關的方式定義資料型別和服務方法。然後,此定義用於在各種程式語言中生成程式碼。

示例

在以下示例中,定義了“User”結構體和“UserService”服務。Thrift IDL 對這些定義進行了抽象,以便它們可以在不同的語言中實現 -

namespace py example

struct User {
  1: string username,
  2: i32 age
}
service UserService {
  User getUser(1: string username),
  void updateUser(1: User user)
}

為不同的語言生成程式碼

Thrift 工具可以從 IDL 檔案生成各種語言的原始碼。此過程確保資料結構和服務方法在不同語言之間保持一致。以下是生成程式碼的步驟 -

  • 定義您的 IDL 檔案:建立一個“.thrift”檔案,其中包含您的資料結構和服務定義。
  • 為目標語言生成程式碼:使用 Thrift 編譯器以所需的語言生成原始碼。
  • 實現和使用生成的程式碼:在生成的類中實現服務邏輯,並在您的應用程式中使用它們。

生成 Python 程式碼

要生成 Python 程式碼,請使用帶有--gen選項的 Thrift 編譯器。此命令將建立一個 Python 模組,其中包含基於 IDL 定義的類和方法 -

thrift --gen py service.thrift

生成 Java 程式碼

同樣,您可以使用--gen選項生成 Java 程式碼。此命令將建立一個 Java 包,其中包含基於 IDL 定義的類和方法 -

thrift --gen java service.thrift

在不同的語言中實現服務

使用生成的程式碼,您現在可以在不同的語言中實現服務。我們將逐步介紹如何在 Python 和 Java 中實現ExampleService

Python 實現

以下是使用 Python 實現“ExampleService”的分步說明 -

匯入必要的模組

  • TServer:用於設定伺服器。
  • TSocket, TTransport:用於處理網路通訊。
  • TBinaryProtocol:用於資料序列化。
  • ExampleService:生成的 service 介面。

定義服務處理程式

  • 建立一個類“ExampleServiceHandler”,該類實現“ExampleService.Iface”介面。
  • 實現“sayHello”方法以列印問候訊息。

設定伺服器

  • 為處理程式和處理器建立例項。
  • 使用“TSocket.TServerSocket”在埠 9090 上設定傳輸。
  • 使用緩衝傳輸和二進位制協議進行通訊。
  • 使用傳輸、協議和處理程式初始化伺服器。

啟動伺服器

  • 列印一條訊息,指示伺服器正在啟動。
  • 呼叫“server.serve()”開始偵聽客戶端請求。
from thrift.server import TServer
from thrift.transport import TSocket, TTransport
from thrift.protocol import TBinaryProtocol
from example import ExampleService

class ExampleServiceHandler(ExampleService.Iface):
   def sayHello(self, person):
      print(f"Hello {person.name}, age {person.age}")

handler = ExampleServiceHandler()
processor = ExampleService.Processor(handler)
transport = TSocket.TServerSocket(port=9090)
tfactory = TTransport.TBufferedTransportFactory()
pfactory = TBinaryProtocol.TBinaryProtocolFactory()

server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
print("Starting the Python server...")
server.serve()

在此示例中,我們在 Python 中設定了一個簡單的 Thrift 伺服器,該伺服器偵聽埠 9090。“ExampleServiceHandler”透過實現“sayHello”方法處理傳入的請求。

Java 實現

同樣,這裡我們在 Java 中設定了一個簡單的 Thrift 伺服器,該伺服器偵聽埠 9090。“ExampleServiceHandler”透過實現“sayHello”方法處理傳入的請求 -

import example.ExampleService;
import example.Person;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TServerTransport;

public class ExampleServiceHandler implements ExampleService.Iface {
   @Override
   public void sayHello(Person person) throws TException {
      System.out.println("Hello " + person.getName() + ", age " + person.getAge());
   }

   public static void main(String[] args) {
      try {
         ExampleServiceHandler handler = new ExampleServiceHandler();
         ExampleService.Processor<ExampleServiceHandler> processor = new ExampleService.Processor<>(handler);
         TServerTransport serverTransport = new TServerSocket(9090);
         TBinaryProtocol.Factory protocolFactory = new TBinaryProtocol.Factory();
         TSimpleServer server = new TSimpleServer(new TServer.Args(serverTransport).processor(processor).protocolFactory(protocolFactory));
         System.out.println("Starting the Java server...");
         server.serve();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

跨語言通訊

使用以不同語言實現的服務,您現在可以測試跨語言通訊。這意味著您可以使用一種語言編寫的客戶端與另一種語言編寫的伺服器通訊。以下是其工作原理 -

  • Python 客戶端呼叫 Java 服務:編寫一個與 Java 伺服器通訊的 Python 客戶端。
  • Java 客戶端呼叫 Python 服務:編寫一個與 Python 伺服器通訊的 Java 客戶端。

示例:Python 客戶端

以下是一個 Python 客戶端,它連線到在 Java 伺服器上執行的 Thrift 服務 -

from thrift.transport import TSocket, TTransport
from thrift.protocol import TBinaryProtocol
from example import ExampleService

transport = TSocket.TSocket('localhost', 9090)
transport = TTransport.TBufferedTransport(transport)
protocol = TBinaryProtocol.TBinaryProtocol(transport)
client = ExampleService.Client(protocol)

transport.open()
person = ExampleService.Person(name="Alice", age=30)
client.sayHello(person)
transport.close()

示例:Java 客戶端

同樣,我們編寫一個 Java 客戶端,它與在 Python 伺服器上執行的 Thrift 服務通訊 -

import example.ExampleService;
import example.Person;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;

public class ExampleClient {
   public static void main(String[] args) {
      try {
         TTransport transport = new TSocket("localhost", 9090);
         TBinaryProtocol protocol = new TBinaryProtocol(transport);
         ExampleService.Client client = new ExampleService.Client(protocol);
         transport.open();
         Person person = new Person("Bob", 25);
         client.sayHello(person);
         transport.close();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}
廣告

© . All rights reserved.