ASP.NET Core: Xử lý lỗi tạm thời bằng cách thử lại gRPC


Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên

Trong bài viết này

  1. Xử lý lỗi nhất thời
  2. Định cấu hình chính sách thử lại gRPC
  3. Bảo hiểm rủi ro
  4. Định cấu hình chính sách phòng ngừa rủi ro gRPC
  5. Tài nguyên bổ sung

Thử lại (retry) gRPC là một tính năng cho phép máy khách gRPC tự động thử lại các lời gọi không thành công. Bài viết này thảo luận cách định cấu hình chính sách thử lại để tạo ra các ứng dụng gRPC linh hoạt, có khả năng chịu lỗi trong .NET.

Việc thử lại gRPC yêu cầu Grpc.Net.Client phiên bản 2.36.0 trở lên.

Xử lý lỗi nhất thời

Lời gọi gRPC có thể bị gián đoạn do lỗi nhất thời (transient fault). Các lỗi nhất thời bao gồm:

  • Mất kết nối mạng tạm thời.
  • Sự không có sẵn tạm thời của một dịch vụ.
  • Hết thời gian chờ do tải máy chủ.

Khi lời gọi gRPC bị gián đoạn, máy khách sẽ ném (throws) ngoại lệ RpcException với thông tin chi tiết về lỗi. Ứng dụng khách phải bắt (catch) ngoại lệ và chọn cách xử lý lỗi.

var client = new Greeter.GreeterClient(channel);
try
{
    var response = await client.SayHelloAsync(
        new HelloRequest { Name = ".NET" });

    Console.WriteLine("From server: " + response.Message);
}
catch (RpcException ex)
{
    // Viết logic để kiểm tra lỗi và thử lại
    // nếu lỗi là lỗi nhất thời.
}

Việc sao chép logic thử lại trong toàn bộ ứng dụng sẽ dài dòng và dễ xảy ra lỗi. May mắn thay, ứng dụng khách .NET gRPC có hỗ trợ tích hợp cho việc thử lại tự động.

Định cấu hình chính sách thử lại gRPC

Chính sách thử lại được định cấu hình một lần khi kênh gRPC được tạo:

var defaultMethodConfig = new MethodConfig
{
    Names = { MethodName.Default },
    RetryPolicy = new RetryPolicy
    {
        MaxAttempts = 5,
        InitialBackoff = TimeSpan.FromSeconds(1),
        MaxBackoff = TimeSpan.FromSeconds(5),
        BackoffMultiplier = 1.5,
        RetryableStatusCodes = { StatusCode.Unavailable }
    }
};

var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
{
    ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } }
});

Đoạn code trên:

  • Tạo một file MethodConfig. Chính sách thử lại có thể được định cấu hình cho mỗi phương thức và các phương thức được khớp bằng property Names. Phương thức này được định cấu hình bằng MethodName.Default, do đó, nó được áp dụng cho tất cả các phương thức gRPC được kênh này gọi.
  • Định cấu hình chính sách thử lại. Chính sách này hướng dẫn máy khách tự động thử lại các lệnh gọi gRPC không thành công với mã trạng thái Unavailable.
  • Định cấu hình kênh đã tạo để sử dụng chính sách thử lại bằng cách đặt GrpcChannelOptions.ServiceConfig.

Các máy khách gRPC được tạo bằng kênh sẽ tự động thử lại các lời gọi không thành công:

var client = new Greeter.GreeterClient(channel);
var response = await client.SayHelloAsync(
    new HelloRequest { Name = ".NET" });

Console.WriteLine("From server: " + response.Message);

Khi lần thử lại hợp lệ

Lời gọi được thử lại khi:

  • Mã trạng thái không khớp với giá trị trong RetryableStatusCodes.
  • Số lần thử trước đó nhỏ hơn MaxAttempts.
  • Lời gọi chưa được thực hiện.
  • Thời hạn chưa được vượt quá.

Lời gọi gRPC sẽ được thực hiện trong hai trường hợp:

  • Máy khách nhận được tiêu đề phản hồi. Tiêu đề phản hồi được máy chủ gửi khi ServerCallContext.WriteResponseHeadersAsync được gọi hoặc khi tin nhắn đầu tiên được ghi vào luồng phản hồi của máy chủ.
  • Message gửi đi của máy khách (hoặc message nếu phát trực tuyến) đã vượt quá kích thước bộ đệm tối đa của máy khách. MaxRetryBufferSize và MaxRetryBufferPerCallSize được cấu hình trên kênh.

