Správa verzí služeb gRPC
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Upozorňující
Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v tématu .NET a .NET Core Zásady podpory. Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Důležité
Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Aktuální verzi najdete ve verzi .NET 8 tohoto článku.
Autor: James Newton-King
Nové funkce přidané do aplikace můžou vyžadovat, aby se služby gRPC poskytované klientům měnily, někdy neočekávanými a zásadními způsoby. Při změně služeb gRPC:
- Je třeba vzít v úvahu, jaký vliv mají změny na klienty.
- Je třeba implementovat strategii správy verzí pro podporu změn.
Zpětná kompatibilita
Protokol gRPC je navržený tak, aby podporoval služby, které se v průběhu času mění. Obecně platí, že doplňky ke službám a metodám gRPC nejsou zásadní. Nefunkční změny umožňují stávajícím klientům pokračovat v práci beze změn. Změny nebo odstranění služeb gRPC jsou zásadními změnami. Pokud mají služby gRPC zásadní změny, musí se klienti používající danou službu aktualizovat a znovu nasadit.
Provádění nerušných změn ve službě má řadu výhod:
- Stávající klienti budou dál spouštět.
- Vyhněte se práci související s upozorňováním klientů na zásadní změny a jejich aktualizací.
- Musí být zdokumentována a udržována pouze jedna verze služby.
Nepřerušované změny
Tyto změny nejsou zásadní na úrovni protokolu gRPC a na binární úrovni .NET.
- Přidání nové služby
- Přidání nové metody do služby
- Přidání pole do zprávy požadavku – Pole přidaná do zprávy požadavku se deserializují s výchozí hodnotou na serveru, pokud není nastavená. Aby se změna nezměnila, musí být služba úspěšná, pokud není nové pole nastaveno staršími klienty.
- Přidání pole do zprávy odpovědi – Pokud se starší klient neaktualizoval s novým polem, hodnota se deserializuje do kolekce neznámých polí zprávy odpovědi.
- Přidání hodnoty do výčtu – výčty jsou serializovány jako číselná hodnota. Nové hodnoty výčtu jsou deserializovány v klientovi na hodnotu výčtu bez názvu výčtu. Aby došlo ke změně způsobující chybu, musí starší klienti při přijímání nové hodnoty výčtu běžet správně.
Binární zásadní změny
Následující změny nejsou zásadní na úrovni protokolu gRPC, ale klient se musí aktualizovat, pokud upgraduje na nejnovější .proto
kontrakt nebo klientské sestavení .NET. Binární kompatibilita je důležitá, pokud plánujete publikovat knihovnu gRPC do NuGetu.
- Odebrání pole – Hodnoty z odebraného pole se deserializují na neznámá pole zprávy. Nejedná se o změnu způsobující chybu protokolu gRPC, ale klient se musí aktualizovat, pokud upgraduje na nejnovější kontrakt. Je důležité, aby se odebrané číslo pole v budoucnu nechtěně znovu použilo. Pokud chcete zajistit, aby k tomu nedošlo, zadejte odstraněná čísla polí a názvy ve zprávě pomocí vyhrazeného klíčového slova Protobuf.
- Přejmenování zprávy – Názvy zpráv se obvykle neodesílají v síti, takže se nejedná o změnu způsobující chybu protokolu gRPC. Klient se bude muset aktualizovat, pokud upgraduje na nejnovější kontrakt. Jedna situace, kdy se v síti odesílají jména zpráv, je jakákoli pole, když se název zprávy používá k identifikaci typu zprávy.
- Vnoření nebo zrušení nenesování zprávy – Typy zpráv můžou být vnořené. Vnoření nebo zrušení označení zprávy změní název zprávy. Změna způsobu vnoření typu zprávy má stejný vliv na kompatibilitu jako přejmenování.
- Změna csharp_namespace – Změna
csharp_namespace
změní obor názvů vygenerovaných typů .NET. Nejedná se o změnu způsobující chybu protokolu gRPC, ale klient se musí aktualizovat, pokud upgraduje na nejnovější kontrakt.
Změny způsobující protokol
Následující položky jsou protokolové a binární zásadní změny:
- Přejmenování pole – s obsahem Protobuf se názvy polí používají pouze ve vygenerovaném kódu. Číslo pole slouží k identifikaci polí v síti. Přejmenování pole není změna způsobující chybu protokolu pro Protobuf. Pokud ale server používá obsah JSON, přejmenování pole je zásadní změnou.
- Změna datového typu pole – Změna datového typu pole na nekompatibilní typ způsobí chyby při deserializaci zprávy. I když je nový datový typ kompatibilní, je pravděpodobné, že klient musí být aktualizován tak, aby podporoval nový typ, pokud upgraduje na nejnovější kontrakt.
- Změna čísla pole – u datových částí Protobuf se číslo pole používá k identifikaci polí v síti.
- Přejmenování balíčku, služby nebo metody – gRPC používá k sestavení adresy URL název balíčku, název služby a název metody. Klient získá ze serveru stav UNIMPLEMENTED .
- Odebrání služby nebo metody – Klient při volání odebrané metody získá ze serveru stav UNIMPLEMENTED .
Změny způsobující chování
Připrováděních Například přidání nového pole do zprávy požadavku:
- Není to změna způsobující chybu protokolu.
- Pokud nové pole není nastavené, vrátí se na serveru stav chyby, způsobí to zásadní změnu pro staré klienty.
Kompatibilitu chování určuje kód specifický pro vaši aplikaci.
Služby číslování verzí
Služby by se měly snažit zůstat zpětně kompatibilní se starými klienty. Změny aplikace nakonec můžou vyžadovat zásadní změny. Porušení starých klientů a vynucení jejich aktualizace spolu s vaší službou není dobrým uživatelským prostředím. Způsob, jak zachovat zpětnou kompatibilitu při provádění zásadních změn, je publikovat více verzí služby.
gRPC podporuje volitelný specifikátor balíčku , který funguje podobně jako obor názvů .NET. Ve skutečnosti se použije jako obor názvů .NET pro vygenerované typy .NET, package
pokud option csharp_namespace
není v .proto
souboru nastaven. Balíček lze použít k zadání čísla verze pro vaši službu a jejích zpráv:
syntax = "proto3";
package greet.v1;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply);
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
Název balíčku se zkombinuje s názvem služby a identifikuje adresu služby. Adresa služby umožňuje hostování více verzí služby vedle sebe:
greet.v1.Greeter
greet.v2.Greeter
Implementace služby s verzí jsou registrovány v Startup.cs
:
app.UseEndpoints(endpoints =>
{
// Implements greet.v1.Greeter
endpoints.MapGrpcService<GreeterServiceV1>();
// Implements greet.v2.Greeter
endpoints.MapGrpcService<GreeterServiceV2>();
});
Zahrnutím čísla verze do názvu balíčku získáte možnost publikovat verzi služby verze 2 s zásadními změnami a zároveň nadále podporovat starší klienty, kteří volají verzi v1 . Jakmile se klienti aktualizují tak, aby používali službu v2 , můžete starou verzi odebrat. Při plánování publikování více verzí služby:
- Pokud je to rozumné, vyhněte se zásadním změnám.
- Neaktualizovat číslo verze, pokud neuděláte zásadní změny.
- Aktualizujte číslo verze, když provedete zásadní změny.
Publikování více verzí služby ho duplikuje. Pokud chcete snížit duplicitu, zvažte přesun obchodní logiky z implementací služby do centralizovaného umístění, které je možné znovu použít ve starých a nových implementacích:
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)
});
}
}
}
Služby a zprávy vygenerované s různými názvy balíčků jsou různé typy .NET. Přesun obchodní logiky do centralizovaného umístění vyžaduje mapování zpráv na běžné typy.