Thrift は、スケーラブルな言語間サービスを開発するために使用されるソフトウェア フレームワーク (リモート プロシージャ コール フレームワーク) であり、データ送信形式 (バイナリ、json) とネットワーク通信のサービス フレームワークをカプセル化し、多言語 (C++、Web) を提供します。 Java、Python、PHP、Ruby、Erlang、Perl、Haskell、C#、Cocoa、JavaScript、Node.js、Smalltalk、OCaml のサーバーおよびクライアント プログラム コンポーネント
大規模なデータ交換およびストレージ ツールの構築に適しています。内部向け大規模システムでのデータ送信では、パフォーマンスと送信サイズの点で JSON や XML よりも明らかな利点があります。この記事では、チュートリアルとして登録サービス インターフェイスとログイン サーバー インターフェイスを使用します。
Thrift によって開発されたいくつかの概念:
サーバー サービス モデル
ハンドラー データ処理インターフェイス
プロセッサ データ処理オブジェクト
プロトコル データ送信プロトコル
トランスポートデータ 送信方法
(1) サポートされる送信形式
TCompactProtocol ? 圧縮形式
TSimpleJSONProtocol ?書き込み専用プロトコル、生成されたファイルは簡単にスクリプト化されます言語解析。
TDebugProtocol ? デバッグを容易にするために、理解しやすく読みやすいテキスト形式を使用します
(2) サポートされる通信方式 (データ送信メソッド) (Transport)
TFileTransport: クライアントが許可するファイル (ログ) 送信クラスto ファイルがサーバーに渡され、サーバーは受信したデータをファイルに書き込むことができます。
THttpTransport: データ送信に Http 送信プロトコルを使用します
TSocket: データ送信に TCP Socket を使用します
TZlibTransport: データを圧縮して送信、または受信したデータを解凍します
主に次のカテゴリが対象です 上記のクラスは装飾されています(デコレーションモード使用)伝送効率を向上させます。
TBufferedTransport: Transport オブジェクトによって操作されるデータをバッファリングします。つまり、送信のためにバッファーからデータを読み取るか、データをバッファーに直接書き込みます。
TFramesTransport: フレーム単位で送信し、ノンブロッキング サービスで使用されます。 TBufferedTransport と同様に、関連データもバッファリングされます。同時に、固定長データの送受信もサポートされます。
TMemoryBuffer: バッファーからのデータの読み取りと書き込み
(3) サポートされているサービス モデル
TSimpleServer ? テストによく使用されるシンプルなシングルスレッド サービス モデル
TThreadedServer - マルチスレッド サービス モデル、ブロッキング IO を使用、リクエストごとに 1 つのスレッドが作成されます。
TThreadPoolServer? スレッド プール サービス モデルは、標準のブロッキング IO を使用して、リクエストを処理するために事前にスレッドのグループを作成します。
TNonblockingServer ? ノンブロッキング IO を使用するマルチスレッド サービス モデル (TframedTransport データ送信メソッドが必要)
大量の更新を処理する必要がある場合は、主に TThreadedServer と TOnblockingServer のどちらかを選択します。 TNonblockingServer は少数のスレッドを使用して多数の同時接続を処理できますが、待ち時間は TThreadedServer の方が低くなります。実際には、TThreadedServer のスループットは TOnblockingServer のスループットよりも高い場合がありますが、TThreadedServer の CPU 使用率は TOnblockingServer のスループットよりもはるかに高くなります。
サーバー側の書き込みの一般的な手順:
1. ハンドラーを作成する
2. ハンドラーに基づいてプロセッサを作成する
5. プロセッサー、トランスポート、およびプロトコルに基づいてサーバー
を作成します。トランスポートとプロトコルはクライアントを作成します
4. クライアントを実行する方法
上記の要約内容は以下から参照されています
正式なコードチュートリアルは以下から始まります
サービス記述ファイルtest.thriftはログインサービスと登録を定義します
/** * The first thing to know about are types. The available types in Thrift are: * * bool Boolean, one byte * byte Signed byte * i16 Signed 16-bit integer * i32 Signed 32-bit integer * i64 Signed 64-bit integer * double 64-bit floating point value * string String * binary Blob (byte array) * map<t1,t2> Map from one type to another * list<t1> Ordered list of one type * set<t1> Set of unique elements of one type * * Did you also notice that Thrift supports C style comments? */namespace java com.penngonamespace php com.penngostruct User { 1: i64 id, 2: string name, 3: string password}service LoginService{ User login(1:string name, 2:string psw);} service RegisterService{ User createUser(1:string name, 2:string psw);}
thrift を使用して、対応するプラットフォーム言語コードを生成します
thrift -gen java test.thrift
thrift -gen php test.thrift
php がサーバー側を生成する必要がある場合、要件は thrift -gen php:server test に変更されます.thrift
java
LoginServiceImpl.java ログイン インターフェイス ビジネスの実装
import org.apache.thrift.TException;public class LoginServiceImpl implements LoginService.Iface{ public LoginServiceImpl(){ } public User login(String name, String psw) throws TException{ User user = null; if(name.equals("penngo") && psw.equals("123")){ user = new User(); user.setId(1); user.setName("penngo"); } return user; }}
RegisterServiceImpl.java 登録インターフェイス ビジネスの実装
import org.apache.thrift.TException;public class RegisterServiceImpl implements RegisterService.Iface{ public RegisterServiceImpl(){ } public User createUser(String name, String psw) throws TException{ User user = new User(); user.setId(2); user.setName(name); user.setPassword(psw); return user; }}
サーバー側 Java コード
package com.penngo.main;import org.apache.thrift.TMultiplexedProcessor;import org.apache.thrift.server.TServer;import org.apache.thrift.server.TThreadPoolServer;import org.apache.thrift.transport.TServerSocket;import org.apache.thrift.transport.TTransportException;import com.penngo.LoginService;import com.penngo.LoginServiceImpl;import com.penngo.RegisterService;import com.penngo.RegisterServiceImpl;public class Server { private void start() { try { TServerSocket serverTransport = new TServerSocket(7911); // 用户登录 LoginService.Processor loginProcessor = new LoginService.Processor( new LoginServiceImpl()); // 用户注册 RegisterService.Processor registerProcessor = new RegisterService.Processor( new RegisterServiceImpl()); // Factory protFactory = new TBinaryProtocol.Factory(true, true); // TServer server = new TThreadPoolServer(new // TThreadPoolServer.Args(serverTransport) // .processor(loginProcessor)); TMultiplexedProcessor processor = new TMultiplexedProcessor(); processor.registerProcessor("LoginService", loginProcessor); processor.registerProcessor("RegisterService", registerProcessor); TServer server = new TThreadPoolServer(new TThreadPoolServer.Args( serverTransport).processor(processor)); System.out.println("Starting server on port 7911 ..."); server.serve(); } catch (TTransportException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String args[]) { Server srv = new Server(); srv.start(); }}
クライアント サイド java
package com.penngo.main;import org.apache.thrift.*;import org.apache.thrift.protocol.*;import org.apache.thrift.transport.*;import com.penngo.LoginService;import com.penngo.RegisterService;import com.penngo.User;public class Client { public static void main(String[] args) { try { TTransport transport = new TSocket("localhost", 7911); TProtocol protocol = new TBinaryProtocol(transport); TMultiplexedProtocol mp1 = new TMultiplexedProtocol(protocol, "LoginService"); // TProtocol protocol = new TBinaryProtocol(transport); // LoginService.Client client = new LoginService.Client(protocol); LoginService.Client loginClient = new LoginService.Client(mp1); TMultiplexedProtocol mp2 = new TMultiplexedProtocol(protocol, "RegisterService"); RegisterService.Client registerClient = new RegisterService.Client( mp2); transport.open(); User user = loginClient.login("penngo", "123"); if (user != null) { System.out.println("登录成功:" + user.getId() + " " + user.getName()); } else { System.out.println("登录失败"); } User user2 = registerClient.createUser("test", "123"); if (user2 != null) { System.out.println("创建用户成功:" + user2.getId() + " " + user2.getName()); } else { System.out.println("创建用户失败"); } transport.close(); } catch (TException x) { x.printStackTrace(); } }}
rreee