Apache Thriftを使った作業

Apache Thriftの使用

1. 概要

この記事では、Apache Thriftと呼ばれるRPCフレームワークを使用して、クロスプラットフォームのクライアントサーバーアプリケーションを開発する方法を説明します。

私たちはカバーします:

  • IDLを使用したデータ型とサービスインターフェイスの定義

  • ライブラリのインストールと異なる言語のソースの生成

  • 定義されたインターフェースを特定の言語で実装する

  • クライアント/サーバーソフトウェアの実装

例に直接進みたい場合は、セクション5に進んでください。

2. アパッチスリフト

Apache Thriftは、もともとFacebook開発チームによって開発され、現在Apacheによって管理されています。

クロスプラットフォームオブジェクトのシリアル化/逆シリアル化プロセスを管理するProtocol Buffersと比較して、Thrift mainly focuses on the communication layer between components of your system.

Thriftは、特別なインターフェイス記述言語(IDL)を使用して、.thriftファイルとして保存され、後で異なるプログラミングを介して通信するクライアントおよびサーバーソフトウェアのソースコードを生成するためのコンパイラーによる入力として使用されるデータ型とサービスインターフェイスを定義します。言語。

プロジェクトでApache Thriftを使用するには、次のMaven依存関係を追加します。


    org.apache.thrift
    libthrift
    0.10.0

最新バージョンはMaven repositoryにあります。

3. インターフェイス記述言語

すでに説明したように、IDLを使用すると、中立的な言語で通信インターフェイスを定義できます。 以下に、現在サポートされているタイプを示します。

3.1. 基本タイプ

  • bool –ブール値(trueまたはfalse)

  • byte –8ビットの符号付き整数

  • i16 –16ビットの符号付き整数

  • i32 –32ビットの符号付き整数

  • i64 –64ビットの符号付き整数

  • double –64ビット浮動小数点数

  • string –UTF-8エンコーディングを使用してエンコードされたテキスト文字列

3.2. 特殊タイプ

  • binary –エンコードされていないバイトのシーケンス

  • optional – Java 8のOptionalタイプ

3.3. 構造体

スリフトstructsは、OOP言語のクラスと同等ですが、継承はありません。 structには、厳密に型指定されたフィールドのセットがあり、それぞれが識別子として一意の名前を持っています。 フィールドにはさまざまな注釈が付いている場合があります(数値フィールドID、オプションのデフォルト値など)。

3.4. コンテナ

リサイクルコンテナは強く型付けされたコンテナです。

  • list –要素の順序付きリスト

  • set –順序付けられていない一意の要素のセット

  • map<type1,type2> –値への厳密に一意のキーのマップ

コンテナ要素は、有効なThriftタイプであればどのようなものでもかまいません。

3.5. 例外

例外は、ネイティブ例外から継承することを除いて、機能的にstructsと同等です。

3.6. サービス内容

サービスは実際には、Thriftタイプを使用して定義された通信インターフェースです。 これらは一連の名前付き関数で構成され、各関数にはパラメーターのリストと戻り値の型があります。

4. ソースコードの生成

4.1. 言語サポート

現在サポートされている言語の長いリストがあります。

  • C++

  • C#

  • Go

  • ハスケル

  • Java

  • ジャバスクリプト

  • Node.js

  • Perl

  • PHP

  • Python

  • Ruby

完全なリストhereを確認できます。

4.2. ライブラリの実行可能ファイルの使用

latest versionをダウンロードし、必要に応じてビルドしてインストールし、次の構文を使用するだけです。

cd path/to/thrift
thrift -r --gen [LANGUAGE] [FILENAME]

上記のコマンドで、[LANGUAGE]はサポートされている言語の1つであり、[FILENAME]はIDL定義のファイルです。

-rフラグに注意してください。 指定された.thriftファイルに含まれていることに気付いたら、コードを再帰的に生成するようにThriftに指示します。

4.3. Mavenプラグインの使用

pom.xmlファイルにプラグインを追加します。


   org.apache.thrift.tools
   maven-thrift-plugin
   0.1.11
   
      path/to/thrift
   
   
      
         thrift-sources
         generate-sources
         
            compile
         
      
   

その後、次のコマンドを実行します。

mvn clean install

このプラグインにはこれ以上メンテナンスが必要ないことに注意してください。 詳細については、this pageにアクセスしてください。

5. クライアントサーバーアプリケーションの例

5.1. Thriftファイルの定義

例外と構造を含むいくつかの簡単なサービスを書いてみましょう。

namespace cpp com.example.thrift.impl
namespace java com.example.thrift.impl

exception InvalidOperationException {
    1: i32 code,
    2: string description
}

struct CrossPlatformResource {
    1: i32 id,
    2: string name,
    3: optional string salutation
}

