Open18

RPCとかgRPCとかConnectとか

axpensiveaxpensive

Buf Technologies, Inc

Connect webを作っている会社。
Protocol BuffersのlinterやCLIツールを開発している。
Protocol Buffersに特化している理由はよくわからない。(儲かるのか?)

axpensiveaxpensive

Protocol Buffers

Protocol Buffers are a language-neutral, platform-neutral extensible mechanism for serializing structured data.

Googleが開発したデータシリアライズのためのプラットフォーム中立的なオープンソース形式のこと。
JSONのようなデータフォーマットで様々なプログラミング言語で使える。
ProtobufはProtocol Buffersの略。

axpensiveaxpensive

proto2やproto3

Protobufのバージョンを意味する。
proto2とproto3は破壊的ではないが互換性がない感じがする。
個人的には必須フィールドが使えないのがきつい。

  • フィールド プレゼンス(hasField)は、プリミティブ フィールドに対してはデフォルトで削除されます。設定されていないプリミティブ フィールドには、言語が定義されたデフォルト値が含まれます。
    • メッセージ フィールドのプレゼンスは引き続き使用できます。このフィールドは、コンパイラによって生成された hasField メソッドを使用したり、null や実装によって定義された標識値と比較したりして、テストすることができます。
    • protobuf v3.14 以降、プリミティブ フィールドは optional キーワードを使用してデフォルト値と設定されていない値を区別できますが、これは一般には推奨されていません。
  • フィールドのユーザー定義デフォルト値は使用できなくなりました。
  • 列挙型の定義は、列挙値 0 から開始する必要があります。
  • 必須フィールドは使用できなくなりました。
  • 拡張機能は使用できなくなりました。google.protobuf.Any を代わりに使用してください。
    • 下位互換性やランタイム互換性の理由から、google/protobuf/descriptor.proto には特別な例外が認められています。
  • グループ構文は削除されます。

https://cloud.google.com/apis/design/proto3?hl=ja

axpensiveaxpensive

RPC

RPC(Remote Procedure Call)とは、ネットワーク上で接続されたほかのコンピュータのプログラムを呼び出して実行させるための技術、またはそのためのプロトコルのことです。RPCは日本語で「遠隔手続き呼び出し」と訳されます。

https://www.ntt-west.co.jp/business/glossary/words-00229.html#:~:text=RPC(Remote Procedure Call)と,呼び出し」と訳されます。

インターネットが普及する古くからある考え方。
ローカルマシン上で関数を呼び出すかのように、リモートマシン上の関数を呼び出すことができる。
RESTのようにHTTPメソッドを切り替える必要がなく、POSTだけしかつかえない。世の中的にはシンプルと肯定的に捉える。

axpensiveaxpensive

gRPC

Googleが作ったRPCのフレームワーク。
RPCの一種。
https://learn.microsoft.com/en-us/aspnet/core/grpc/comparison?view=aspnetcore-7.0#grpc-strengths

JSONを使ったHTTP APIと比較したgRPCの強み

  • パーフォーマンス

    • 効率的なバイナリメッセージ形式であるProtobufを使用してシリアル化されたメッセージを扱うので、高速なシリアル化・デシリアル化が可能。
      • 高速なシリアル化・デシリアル化できる理由は、テキストデータは人が読める文字列に変換する必要があるのでエンコーディング、デコーディングの工程が発生するがバイナリデータではそういった工程は発生しない。なのでバイナリデータは読み書きが早い。
    • HTTP/2プロトコルを使うことで少ない通信量で高速なやりとりができる。
  • コード生成

    • protoファイルによりAPI仕様を定義しクライアント、サーバーサイドのコードを自動生成できる。
    • protoファイルはJSONと違って型を指定できるので型安全。
  • 厳密な仕様

  • ストリーミング

    • HTTP1では1つのリクエストが完了するまで次のリクエストを送れませんでした。
  • 締め切り/タイムアウトとキャンセル

https://blog.redbox.ne.jp/http2-cdn.html

axpensiveaxpensive

RPCとgRPCの違い

  • HTTP/2
    • 通信が高速。
  • Protocol Buffers
    • JSONと違ってプレーンテキストではなくバイナリでデータを渡すので
    • データ型
      • enumやマップ型が使える。
axpensiveaxpensive

HTTP/1.1とHTTP/2の違い

  • HTTP/1.1
    • 1つのリクエストが完了するまで、原則次のリクエストを送ることができない。
    • 同時にリクエストを送信するため複数同時接続で解決していたが、ブラウザには同時にリクエストできる上限が決まっている。(Chromeだと6回)6回分のリクエスト処理に時間がかかると他のリクエストが送れなくなる問題が発生していた。
    • HTTPパイプラインという仕組みを使ってリクエストの完了を待たないことができたが、技術的に扱いにくいので使われなくなった。(HoLブロッキング)
    • リクエスト数を増やし(複数ドメインで処理する)、リクエストする数を減らすこと(ファイルをまとめる、キャッシュの利用など)でしか高速化できない。
  • HTTP/2
    • HTTP/1.1と違って1つのコネクションで並列処理ができる。リクエストの完了を待たなくていい。
    • ~ストリームの優先度を設定できる。~ 廃止された模様。
    • ヘッダー圧縮。一度送信したヘッダーは送信せずに差分だけ送信する。

https://zenn.dev/hsaki/books/golang-grpc-starting/viewer/stream

axpensiveaxpensive

