gRPC Deadlinesの事故を記録する
2516 ワード
トランザクションサービスのアラームを受信し、サーバのメモリが急増しました.後で調べたところ、gRPCクライアントが呼び出したときにコンテキスト(context)にDeadlineが設定されていないためであることが分かった.では、なぜDeadlineを設定しないとメモリが消費されるのでしょうか.
gRPCを使用する場合、gRPCライブラリは通信、グループ化、グループ解除、および最終期限の実行を担当します.Deadlineでは、gRPCクライアントがRPCで誤ったDEADLINEを指定できるようにします.EXCEEDEDが終了する前に、RPCの完了を待つことを望んでいます.デフォルトでは、言語実装に応じて、この締め切りは非常に大きな数字です.締め切りをどのように指定するかも言語によって異なります.締め切り日またはタイムアウトを指定する方法は言語によって異なります.たとえば、すべての言語にデフォルトの締め切り日があるわけではありません.deadlineを使用する言語もあれば、timeoutsを使用する言語もあります.サーバ側では、サーバは、特定のRPCがタイムアウトしたかどうか、またはRPCを完了するのにどれだけの時間が残っているかを問い合わせることができます.
通常、締め切り日を設定しないと、進行中のすべてのリクエストにリソースが保持され、すべてのリクエストが最大タイムアウトに達する可能性があります.これにより、メモリなどのサービスが消費されるリスクに直面し、サービスの遅延が増加したり、最悪の場合、プロセス全体がクラッシュする可能性があります.
「良い締め切り/タイムアウト値とは?」単一の答えはない.では、締め切り日を賢明に選択するには何を考慮する必要がありますか?考慮すべき要因には、システム全体のエンドツーエンド遅延、どのRPCがシリアルであり、並列に実行できるかが含まれます.エンジニアはサービスを理解し、クライアントとサーバの間のRPCのために意図的な締め切りを設定する必要があります.
gRPCでは,リモートプロシージャ呼び出し(RPC)が成功したかどうかについて,クライアントとサーバが独立してローカルで判断した.これは彼らの結論が一致しない可能性があることを意味します!サービス側で正常に完了したRPCは、クライアントで失敗する可能性があります.たとえば、サーバは応答を送信することができますが、この返信は締め切り日が切れた後にクライアントに到達することができ、クライアントは返信が到着する前にエラー状態DEADLINE_を使用します.EXCEEDED終了.
Setting a deadline
Go
クライアントとして、サーバの返信を待つ時間を決定するために、常に期限を設定する必要があります.
Checking deadlines
On the server side, the server can query to see if a particular RPC is no longer wanted. サービス側では、サーバが特定のRPCが不要になったかどうかを確認できます.サーバが応答を開始する前に、クライアントが待機しているかどうかを確認することが重要です.この点は、高価な処理を開始する前に特に重要です.
Go
お客様が締め切りに達したことを知っている場合、サーバはリクエストの処理を続行しますか?これは次第です.応答がサーバにキャッシュできる場合は、処理とキャッシュに値する.特に、リソースが重く、リクエストごとにお金がかかります.これにより、結果が使用可能になったため、将来のリクエストがより速くなります.
Adjusting deadlines
新しいバージョンまたはサーババージョンで締め切り日を設定するとエラーが発生します.どうすればいいですか?締め切りが小さすぎると、すべてのリクエストがタイムアウトする可能性があります.EXCEEDED、または大きすぎて、ユーザーの末尾の遅延が大きくなりました.フラグを使用して、締め切り日を設定および調整できます.
Go
リファレンス
gRPC and Deadlines gRPC
gRPCを使用する場合、gRPCライブラリは通信、グループ化、グループ解除、および最終期限の実行を担当します.Deadlineでは、gRPCクライアントがRPCで誤ったDEADLINEを指定できるようにします.EXCEEDEDが終了する前に、RPCの完了を待つことを望んでいます.デフォルトでは、言語実装に応じて、この締め切りは非常に大きな数字です.締め切りをどのように指定するかも言語によって異なります.締め切り日またはタイムアウトを指定する方法は言語によって異なります.たとえば、すべての言語にデフォルトの締め切り日があるわけではありません.deadlineを使用する言語もあれば、timeoutsを使用する言語もあります.サーバ側では、サーバは、特定のRPCがタイムアウトしたかどうか、またはRPCを完了するのにどれだけの時間が残っているかを問い合わせることができます.
通常、締め切り日を設定しないと、進行中のすべてのリクエストにリソースが保持され、すべてのリクエストが最大タイムアウトに達する可能性があります.これにより、メモリなどのサービスが消費されるリスクに直面し、サービスの遅延が増加したり、最悪の場合、プロセス全体がクラッシュする可能性があります.
「良い締め切り/タイムアウト値とは?」単一の答えはない.では、締め切り日を賢明に選択するには何を考慮する必要がありますか?考慮すべき要因には、システム全体のエンドツーエンド遅延、どのRPCがシリアルであり、並列に実行できるかが含まれます.エンジニアはサービスを理解し、クライアントとサーバの間のRPCのために意図的な締め切りを設定する必要があります.
gRPCでは,リモートプロシージャ呼び出し(RPC)が成功したかどうかについて,クライアントとサーバが独立してローカルで判断した.これは彼らの結論が一致しない可能性があることを意味します!サービス側で正常に完了したRPCは、クライアントで失敗する可能性があります.たとえば、サーバは応答を送信することができますが、この返信は締め切り日が切れた後にクライアントに到達することができ、クライアントは返信が到着する前にエラー状態DEADLINE_を使用します.EXCEEDED終了.
Setting a deadline
Go
クライアントとして、サーバの返信を待つ時間を決定するために、常に期限を設定する必要があります.
clientDeadline := time.Now().Add(time.Duration(*deadlineMs) * time.Millisecond)
ctx, cancel := context.WithDeadline(ctx, clientDeadline)
Checking deadlines
On the server side, the server can query to see if a particular RPC is no longer wanted. サービス側では、サーバが特定のRPCが不要になったかどうかを確認できます.サーバが応答を開始する前に、クライアントが待機しているかどうかを確認することが重要です.この点は、高価な処理を開始する前に特に重要です.
Go
if ctx.Err() == context.Canceled {
return status.New(codes.Canceled, "Client cancelled, abandoning.")
}
お客様が締め切りに達したことを知っている場合、サーバはリクエストの処理を続行しますか?これは次第です.応答がサーバにキャッシュできる場合は、処理とキャッシュに値する.特に、リソースが重く、リクエストごとにお金がかかります.これにより、結果が使用可能になったため、将来のリクエストがより速くなります.
Adjusting deadlines
新しいバージョンまたはサーババージョンで締め切り日を設定するとエラーが発生します.どうすればいいですか?締め切りが小さすぎると、すべてのリクエストがタイムアウトする可能性があります.EXCEEDED、または大きすぎて、ユーザーの末尾の遅延が大きくなりました.フラグを使用して、締め切り日を設定および調整できます.
Go
var deadlineMs = flag.Int("deadline_ms", 20*1000, "Default deadline in milliseconds.")
ctx, cancel := context.WithTimeout(ctx, time.Duration(*deadlineMs) * time.Millisecond)
リファレンス
gRPC and Deadlines gRPC