Layanan gRPC yang andal dengan tenggat waktu dan pembatalan
Catatan
Ini bukan versi terbaru dari artikel ini. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Peringatan
Versi ASP.NET Core ini tidak lagi didukung. Untuk informasi selengkapnya, lihat Kebijakan Dukungan .NET dan .NET Core. Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Penting
Informasi ini berkaitan dengan produk pra-rilis yang mungkin dimodifikasi secara substansial sebelum dirilis secara komersial. Microsoft tidak memberikan jaminan, tersirat maupun tersurat, sehubungan dengan informasi yang diberikan di sini.
Untuk rilis saat ini, lihat versi .NET 8 dari artikel ini.
Oleh James Newton-King
Tenggat waktu dan pembatalan adalah fitur yang digunakan oleh klien gRPC untuk membatalkan panggilan yang sedang berlangsung. Artikel ini membahas mengapa tenggat waktu dan pembatalan penting, dan cara menggunakannya di aplikasi .NET gRPC.
Tenggat waktu
Tenggat waktu memungkinkan klien gRPC menentukan berapa lama akan menunggu panggilan selesai. Ketika tenggat waktu terlampaui, panggilan dibatalkan. Mengatur tenggat waktu penting karena memberikan batas atas berapa lama panggilan dapat berjalan. Ini menghentikan layanan yang salah tingkah laku agar tidak berjalan selamanya dan menghabiskan sumber daya server. Tenggat waktu adalah alat yang berguna untuk membangun aplikasi yang andal dan harus dikonfigurasi.
Konfigurasi tenggat waktu:
- Tenggat waktu dikonfigurasi menggunakan
CallOptions.Deadline
saat panggilan dilakukan. - Tidak ada nilai tenggat waktu default. Panggilan gRPC tidak terbatas waktu kecuali tenggat waktu ditentukan.
- Tenggat waktu adalah waktu UTC ketika tenggat waktu terlampaui. Misalnya,
DateTime.UtcNow.AddSeconds(5)
adalah tenggat waktu 5 detik dari sekarang. - Jika waktu lalu atau saat ini digunakan, panggilan segera melebihi tenggat waktu.
- Tenggat waktu dikirim dengan panggilan gRPC ke layanan dan dilacak secara independen oleh klien dan layanan. Ada kemungkinan bahwa panggilan gRPC selesai pada satu komputer, tetapi pada saat respons telah kembali ke klien, tenggat waktu telah terlampaui.
Jika tenggat waktu terlampaui, klien dan layanan memiliki perilaku yang berbeda:
- Klien segera membatalkan permintaan HTTP yang mendasar dan melemparkan
DeadlineExceeded
kesalahan. Aplikasi klien dapat memilih untuk menangkap kesalahan dan menampilkan pesan batas waktu kepada pengguna. - Di server, permintaan HTTP yang dijalankan dibatalkan dan ServerCallContext.CancellationToken dinaikkan. Meskipun permintaan HTTP dibatalkan, panggilan gRPC terus berjalan di server hingga metode selesai. Penting bahwa token pembatalan diteruskan ke metode asinkron sehingga dibatalkan bersama dengan panggilan. Misalnya, meneruskan token pembatalan ke kueri database asinkron dan permintaan HTTP. Melewati token pembatalan memungkinkan panggilan yang dibatalkan selesai dengan cepat di server dan membebaskan sumber daya untuk panggilan lain.
Konfigurasikan CallOptions.Deadline
untuk mengatur tenggat waktu untuk panggilan gRPC:
var client = new Greet.GreeterClient(channel);
try
{
var response = await client.SayHelloAsync(
new HelloRequest { Name = "World" },
deadline: DateTime.UtcNow.AddSeconds(5));
// Greeting: Hello World
Console.WriteLine("Greeting: " + response.Message);
}
catch (RpcException ex) when (ex.StatusCode == StatusCode.DeadlineExceeded)
{
Console.WriteLine("Greeting timeout.");
}
Menggunakan ServerCallContext.CancellationToken
dalam layanan gRPC:
public override async Task<HelloReply> SayHello(HelloRequest request,
ServerCallContext context)
{
var user = await _databaseContext.GetUserAsync(request.Name,
context.CancellationToken);
return new HelloReply { Message = "Hello " + user.DisplayName };
}
Tenggat waktu dan percobaan ulang
Saat panggilan gRPC dikonfigurasi dengan penanganan kesalahan coba lagi dan tenggat waktu, tenggat waktu melacak waktu di semua percobaan ulang untuk panggilan gRPC. Jika tenggat waktu terlampaui, panggilan gRPC segera membatalkan permintaan HTTP yang mendasarinya, melewati percobaan ulang yang tersisa, dan melemparkan DeadlineExceeded
kesalahan.
Menyebarkan tenggat waktu
Ketika panggilan gRPC dilakukan dari layanan gRPC yang mengeksekusi, tenggat waktu harus disebarluaskan. Contohnya:
- Panggilan
FrontendService.GetUser
aplikasi klien dengan tenggat waktu. FrontendService
UserService.GetUser
memanggil . Tenggat waktu yang ditentukan oleh klien harus ditentukan dengan panggilan gRPC baru.UserService.GetUser
menerima tenggat waktu. Waktu habis dengan benar jika tenggat waktu aplikasi klien terlampaui.
Konteks panggilan menyediakan tenggat waktu dengan ServerCallContext.Deadline
:
public override async Task<UserResponse> GetUser(UserRequest request,
ServerCallContext context)
{
var client = new User.UserServiceClient(_channel);
var response = await client.GetUserAsync(
new UserRequest { Id = request.Id },
deadline: context.Deadline);
return response;
}
Menyebarkan tenggat waktu secara manual bisa rumit. Tenggat waktu perlu diteruskan ke setiap panggilan, dan mudah untuk melewatkan secara tidak sengaja. Solusi otomatis tersedia dengan pabrik klien gRPC. Menentukan EnableCallContextPropagation
:
- Secara otomatis menyebarluaskan tenggat waktu dan token pembatalan ke panggilan anak.
- Tidak menyebarluaskan tenggat waktu jika panggilan anak menentukan tenggat waktu yang lebih kecil. Misalnya, tenggat waktu yang disebarkan 10 detik tidak digunakan jika panggilan anak menentukan tenggat waktu baru 5 detik menggunakan
CallOptions.Deadline
. Saat beberapa tenggat waktu tersedia, tenggat waktu terkecil digunakan. - Adalah cara yang sangat baik untuk memastikan bahwa skenario gRPC yang kompleks dan berlapis selalu menyebarluaskan tenggat waktu dan pembatalan.
services
.AddGrpcClient<User.UserServiceClient>(o =>
{
o.Address = new Uri("https://localhost:5001");
})
.EnableCallContextPropagation();
Untuk informasi selengkapnya, lihat integrasi pabrik klien gRPC di .NET.
Pembatalan
Pembatalan memungkinkan klien gRPC untuk membatalkan panggilan jangka panjang yang tidak lagi diperlukan. Misalnya, panggilan gRPC yang melakukan streaming pembaruan realtime dimulai ketika pengguna mengunjungi halaman di situs web. Aliran harus dibatalkan saat pengguna menavigasi jauh dari halaman.
Panggilan gRPC dapat dibatalkan di klien dengan meneruskan token pembatalan dengan CallOptions.CancellationToken atau memanggil Dispose
panggilan.
private AsyncServerStreamingCall<HelloReply> _call;
public void StartStream()
{
_call = client.SayHellos(new HelloRequest { Name = "World" });
// Read response in background task.
_ = Task.Run(async () =>
{
await foreach (var response in _call.ResponseStream.ReadAllAsync())
{
Console.WriteLine("Greeting: " + response.Message);
}
});
}
public void StopStream()
{
_call.Dispose();
}
Layanan gRPC yang dapat dibatalkan harus:
- Teruskan
ServerCallContext.CancellationToken
ke metode asinkron. Membatalkan metode asinkron memungkinkan panggilan di server selesai dengan cepat. - Menyebarkan token pembatalan ke panggilan anak. Menyebarkan token pembatalan memastikan bahwa panggilan anak dibatalkan dengan induknya. pabrik klien gRPC dan
EnableCallContextPropagation()
secara otomatis menyebarkan token pembatalan.
Sumber Daya Tambahan:
ASP.NET Core