Share via


Son tarihler ve iptal ile güvenilir gRPC hizmetleri

Yayınlayan James Newton-King

Son tarihler ve iptaller, gRPC istemcileri tarafından devam eden çağrıları durdurmak için kullanılan özelliklerdir. Bu makalede, son tarihlerin ve iptallerin neden önemli olduğu ve .NET gRPC uygulamalarında bunların nasıl kullanılacağı açıklanır.

Tarihler

Son tarih, gRPC istemcisinin bir çağrının tamamlanmasını ne kadar bekleyeceğini belirtmesine olanak tanır. Son tarih aşıldığında çağrı iptal edilir. Bir çağrının ne kadar süreyle çalışabileceğine ilişkin bir üst sınır sağladığından, son tarih ayarlamak önemlidir. Hatalı davranan hizmetlerin sonsuza kadar çalışmasını ve sunucu kaynaklarının tükenmesini engeller. Son tarihler, güvenilir uygulamalar oluşturmak için kullanışlı bir araçtır ve yapılandırılması gerekir.

Son tarih yapılandırması:

  • Son tarih, çağrı yapıldığında kullanılarak CallOptions.Deadline yapılandırılır.
  • Varsayılan son tarih değeri yoktur. Son tarih belirtilmediği sürece gRPC çağrıları zaman sınırlı değildir.
  • Son tarih, son tarihin aşılmasıyla ilgili UTC saatidir. Örneğin, DateTime.UtcNow.AddSeconds(5) şu andan itibaren 5 saniyelik bir son tarihtir.
  • Geçmiş veya geçerli bir saat kullanılırsa, çağrı hemen son tarihi aşıyor demektir.
  • Son tarih, hizmete yapılan gRPC çağrısıyla gönderilir ve hem istemci hem de hizmet tarafından bağımsız olarak izlenir. Bir gRPC çağrısının bir makinede tamamlanması mümkündür, ancak yanıt istemciye geri döndüğünde son tarih aşılır.

Son tarih aşılırsa istemci ve hizmet farklı davranışlara sahiptir:

  • İstemci, temel alınan HTTP isteğini hemen durdurur ve bir DeadlineExceeded hata oluşturur. İstemci uygulaması hatayı yakalamayı ve kullanıcıya bir zaman aşımı iletisi görüntülemeyi seçebilir.
  • Sunucuda, yürütülen HTTP isteği durduruldu ve ServerCallContext.CancellationToken tetiklendi. HTTP isteği durdurulsa da gRPC çağrısı, yöntem tamamlanana kadar sunucuda çalışmaya devam eder. İptal belirtecinin zaman uyumsuz yöntemlere geçirilmesi önemlidir, bu nedenle çağrıyla birlikte iptal edilirler. Örneğin, zaman uyumsuz veritabanı sorgularına ve HTTP isteklerine iptal belirteci geçirme. İptal belirtecinin geçirilmesi, iptal edilen çağrının sunucuda hızla tamamlanmasını ve diğer çağrılar için kaynakları boşaltmasını sağlar.

gRPC çağrısı için son tarih ayarlamak üzere yapılandırın CallOptions.Deadline :

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.");
}

gRPC hizmetinde kullanma ServerCallContext.CancellationToken :

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 };
}

Son tarihler ve yeniden denemeler

Bir gRPC çağrısı yeniden deneme hatası işleme ve son tarih ile yapılandırıldığında, son tarih gRPC çağrısı için tüm yeniden denemelerde süreyi izler. Son tarih aşılırsa, gRPC çağrısı temel http isteğini hemen durdurur, kalan tüm yeniden denemeleri atlar ve bir DeadlineExceeded hata oluşturur.

Son tarihleri yayma

Yürütülen bir gRPC hizmetinden gRPC çağrısı yapıldığında, son tarih yayılmalıdır. Örnek:

  1. Son tarihi olan istemci uygulaması çağrıları FrontendService.GetUser .
  2. FrontendService çağrısında bulunur UserService.GetUser. İstemci tarafından belirtilen son tarih yeni gRPC çağrısıyla belirtilmelidir.
  3. UserService.GetUser son tarihi alır. İstemci uygulamasının son tarihi aşılırsa zaman aşımına doğru zaman aşımına ular.

Çağrı bağlamı ile ServerCallContext.Deadlineson tarihi sağlar:

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;
}

Son tarihleri el ile yaymak zahmetli olabilir. Son tarihin her çağrıya geçirilmesi gerekir ve yanlışlıkla kaçırılması kolaydır. gRPC istemci fabrikası ile otomatik bir çözüm mevcuttur. Belirtilmesi EnableCallContextPropagation:

  • Son tarih ve iptal belirtecini alt çağrılara otomatik olarak yayılım.
  • Alt çağrı daha küçük bir son tarih belirtiyorsa, son tarihi yaymaz. Örneğin, bir alt çağrı kullanılarak CallOptions.Deadline5 saniyelik yeni bir son tarih belirtirse 10 saniyelik bir yayılan son tarih kullanılmaz. Birden çok son tarih kullanılabilir olduğunda, en küçük son tarih kullanılır.
  • Karmaşık, iç içe gRPC senaryolarının her zaman son tarihi ve iptali yaymasını sağlamanın mükemmel bir yoludur.
services
    .AddGrpcClient<User.UserServiceClient>(o =>
    {
        o.Address = new Uri("https://localhost:5001");
    })
    .EnableCallContextPropagation();

Daha fazla bilgi için bkz . .NET'te gRPC istemci fabrikası tümleştirmesi.

İptal

İptal etme, gRPC istemcisinin artık gerekmeyen uzun süre çalışan çağrıları iptal etmesine olanak tanır. Örneğin, kullanıcı bir web sitesindeki bir sayfayı ziyaret ettiğinde gerçek zamanlı güncelleştirmeleri akışla aktaran bir gRPC çağrısı başlatılır. Kullanıcı sayfadan uzaklaştığında akış iptal edilmelidir.

Bir gRPC çağrısı, CallOptions.CancellationToken ile bir iptal belirteci geçirilerek veya çağrıda çağrılarak Dispose istemcide iptal edilebilir.

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();
}

İptal edilebilecek gRPC hizmetleri:

  • Zaman uyumsuz yöntemlere geçirin ServerCallContext.CancellationToken . Zaman uyumsuz yöntemleri iptal etmek, sunucudaki çağrının hızlı bir şekilde tamamlanmasını sağlar.
  • İptal belirtecini alt çağrılara yayın. İptal belirtecinin yayılması, alt çağrıların üstleriyle birlikte iptal edilmesini sağlar. gRPC istemci fabrikası ve EnableCallContextPropagation() iptal belirtecini otomatik olarak yayılım.

Ek kaynaklar