アルバムの概要
proto3
etcd v3の通信はgRPCをベースにしており、プロトファイルはサーバとクライアント間の通信インタフェースを定義する標準です。プロトファイルとは、サーバとクライアント間の通信インタフェース、つまり、クライアントからどのようなパラメータを渡すべきか、サーバからどのようなパラメータを返すべきか、クライアントから何を呼び出すべきか、ブロッキングかノンブロッキングか、同期か非同期かを定義する規格です。コアAPIの学習では、gRPCはproto3の使用を推奨し、proto3の基本的な構文の予備的な理解を持っている必要があります。proto3は、機能の削除された部分のアップグレード版の元のプロトコルバッファ2(proto2として知られている)、モバイルデバイスに最適化されたサポートは、アンドロイドとiOSのサポートを追加することに加えて、gRPCが正常に使用できるようにします。また、gRPCが問題なくモバイルデバイス上で使用できるように、アンドロイドとiOSのためのサポートを追加します。
Protocol Buffer
プロトコルバッファは、構造化データをシリアライズするための柔軟で効率的な自動メカニズムです。いったんデータの構造化方法を定義すれば、特別に生成されたソースコードを使用して、さまざまな言語で、さまざまなデータストリームで、構造化データを簡単に書いたり読んだりすることができます。レガシー」フォーマットでコンパイルされたプログラムを壊すことなく、定義されたデータ構造を更新することも可能です。
メッセージタイプの定義
まず、非常に単純な例を見てみましょう。検索リクエストメッセージを定義し、それぞれにクエリ文字列、興味のある特定のページ番号、各ページのヒット数を含める必要があるとします。
syntax = "proto3";
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}
- 検索要求メッセージ構造には、定義によって指定された3つのフィールドがあることを確認してください。各フィールドには名前と型があります。
フィールドタイプの指定
上記の例では、すべてのフィールドが値型です。しかし、フィールドには列挙型やその他のメッセージ・タイプなど、さまざまな型の組み合わせを指定することもできます。
識別子の割り当て - タグ
メッセージの各フィールドには一意な数値の識別子があります。これらの識別子は、メッセージのバイナリ・フォーマットでフィールドを識別するために使用され、一度メッセージが使用されると、これらの識別子は変更されるべきではありません。
識別番号は、識別番号とフィールドタイプを含めて1バイトで1から15までエンコードされることに注意してください。
識別子 16 から 2047 までは 2 バイト必要です。ですから、1 から 15 までは最も頻繁に出現するメッセージ・タイプのために確保 しておくべきです。つまり、1 から 15 を一度に使い切らずに、将来のために少し残しておくのです。
また、19000から19999までの数字は、プロトコルバッファで使用するために予約されているため、使用することができません。もし、自分の.protoファイルで予約された数字を使用すると、プロトコルバッファコンパイラからプロンプトが表示されます。自分の .proto ファイルで予約番号を使用すると、プロトコルバッファコンパイラがプロンプトを出します。同様に、予約された識別子を使用することはできません。
フィールドルールの指定
メッセージ・フィールドには以下のいずれかを指定します:
- singular:文法的に正しいメッセージには、これらのフィールドがゼロか1つ含まれています。
- repeated: フィールドは正規のメッセージの中で一定回数繰り返すことができます。繰り返される値の順序は保持されます。proto3では、繰り返し値型のフィールドはデフォルトで圧縮符号化されます。
メッセージタイプの追加
複数のメッセージタイプを一つの .proto ファイルで定義することができます。これは、複数の関連メッセージを定義する場合に便利です。例えば、検索メッセージ・タイプの応答メッセージ・フォーマットを定義したい場合、同じ.protoファイルに以下を追加することができます:
message SearchRequest {
string query = 1;
int32 page_number = 2;
int32 result_per_page = 3;
}
message SearchResponse {
...
}
message SearchRequest {
string query = 1;
int32 page_number = 2; // Which page number do we want?
int32 result_per_page = 3; // Number of results to return per page.
}
予約フィールド
message Foo {
reserved 2, 15, 9 to 11;
reserved "foo", "bar";
}
同じ予約文の中でフィールド名と識別子を混同しないように注意してください。
値の種類
この表は、.proto ファイルで使用できる型と、対応する言語用に自動生成される型を示したものです:
proto コンパイル方法
.proto ファイルがコンパイルされると、コンパイラは選択した言語用のコードを 生成します。フィールドの値の取得や設定、出力ストリームへのメッセージの直列化、入力ストリームからのメッセージの変換など、ファイルに記述するメッセージの種類を指定します。
- C++ の場合、コンパイラは .proto ファイルごとに .h ファイルと .cc ファイルを 1 つずつ生成し、指定されたメッセージ・タイプごとに 1 つのクラスを生成します。
- Java の場合、コンパイラは各メッセージ・タイプのクラスと、それらのメッ セージ・クラスのインスタンスを作成するための特別な Builder クラスを含む java ファイルを生成します。
- Python コンパイラは、各メッセージタイプの静的記述子を生成するモジュールを生成し、このモジュールは実行時にメタクラスとともに使用され、必要な Python データアクセスクラスを作成します。
- Goの場合、コンパイラーはメッセージ・タイプごとに.pb.goファイルを生成します。
概要
全ての etcd3 API は gRPC サービスで定義されており、etcd サーバが理解できるリモートプロシージャコールを分類しています。この記事では、proto3定義の概念を紹介し、gRPCインターフェースについて学ぶために必要な知識を提供します。次回は etcd3 のコアとなる gRPC API インターフェースについて紹介します。