service CrossPlatformService {

    CrossPlatformResource get(1:i32 id) throws (1:InvalidOperationException e),

    void save(1:CrossPlatformResource resource) throws (1:InvalidOperationException e),

    list  getList() throws (1:InvalidOperationException e),

    bool ping() throws (1:InvalidOperationException e)
}

ご覧のとおり、構文は非常にシンプルで、一目瞭然です。 名前空間のセット(実装言語ごと)、例外タイプ、構造体、そして最終的に異なるコンポーネント間で共有されるサービスインターフェイスを定義します。

次に、それをservice.thriftファイルとして保存します。

5.2. コードのコンパイルと生成

次に、コードを生成するコンパイラを実行します。

thrift -r -out generated --gen java /path/to/service.thrift

ご覧のとおり、生成されたファイルの出力ディレクトリを指定するために、特別なフラグ-outを追加しました。 エラーが発生しなかった場合、generatedディレクトリには次の3つのファイルが含まれます。

  • CrossPlatformResource.java

  • CrossPlatformService.java

  • InvalidOperationException.java

次のコマンドを実行して、サービスのC ++バージョンを生成しましょう。

thrift -r -out generated --gen cpp /path/to/service.thrift

これで、同じサービスインターフェイスの2つの異なる有効な実装(JavaとC ++)を取得できます。

5.3. サービス実装の追加

Thriftがほとんどの作業を行ってくれましたが、それでもCrossPlatformServiceの独自の実装を作成する必要があります。 これを行うには、CrossPlatformService.Ifaceインターフェイスを実装する必要があります。

public class CrossPlatformServiceImpl implements CrossPlatformService.Iface {

    @Override
    public CrossPlatformResource get(int id)
      throws InvalidOperationException, TException {
        return new CrossPlatformResource();
    }

    @Override
    public void save(CrossPlatformResource resource)
      throws InvalidOperationException, TException {
        saveResource();
    }

    @Override
    public List getList()
      throws InvalidOperationException, TException {
        return Collections.emptyList();
    }

    @Override
    public boolean ping() throws InvalidOperationException, TException {
        return true;
    }
}

5.4. サーバーの作成

先ほど言ったように、クロスプラットフォームのクライアントサーバーアプリケーションを構築したいので、そのためのサーバーが必要です。 Apache Thriftの素晴らしいところは、独自のクライアント/サーバー通信フレームワークがあり、通信を簡単にすることです。

public class CrossPlatformServiceServer {
    public void start() throws TTransportException {
        TServerTransport serverTransport = new TServerSocket(9090);
        server = new TSimpleServer(new TServer.Args(serverTransport)
          .processor(new CrossPlatformService.Processor<>(new CrossPlatformServiceImpl())));

        System.out.print("Starting the server... ");

        server.serve();

        System.out.println("done.");
    }

    public void stop() {
        if (server != null && server.isServing()) {
            System.out.print("Stopping the server... ");

            server.stop();

            System.out.println("done.");
        }
    }
}

まず、TServerTransportインターフェイス(より正確には抽象クラス)を実装してトランスポート層を定義します。 サーバーについて話しているので、リッスンするポートを提供する必要があります。 次に、TServerインスタンスを定義し、使用可能な実装の1つを選択する必要があります。

  • TSimpleServer –単純なサーバーの場合

  • TThreadPoolServer –マルチスレッドサーバーの場合

  • TNonblockingServer –ノンブロッキングマルチスレッドサーバー用

最後に、Thriftによって既に生成された、選択したサーバーのプロセッサ実装を提供します。 CrossPlatofformService.Processorクラス。

5.5. クライアントを書く

そして、これがクライアントの実装です。

TTransport transport = new TSocket("localhost", 9090);
transport.open();

TProtocol protocol = new TBinaryProtocol(transport);
CrossPlatformService.Client client = new CrossPlatformService.Client(protocol);

boolean result = client.ping();

transport.close();

クライアントの観点から見ると、アクションはかなり似ています。

まず、トランスポートを定義してサーバーインスタンスをポイントし、適切なプロトコルを選択します。 唯一の違いは、ここでは、Thriftによって既に生成されたクライアントインスタンスを初期化することです。 CrossPlatformService.Clientクラス。

.thriftファイル定義に基づいているため、そこで説明されているメソッドを直接呼び出すことができます。 この特定の例では、client.ping()はサーバーにリモート呼び出しを行い、サーバーはtrueで応答します。

6. 結論

この記事では、Apache Thriftを使用する際の基本的な概念と手順を示し、Thriftライブラリを利用する実用的な例を作成する方法を示しました。

いつものように、すべての例は常にthe GitHub repositoryにあります。