Lời gọi đã cam kết sẽ không thử lại, bất kể mã trạng thái hay số lần thử trước đó.

Truyền phát lời gọi

Bạn có thể sử dụng tính năng truyền trực tuyến lời gọi khi thử lại gRPC, nhưng có những điểm quan trọng cần cân nhắc khi sử dụng chúng cùng nhau:

  • Truyền phát máy chủ, truyền phát hai chiều: Truyền phát RPC trả về nhiều message từ máy chủ sẽ không thử lại sau khi nhận được message đầu tiên. Ứng dụng phải thêm logic bổ sung để thiết lập lại máy chủ và các lời gọi truyền phát hai chiều theo cách thủ công.
  • Truyền phát ứng dụng khách, truyền phát hai chiều: Truyền phát RPC gửi nhiều message đến máy chủ sẽ không thử lại nếu các message gửi đi đã vượt quá kích thước bộ đệm tối đa của máy khách. Kích thước bộ đệm tối đa có thể được tăng lên bằng cấu hình.

Để biết thêm thông tin, hãy xem Thời điểm thử lại hợp lệ.

Thử lại độ trễ chờ đợi

Độ trễ chờ giữa các lần thử lại được định cấu hình bằng InitialBackoffMaxBackoff và BackoffMultiplier. Thông tin thêm về từng tùy chọn có sẵn trong phần tùy chọn thử lại gRPC.

Độ trễ thực tế giữa các lần thử lại là ngẫu nhiên. Độ trễ ngẫu nhiên giữa 0 và độ trễ hiện tại xác định thời điểm thực hiện lần thử lại tiếp theo. Hãy cân nhắc rằng ngay cả khi đã định cấu hình thời gian chờ theo cấp số nhân, việc tăng thời gian chờ hiện tại giữa các lần thử thì độ trễ thực tế giữa các lần thử không phải lúc nào cũng lớn hơn. Độ trễ được chọn ngẫu nhiên để ngăn việc thử lại từ nhiều lời gọi cụm lại với nhau và có khả năng làm máy chủ bị quá tải.

Phát hiện lần thử lại bằng siêu dữ liệu

Việc thử lại gRPC có thể được phát hiện nhờ sự hiện diện của siêu dữ liệu grpc-previous-rpc-attempts. Siêu dữ liệu grpc-previous-rpc-attempts:

  • Được tự động thêm vào các lời gọi thử lại và gửi đến máy chủ.
  • Giá trị đại diện cho số lần thử lại trước đó.
  • Giá trị luôn là số nguyên.

Hãy xem xét kịch bản thử lại sau:

  1. Máy khách thực hiện lời gọi gRPC đến máy chủ.
  2. Máy chủ không thành công và trả về phản hồi mã trạng thái có thể truy xuất được.
  3. Máy khách thử lại lời gọi gRPC. Vì đã có một lần thử trước đó nên siêu dữ liệu grpc-previous-rpc-attempts có giá trị là 1. Siêu dữ liệu được gửi đến máy chủ khi thử lại.
  4. Máy chủ thành công và trả về OK.
  5. Khách hàng báo cáo thành công. grpc-previous-rpc-attempts nằm trong siêu dữ liệu phản hồi và có giá trị là 1.

Siêu dữ liệu grpc-previous-rpc-attempts không có trong lệnh gọi gRPC đầu tiên, dành 1 cho lần thử lại đầu tiên, 2 cho lần thử lại thứ hai, v.v.

Tùy chọn thử lại gRPC

Bảng sau mô tả các tùy chọn để định cấu hình chính sách thử lại gRPC:

Lựa chọn Mô tả
MaxAttempts Số lần thử lời gọi tối đa, bao gồm cả lần thử ban đầu. Giá trị này được giới hạn theo GrpcChannelOptions.MaxRetryAttempts với mặc định là 5. Giá trị là bắt buộc và phải lớn hơn 1.
InitialBackoff Độ trễ chờ ban đầu giữa các lần thử lại. Độ trễ ngẫu nhiên giữa 0 và độ trễ hiện tại xác định thời điểm thực hiện lần thử lại tiếp theo. Sau mỗi lần thử, thời gian chờ hiện tại được nhân với BackoffMultiplier. Một giá trị là bắt buộc và phải lớn hơn 0.
MaxBackoff Khoản hoàn trả tối đa đặt ra giới hạn trên cho mức tăng trưởng khoản hoàn trả theo cấp số nhân. Một giá trị là bắt buộc và phải lớn hơn 0.
BackoffMultiplier Giá trị chờ sẽ được nhân với giá trị này sau mỗi lần thử lại và sẽ tăng theo cấp số nhân khi hệ số nhân lớn hơn 1. Cần có một giá trị và phải lớn hơn 0.
RetryableStatusCodes Một collection các mã trạng thái. Lời gọi gRPC không thành công với trạng thái khớp sẽ được tự động thử lại. Để biết thêm thông tin về mã trạng thái, hãy xem Mã trạng thái và cách sử dụng chúng trong gRPC. Cần có ít nhất một mã trạng thái có thể thử lại.

