「全部gRPCにすれば速くなる」は間違い
マイクロサービス間通信にgRPCを採用する企業が増えている。しかしKGAの経験では、盲目的にgRPCを採用して後悔するケースも少なくない。RESTが最適なケース、gRPCが最適なケース、両方を混在させるべきケースがある。この記事では実測データに基づいて判断基準を提供する。
Protocol Buffers vs JSON: シリアライゼーションの本質
gRPCの性能優位の大部分はProtocol Buffers(protobuf)のバイナリシリアライゼーションに由来する。JSONと比較して、シリアライゼーション速度は3-10倍高速、ペイロードサイズは1/3-1/5程度になる。
KGAの実測では、1KBのJSONペイロード(典型的なAPIレスポンス)のシリアライズ/デシリアライズで、JSON(Go標準ライブラリ)が45μs、protobufが8μsだった。10KBペイロードではJSON 320μs、protobuf 25μsとさらに差が開く。
ただし、ペイロードが小さい場合(100B以下)はHTTP/2のヘッダー圧縮やコネクション管理のオーバーヘッドの方が支配的になり、gRPCの優位性は薄れる。小さなメッセージを大量にやり取りする場合は、バッチ化を検討すべきだ。
ストリーミング: gRPCの真の強み
RESTのリクエスト-レスポンスモデルでは実現困難なパターンを、gRPCのストリーミングが解決する。Server-side streaming(サーバーからの継続的なデータ送信)、Client-side streaming(クライアントからの連続データ送信)、Bidirectional streaming(双方向リアルタイム通信)の3パターンがある。
KGAのリアルタイムログ集約システムでは、各マイクロサービスからのログをClient-side streamingで集約サーバーに送信している。HTTPリクエストの度にコネクションを張る方式と比較して、ネットワークオーバーヘッドが85%削減された。
Bidirectional streamingはチャットシステムやリアルタイム協調編集で威力を発揮する。WebSocketとの比較では、protobufによる型安全性と自動コード生成が大きなアドバンテージだ。
エラーハンドリングの設計差
RESTではHTTPステータスコード(404、500等)とレスポンスボディでエラーを表現するが、統一規格がないため実装がバラつく。Google JSON StyleやProblem Details(RFC 7807)などのガイドラインはあるが、チーム間での一貫性確保に労力がかかる。
gRPCでは15種類の標準ステータスコード(OK、NOT_FOUND、INTERNAL等)とgoogle.rpc.Statusメッセージにより、エラー表現が統一されている。さらにError Detailsの仕組みで、構造化されたエラー情報(リトライ可能か、いつリトライすべきか等)を型安全に伝達できる。
KGAの20以上のマイクロサービスで、gRPCのエラーハンドリングを統一した結果、障害調査にかかる平均時間が40%短縮された。エラーの種類と付随情報が予測可能になり、自動リトライの判定が確実になったためだ。
本番ベンチマーク: 現実のワークロード
KGAの本番環境(Go 1.22、Kubernetes on AWS EKS)で、同一のビジネスロジックをREST(gin + JSON)とgRPC(protobuf)で実装し比較した結果を示す。
レイテンシ(P50/P99、同一AZ内通信): REST 2.1ms/8.5ms、gRPC 0.9ms/3.2ms。スループット(1コネクションあたり): REST 2,800 req/s、gRPC 7,200 req/s。CPU使用率(10,000 req/s処理時): REST 45%、gRPC 28%。
gRPCが全指標で優位だが、注目すべきはCPU使用率の差だ。シリアライゼーションのCPU負荷が大きく異なるため、大規模環境ではインフラコストに直結する。
RESTを選ぶべきケース
gRPCが万能ではない。以下のケースではRESTを推奨する。外部公開API: ブラウザやサードパーティからの直接アクセスが必要な場合。gRPC-Webは制約が多く、REST APIの方が消費者にとって使いやすい。デバッグの容易性が重要な場合: curlでリクエストを投げてJSONで確認できるRESTのデバッグ体験は、protobufのバイナリ形式では得られない。チームのスキルセット: protobuf定義の管理、コード生成のCI/CD統合、後方互換性の維持はRESTより学習コストが高い。
KGAの使い分け戦略
KGAでは以下の基準で使い分けている。サービス間内部通信: gRPC(パフォーマンスと型安全性を優先)。外部公開API: REST + OpenAPI(消費者の利便性を優先)。リアルタイム通信: gRPC streaming(WebSocketの代替)。BFF(Backend for Frontend): REST(フロントエンドとの親和性)。
gRPCとRESTの共存にはgRPC-Gatewayが有効だ。gRPCサービスの前段にHTTP/JSONのリバースプロキシを自動生成し、内部はgRPC、外部はRESTというパターンを低コストで実現できる。KGAの3つのプロダクトでこのパターンを採用し、内部通信の効率化と外部APIの使いやすさを両立している。
後方互換性の維持
protobufのスキーマ進化ルール(フィールドの追加はOK、フィールド番号の変更はNG、requiredフィールドの削除はNG)を厳格に守ることが、gRPC運用の生命線だ。KGAではBuf(buf.build)のCIツールを使い、protoファイルの変更がPRとして提出されるたびに後方互換性チェックを自動実行している。Breaking changeが検出されたPRは自動的にブロックされる。この仕組みにより、2年間の運用でprotoスキーマの互換性破壊を一度も本番に出していない。