ASP.NET Core: Phiên bản dịch vụ 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. Khả năng tương thích ngược
  2. Dịch vụ số phiên bản
  3. Tài nguyên bổ sung

Các tính năng mới được thêm vào ứng dụng có thể yêu cầu các dịch vụ gRPC cung cấp cho máy khách phải thay đổi, đôi khi theo những cách không mong muốn và đột phá. Khi dịch vụ gRPC thay đổi:

  • Cần cân nhắc xem những thay đổi này tác động đến máy khách như thế nào.
  • Một chiến lược phiên bản để hỗ trợ những thay đổi nên được thực hiện.

Khả năng tương thích ngược

Giao thức gRPC được thiết kế để hỗ trợ các dịch vụ thay đổi theo thời gian. Nói chung, các bổ sung cho các dịch vụ và phương thức gRPC là không có tính đột phá. Những thay đổi không mang tính đột phá cho phép máy khách hiện tại tiếp tục làm việc mà không cần thay đổi. Việc thay đổi hoặc xóa dịch vụ gRPC là vi phạm các thay đổi. Khi dịch vụ gRPC có những thay đổi lớn, các máy khách sử dụng dịch vụ đó phải được cập nhật và triển khai lại.

Việc thực hiện các thay đổi không gây gián đoạn cho một dịch vụ có một số lợi ích:

  • Các máy khách hiện tại vẫn tiếp tục hoạt động.
  • Tránh làm việc liên quan đến việc thông báo cho máy khách về những thay đổi đáng chú ý và cập nhật chúng.
  • Chỉ một phiên bản của dịch vụ cần được ghi lại và duy trì.

Những thay đổi không phá vỡ

Những thay đổi này không vi phạm ở cấp độ giao thức gRPC và cấp độ nhị phân .NET.

  • Thêm một dịch vụ mới
  • Thêm một phương thức mới vào một dịch vụ
  • Thêm trường vào message yêu cầu - Các trường được thêm vào message yêu cầu sẽ được giải tuần tự hóa với giá trị mặc định trên máy chủ khi không được thiết lập. Để trở thành một thay đổi không gây gián đoạn, dịch vụ phải thành công khi trường mới không được máy khách cũ thiết lập.
  • Thêm trường vào message phản hồi - Các trường được thêm vào message phản hồi sẽ được giải tuần tự hóa vào bộ sưu tập các trường không xác định của message trên máy khách.
  • Thêm giá trị vào enum - Enum được tuần tự hóa dưới dạng giá trị số. Các giá trị enum mới được giải tuần tự hóa trên máy khách thành giá trị enum không có tên enum. Để thay đổi không gây gián đoạn, các máy khách cũ hơn phải chạy chính xác khi nhận được giá trị enum mới.

Thay đổi vi phạm nhị phân

Các thay đổi sau đây không vi phạm ở cấp giao thức gRPC, nhưng máy khách cần được cập nhật nếu nâng cấp lên hợp đồng .proto mới nhất hoặc cụm .NET máy khách. Khả năng tương thích nhị phân rất quan trọng nếu bạn dự định xuất bản thư viện gRPC lên NuGet.

  • Xóa một trường - Các giá trị từ một trường đã xóa sẽ được giải tuần tự hóa thành các trường không xác định của message. Đây không phải là thay đổi phá vỡ giao thức gRPC nhưng ứng dụng khách cần được cập nhật nếu nâng cấp lên hợp đồng mới nhất. Điều quan trọng là số trường đã xóa không được vô tình sử dụng lại trong tương lai. Để đảm bảo điều này không xảy ra, hãy chỉ định số và tên trường đã xóa trên message bằng từ khóa dành riêng của Protobuf.
  • Đổi tên message - Tên message thường không được gửi trên mạng nên đây không phải là thay đổi làm hỏng giao thức gRPC. Khách hàng sẽ cần được cập nhật nếu nâng cấp lên hợp đồng mới nhất. Một tình huống trong đó tên message được gửi trên mạng là với trường Bất kỳ, khi tên message được sử dụng để xác định loại message.
  • Lồng hoặc hủy lồng một message - Các loại message có thể được lồng nhau. Việc lồng hoặc tách một message sẽ thay đổi tên message của nó. Việc thay đổi cách lồng một loại message có tác động tương tự đến khả năng tương thích như việc đổi tên.
  • Thay đổi csharp_namespace - Thay đổi csharp_namespace sẽ thay đổi namespace của các loại .NET được tạo. Đây không phải là thay đổi phá vỡ giao thức gRPC nhưng ứng dụng khách cần được cập nhật nếu nâng cấp lên hợp đồng mới nhất.

Thay đổi phá vỡ giao thức