Bảo hiểm rủi ro

Phòng ngừa rủi ro là một chiến lược thử lại thay thế. Bảo hiểm rủi ro cho phép chủ động gửi nhiều bản sao của một lệnh gọi gRPC mà không cần chờ phản hồi. Các lệnh gọi gRPC được bảo vệ có thể được thực thi nhiều lần trên máy chủ và kết quả thành công đầu tiên sẽ được sử dụng. Điều quan trọng là tính năng phòng ngừa rủi ro chỉ được kích hoạt đối với các phương pháp an toàn để thực hiện nhiều lần mà không gây ảnh hưởng xấu.

Bảo hiểm rủi ro có những ưu và nhược điểm khi so sánh với lần thử lại:

  • Một lợi thế của việc phòng ngừa rủi ro là nó có thể mang lại kết quả thành công nhanh hơn. Nó cho phép thực hiện nhiều lời gọi gRPC đồng thời và sẽ hoàn thành khi có kết quả thành công đầu tiên.
  • Một bất lợi của việc phòng ngừa rủi ro là nó có thể gây lãng phí. Nhiều lời gọi có thể được thực hiện và tất cả đều thành công. Chỉ kết quả đầu tiên được sử dụng và phần còn lại sẽ bị loại bỏ.

Định cấu hình chính sách phòng ngừa rủi ro gRPC

Chính sách phòng ngừa rủi ro được cấu hình giống như chính sách thử lại. Lưu ý rằng không thể kết hợp chính sách phòng ngừa rủi ro với chính sách thử lại.

var defaultMethodConfig = new MethodConfig
{
    Names = { MethodName.Default },
    HedgingPolicy = new HedgingPolicy
    {
        MaxAttempts = 5,
        NonFatalStatusCodes = { StatusCode.Unavailable }
    }
};

var channel = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
{
    ServiceConfig = new ServiceConfig { MethodConfigs = { defaultMethodConfig } }
});

Tùy chọn phòng ngừa rủi ro gRPC

Bảng sau đây mô tả các tùy chọn để định cấu hình chính sách phòng ngừa rủi ro gRPC:

Lựa chọn Mô tả
MaxAttempts Chính sách phòng ngừa rủi ro sẽ gửi tới số lượng lời gọi này. MaxAttempts đại diện cho tổng số lần thử, bao gồm cả lần thử ban đầu. Giá trị này được giới hạn theo GrpcChannelOptions.MaxRetryAttempts với mặc định là 5. Giá trị là bắt buộc và phải bằng 2 hoặc lớn hơn.
HedgingDelay Lời gọi đầu tiên được gửi ngay lập tức, các lời gọi phòng ngừa rủi ro tiếp theo sẽ bị trì hoãn bởi giá trị này. Khi độ trễ được đặt thành 0 hoặc null, tất cả các lời gọi được bảo vệ sẽ được gửi ngay lập tức. HedgingDelay là tùy chọn và mặc định là 0. Giá trị phải bằng 0 hoặc lớn hơn.
NonFatalStatusCodes Một tập hợp các mã trạng thái cho biết các lệnh phòng ngừa rủi ro khác vẫn có thể thành công. Nếu mã trạng thái không nghiêm trọng được máy chủ trả về, các lời gọi được bảo vệ sẽ tiếp tục. Nếu không, các yêu cầu chưa xử lý sẽ bị hủy và lỗi sẽ quay trở lại ứng dụng. Để biết thêm thông tin về mã trạng thái, hãy xem Mã trạng thái và cách sử dụng chúng trong gRPC.

Tài nguyên bổ sung

Nguồn: learn.microsoft.com
» Tiếp: Cân bằng tải phía máy khách gRPC
« Trước: Dịch vụ gRPC đáng tin cậy có thời hạn và hủy bỏ
Khóa học qua video:
Lập trình Python All Lập trình C# All SQL Server All Lập trình C All Java PHP HTML5-CSS3-JavaScript
Đăng ký Hội viên
Tất cả các video dành cho hội viên
Copied !!!