Connectが作られた背景
https://buf.build/blog/connect-a-better-grpc

  • Excluding comments, grpc-go is 130 thousand lines of hand-written code. It has dozens of subpackages, nearly a hundred configuration options, and bespoke name resolution and load balancing mechanisms. Just sifting through the kitchen sink of features takes hours, and the sheer quantity of code makes subtle bugs and resource leaks inevitable.
  • Rather than using the Go standard library's net/http, grpc-go uses its own implementation of HTTP/2. It's incompatible with the rest of Go's HTTP ecosystem, so you can't cleanly serve gRPC requests alongside other HTTP traffic and can't use most third-party packages.
  • The gRPC protocol requires end-to-end support for HTTP/2 and trailers. Supporting common HTTP clients — like web browsers — requires elaborate translating proxies.
  • In addition to using obscure HTTP features, the gRPC protocol is difficult to debug. Even with JSON support enabled, simple request-response RPCs mix the JSON you care about with binary framing data. Forget curl | jq or the Chrome network inspector — the available tools are all immature and gRPC-specific.
  • As a policy, grpc-go doesn't follow semantic versioning; the release notes even include a special section for "Behavior Changes." At least four releases in the past year have broken backward compatibility, and prominent gRPC users (including etcd) are often unable to update for months at a time.

gRPCに不満があって作られた。

  • ソースコードが大きい。
  • 独自のHTTP/2を実装していて、Goの標準機能やライブラリが使えない
  • プロキシが必要
  • デバッグが難しい
  • 互換性がない
    Connectではこれらの不満を解消された。
axpensiveaxpensive

connect-goとかconnect-kotlinがなんなのか

Connectをプログラミング言語ごとに使用できるようにしたライブラリ。
GolangでConnect使いたいならconnect-goを使う。

axpensiveaxpensive

connect-Webとは

WebブラウザからRPCを呼び出すためのライブラリ。
connect-goはサーバーサイドのライブラリであるのに対しconnect-Webはフロントエンドのライブラリ。

axpensiveaxpensive

gRPC, Connectを導入した場合の開発手順。

  1. APIの仕様を決める。
  2. protoファイルにAPIを定義し、buf generateする。
  3. バックエンドはprotoファイルから生成されたAPIのリクエスト、レスポンスのインターフェースに従って開発をする。
  4. フロントエンドは共有されたprotoファイルからmockを作成し開発を進める。
  5. APIできたら結合テストをする。
  6. 完成。
axpensiveaxpensive

gRPCとConnectの違い

どちらもRPCのフレームワーク。
RPCを実現するための使うが、開発効率を上げるライブラリやツールが入ってる。
ConnectはA better gRPCと書いている。

axpensiveaxpensive

Connectの特徴

使いにくいgRPCの欠点を克服したものになっている

  • コード量を少なくする。1つのパッケージで完結させる。
  • Go標準のnet/httpを使っているのでConnectを導入してもGoのライブラリは使える。
  • net/httpを使っているのにRPC, gRPC-Web, Connect(Connectの独自プロトコル)の3つのプロトコルを扱える。
    • net/httpを使って頑張って実装したのかな?
  • ConnectプロトコルはHTTP/1.1またはHTTP/2でも動作するPOST専用のプロトコル。gRPCとgRPC-Webのいいとこ取り。
axpensiveaxpensive

Buf Schema Registry(BSR)

https://buf.build/product/bsr
https://github.com/bufbuild/buf#the-buf-schema-registry

The only purpose built solution for managing the complete lifecycle of Protocol Buffers APIs
Protocol Buffers APIのライフサイクルを完全に管理するための唯一の専用ソリューションです。

The Buf Schema Registry (BSR) is a SaaS platform for managing your Protobuf APIs. It provides a centralized registry and a single source of truth for all of your Protobuf assets, including not just your .proto files but also remote plugins. Although the BSR provides an intuitive browser UI, buf enables you to perform most BSR-related tasks from the command line, such as pushing Protobuf sources to the registry and managing users and repositories. The BSR is currently in beta.
The BSR is not required to use buf. We've made the core features of the buf CLI available to all Protobuf users.

Buf Schema Registry (BSR) は、Protobuf API を管理するための SaaS プラットフォームです。.protoファイルだけでなく、リモートプラグインを含むすべてのProtobuf資産の集中レジストリと単一ソースオブトゥルースを提供します。BSRは直感的なブラウザUIを提供しますが、bufはコマンドラインからほとんどのBSR関連タスク(Protobufソースをレジストリにプッシュし、ユーザーとリポジトリを管理する等)を実行することが可能です。BSRは現在ベータ版です。

BSRはbufを使用するために必要なものではありません。私たちは、buf CLIのコア機能をすべてのProtobufユーザーが利用できるようにしました。

使ってみた感想

  • protoの内容がWeb上できれいに表示される。
  • 使うメリットとしてはprotoを共有するリポジトリがBSRにバージョン指定で参照することで開発の手間を省く
    • BSRを使わない場合、各リポジトリでprotoをbuf buildして反映することになる。
      • protoを管理しているリポジトリが更新される->他リポジトリがビルドした内容を反映する手間がかかる
      • コミット履歴を遡る必要がある
    • BSRを使う
      • protoから生成されるコードを一々反映しないで済む
        • BSRでビルドされるファイルを参照する
      • BSRのコードをバージョン指定で参照できる
axpensiveaxpensive

シリアライズ化とは

https://e-words.jp/w/シリアライズ.html

シリアライズとは、複数の要素を一列に並べる操作や処理のこと。単にシリアライズといった場合には、プログラムの実行状態や複雑なデータ構造などを一つの文字列やバイト列で表現する「直列化」を指すことが多い。

RPCはオブジェクトをバイナリデータに変換する処理

メリット

  • データ量削減

デメリット

  • データはバイナリなのでデバッグや監視が難しい。内容を知りたい場合はデシリアライズが必要

ちなみにConnectではシリアライズ化するかどうか決めることができる。