Các mục sau đây là các thay đổi vi phạm giao thức và nhị phân:

  • Đổi tên trường - Với nội dung Protobuf, tên trường chỉ được sử dụng trong mã được tạo. Số trường được sử dụng để xác định các trường trên mạng. Đổi tên trường không phải là thay đổi phá vỡ giao thức đối với Protobuf. Tuy nhiên, nếu máy chủ đang sử dụng nội dung JSON thì việc đổi tên trường là một thay đổi có thể xảy ra.
  • Thay đổi kiểu dữ liệu trường - Việc thay đổi kiểu dữ liệu của trường thành kiểu không tương thích sẽ gây ra lỗi khi giải tuần tự hóa message. Ngay cả khi loại dữ liệu mới tương thích, có thể khách hàng cần được cập nhật để hỗ trợ loại mới nếu nâng cấp lên hợp đồng mới nhất.
  • Thay đổi số trường - Với tải trọng Protobuf, số trường được sử dụng để xác định các trường trên mạng.
  • Đổi tên gói, dịch vụ hoặc phương thức - gRPC sử dụng tên gói, tên dịch vụ và tên phương thức để tạo URL. Máy khách nhận được trạng thái KHÔNG HOÀN TOÀN từ máy chủ.
  • Xóa dịch vụ hoặc phương thức - Máy khách nhận được trạng thái KHÔNG HOÀN TOÀN từ máy chủ khi gọi phương thức đã xóa.

Thay đổi hành vi phá vỡ

Khi thực hiện các thay đổi không gây đột phá, bạn cũng phải xem xét liệu các máy khách cũ hơn có thể tiếp tục làm việc với hành vi dịch vụ mới hay không. Ví dụ: thêm trường mới vào message yêu cầu:

  • Đây không phải là một thay đổi phá vỡ giao thức.
  • Việc trả về trạng thái lỗi trên máy chủ nếu trường mới không được đặt sẽ khiến nó trở thành một thay đổi có thể xảy ra đối với các máy khách cũ.

Khả năng tương thích hành vi được xác định bởi mã dành riêng cho ứng dụng của bạn.

Dịch vụ số phiên bản

Các dịch vụ nên cố gắng duy trì khả năng tương thích ngược với các máy khách cũ. Cuối cùng, những thay đổi đối với ứng dụng của bạn có thể yêu cầu những thay đổi đột phá. Phá vỡ các máy khách cũ và buộc chúng phải cập nhật cùng với dịch vụ của bạn không phải là trải nghiệm tốt cho người dùng. Một cách để duy trì khả năng tương thích ngược trong khi thực hiện các thay đổi đột phá là xuất bản nhiều phiên bản của một dịch vụ.

gRPC hỗ trợ một trình xác định gói tùy chọn, có chức năng giống như một namespace .NET. Trong thực tế, package sẽ được sử dụng làm namespace .NET cho các loại .NET được tạo nếu option csharp_namespace không được thiết đặt trong file .proto. Gói này có thể được sử dụng để chỉ định số phiên bản cho dịch vụ của bạn và các message của dịch vụ đó:

syntax = "proto3";

package greet.v1;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply);
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

Tên gói được kết hợp với tên dịch vụ để xác định địa chỉ dịch vụ. Một địa chỉ dịch vụ cho phép nhiều phiên bản của một dịch vụ được lưu trữ cạnh nhau:

  • greet.v1.Greeter
  • greet.v2.Greeter

Việc triển khai dịch vụ được phiên bản được đăng ký tại Startup.cs:

app.UseEndpoints(endpoints =>
{
    // Implements greet.v1.Greeter
    endpoints.MapGrpcService<GreeterServiceV1>();

    // Implements greet.v2.Greeter
    endpoints.MapGrpcService<GreeterServiceV2>();
});

Việc bao gồm số phiên bản trong tên gói mang đến cho bạn cơ hội xuất bản phiên bản v2 của dịch vụ với những thay đổi quan trọng, đồng thời tiếp tục hỗ trợ các khách hàng cũ gọi phiên bản v1. Khi khách hàng đã cập nhật để sử dụng dịch vụ v2 , bạn có thể chọn xóa phiên bản cũ. Khi lập kế hoạch xuất bản nhiều phiên bản của một dịch vụ:

  • Tránh phá vỡ các thay đổi nếu hợp lý.
  • Không cập nhật số phiên bản trừ khi thực hiện các thay đổi đột phá.
  • Hãy cập nhật số phiên bản khi bạn thực hiện các thay đổi đột phá.

Xuất bản nhiều phiên bản của một dịch vụ sẽ sao chép nó. Để giảm sự trùng lặp, hãy cân nhắc việc chuyển logic nghiệp vụ từ việc triển khai dịch vụ sang một vị trí tập trung mà các hoạt động triển khai cũ và mới có thể tái sử dụng:

using Greet.V1;
using Grpc.Core;
using System.Threading.Tasks;

namespace Services
{
    public class GreeterServiceV1 : Greeter.GreeterBase
    {
        private readonly IGreeter _greeter;
        public GreeterServiceV1(IGreeter greeter)
        {
            _greeter = greeter;
        }

        public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
        {
            return Task.FromResult(new HelloReply
            {
                Message = _greeter.GetHelloMessage(request.Name)
            });
        }
    }
}

Các dịch vụ và message được tạo với các tên gói khác nhau là các loại .NET khác nhau. Việc di chuyển logic nghiệp vụ đến một vị trí tập trung yêu cầu ánh xạ message tới các kiểu phổ biến.

Tài nguyên bổ sung

Nguồn: learn.microsoft.com
» Tiếp: Kiểm thử dịch vụ gRPC trong ASP.NET Core
« Trước: Tạo message Protobuf cho ứng dụng .NET
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 !!!