概要
gRPC は Google がオープンソース化した最新の高性能 RPC フレームワークであり、HTTP/2 プロトコルと Protocol Buffers によるシリアライゼーションを基盤としている。多言語対応のクロスプラットフォーム通信をサポートし、ストリーミング転送、認証、ロードバランシングなどの機能を提供する。
README プレビュー
# gRPC – An RPC library and framework\n\ngRPC is a modern, open source, high-performance remote procedure call (RPC)\nframework that can run anywhere. gRPC enables client and server applications to\ncommunicate transparently, and simplifies the building of connected systems.\n\n\n \n Homepage:\n grpc.io\n \n \n Mailing List:\n grpc-io@googlegroups.com\n \n\n\n[](https://gitter.im/grpc/grpc?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n\n## To start using gRPC\n\nTo maximize usability, gRPC supports the standard method for adding dependencies\nto a user's chosen language (if there is one). In most languages, the gRPC\nruntime comes as a package available in a user's language package manager.\n\nFor instructions on how to use the language-specific gRPC runtime for a project,\nplease refer to these documents\n\n- [C++](src/cpp): follow the instructions under the `src/cpp` directory\n- [C#/.NET](https://github.com/grpc/grpc-dotnet): NuGet packages\n `Grpc.Net.Client`, `Grpc.AspNetCore.Server`\n- [Dart](https://github.com/grpc/grpc-dart): pub package `grpc`\n- [Go](https://github.com/grpc/grpc-go): `go get google.golang.org/grpc`\n- [Java](https://github.com/grpc/grpc-java): Use JARs from Maven Central\n Repository\n- [Kotlin](https://github.com/grpc/grpc-kotlin): Use JARs from Maven Central\n Repository\n- [Node](https://github.com/grpc/grpc-node): `npm install @grpc/grpc-js`\n- [Objective-C](src/objective-c): Add `gRPC-ProtoRPC` dependency to podspec\n- [PHP](src/php): `pecl install grpc`\n- [Python](src/python/grpcio): `pip install grpcio`\n- [Ruby](src/ruby): `gem install grpc`\n- [WebJS](https://github.com/grpc/grpc-web): follow the grpc-web instructions\n\nPer-language quickstart guides and tutorials can be found in the\n[documentation section on the grpc.io website](https://grpc.io/docs/). Code\nexamples are available in the [examples](examples) directory.\n\nPrecompiled bleeding-edge p
FAQ (5)
トラブル対応クライアントがサーバーに接続できない場合に gRPC C++ で発生する Abseil の「Potential Mutex deadlock」アボートを修正する方法
これは、gRPC の TCP コネクトハンドシェイカーにおけるロック順序の逆転が原因です。TCPConnectHandshaker::FinishLocked() は TCPConnectHandshaker::mu_ を保持したままハンドシェイク完了コールバックを呼び出すため、接続の失敗、再試行、シャットダウンの際に HandshakeManager::mu_ が一貫性のない順序で取得される可能性があります。その結果、Abseil のデバッグ用デッドロック検出器が abort() を呼び出します。
恒久対応: PR #43184 を含む gRPC リリースを使用するか、gRPC をビルドする際にその PR を cherry-pick してください。この修正により、InvokeOnHandshakeDone が TCPConnectHandshaker::mu_ のクリティカルセクションの外側で呼び出されるようになります。
一時的な回避策として、gRPC を使用する前に、Abseil のデッドロック検出を abort ではなく report(報告)するように初期化します。
#include "absl/synchronization/mutex.h"
absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kReport);
あるいは、-DCMAKE_BUILD_TYPE=Release などを指定して Abseil を gRPC と同じリリース構成でビルドし、NDEBUG が定義されてデバッグ専用のデッドロックチェックが無効になるようにします。ただし、この検出器は実際に存在するロック順序の逆転を検出しているため、gRPC のアップグレードまたはパッチ適用を優先してください。
トラブル対応macOSで「Too many open files」または「Failed accept4」によるgRPCストレステストの失敗を修正するにはどうすればよいですか?
ストレステストを実行する前に、シェルのオープンファイルディスクリプタ数の上限を引き上げてください:
ulimit -n 8192
build/client_channel_stress_test
thread_stress_test やその他の影響を受ける gRPC テストを実行する前にも、同じコマンドを使用してください。設定は ulimit -n で確認できます。この失敗は、テストがデフォルトのファイルディスクリプタ数の上限を使い切った場合に発生します。特にコア数の多いマシンで起こりやすくなります。
トラブル対応OpenSSL 4.0でのgRPCビルドエラー (C2440: 'const X509_NAME *' から 'X509_NAME *' に変換できません) の修正方法
OpenSSL 4.0 に対して gRPC のコンパイルが失敗します。これは X509_get_subject_name() が const X509_NAME* を返すようになったため、src/core/tsi/ssl_transport_security.cc、ssl_transport_security_utils.cc、grpc_tls_crl_provider.cc で 'conversion loses qualifiers' エラーが発生します。修正方法: コミット fb056ab0bb3ed003febe82f069ff41514288a4f3(OpenSSL 4 コンパイルサポート、PR #41932)を含む gRPC バージョンにアップグレードしてください。古いリリース(例: 1.76.0)の場合は、ソースにパッチを適用してください: subject_name を const X509_NAME* として宣言し、X509_NAME_get_index_by_NID、X509_NAME_get_entry、X509_NAME_print_ex に渡す際に const_cast<X509_NAME*>(...) でラップします。注意: gRPC における OpenSSL 4 のサポートは実験的とみなされています。
トラブル対応接続ハンドシェイク中にTCPConnectHandshakerで発生するgRPC C++クライアントのSIGABRTデッドロックを修正する方法
これは HandshakeManager::mu_ と TCPConnectHandshaker::mu_ の間でのロック取得順序の逆転(ロックインバージョン)が原因で発生します。接続の失敗、再試行、またはシャットダウン時に、TCPConnectHandshaker::FinishLocked() が TCPConnectHandshaker::mu_ を保持したままハンドシェイク完了コールバックを呼び出すため、そのコールバックが HandshakeManager に再入した際にデッドロックが発生する可能性があります。
修正方法:
1. PR [#43184](https://github.com/grpc/grpc/pull/43184) を含むリリースへ gRPC をアップグレードしてください。
2. すぐにアップグレードできない場合は、その PR を適用した状態でソースから gRPC をビルドしてください:
git clone https://github.com/grpc/grpc.git
cd grpc
git fetch origin pull/43184/head:fix-tcp-handshake-deadlock
git checkout fix-tcp-handshake-deadlock
cmake -S . -B build -DgRPC_INSTALL=ON
cmake --build build --target install3. パッチ適用済みの gRPC ライブラリに対してクライアントをリビルドしてください。
このパッチは InvokeOnHandshakeDone をミューテックスのスコープ外で実行することで、デッドロックの循環を断ち切ります。一時的な緩和策としては、長時間アイドル状態の接続の切断を減らし、同一アドレスへの複数チャネルの繰り返し作成を避けてください。ただし、アップグレードまたはパッチの適用が確実な修正方法です。この問題は gRPC 1.69、RHEL 9.x、GCC 11.4.1 の環境で報告されています。
トラブル対応サポートされていない grpc-encoding ヘッダーに対して gRPC C++ が "Stream removed" または INTERNAL_ERROR を返す問題の修正方法
gRPC C++ を、issue #36770 に対応する PR「[Core] Fix compression error handling edge cases」を含むリリースにアップグレードするか、その修正を含むコミットからビルドしてください。修正後の動作は次のとおりです。サーバーからサポートされていないエンコーディングを受信したクライアントは INTERNAL を返します。クライアントからサポートされていないエンコーディングを受信したサーバーは、HTTP/2 ストリームを RST_STREAM INTERNAL_ERROR でリセットする代わりに UNIMPLEMENTED を返します。また、identity 以外のエンコーディングがネゴシエートされていない状態でエンベロープ圧縮ビットが設定されたメッセージは、無視される代わりに INTERNAL で失敗します。回避策として、両方のピアが相互にサポートされている圧縮アルゴリズムのみをアドバタイズし、ストリームに対して identity 以外のエンコーディングがネゴシエートされていない限り、圧縮メッセージビットを設定しないようにしてください。