Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento článek obsahuje pokyny k migraci pro upgrade mezi hlavními Orleans verzemi. Zvolte cílovou verzi pomocí výše uvedeného selektoru verzí.
Migrace z Orleans verze 7.0 na 10.0
Orleans 10.0 představuje několik nových funkcí, včetně integrovaného řídicího panelu. Tato část popisuje změny potřebné k migraci z Orleans 7.0 na 10.0, včetně mezikroků přes 8.0 a 9.0.
Souhrn zásadních změn
| Zásadní změna | Dopad | Migrace |
|---|---|---|
AddGrainCallFilter odstraněný |
Chyba kompilace | Použijte AddIncomingGrainCallFilter |
LeaseAquisitionPeriod oprava překlepu |
Chyba kompilace | Použijte LeaseAcquisitionPeriod |
LoadSheddingLimit Přejmenován |
Chyba kompilace | Použijte CpuThreshold |
CancelRequestOnTimeout výchozí nastavení změněno |
Behaviorální | Explicitně nastaveno na true v případě potřeby |
Zprostředkovatel ADO.NET vyžaduje Microsoft.Data.SqlClient |
Chyba kompilace/modulu runtime | Nahradit System.Data.SqlClient balíček |
[Unordered] atribut zastaralé |
Výstraha | Odebrat atribut (nemá žádný vliv) |
OrleansConstructorAttribute zastaralé |
Výstraha | Použití GeneratedActivatorConstructorAttribute nebo ActivatorUtilitiesConstructorAttribute pouze pro konstruktory, které vyžadují injektáž závislostí, nikoli pro serializované vlastnosti dat |
RegisterTimer zastaralé |
Výstraha | Použijte RegisterGrainTimer |
Aktualizace balíčků
Aktualizujte odkazy na balíčky NuGet z Orleans verze 7.x na 10.0:
| Orleans Balíček 7.x | Orleans Balíček 10.0 |
|---|---|
Microsoft.Orleans.Server 7.x |
Microsoft.Orleans.Server 10.0.0 |
Microsoft.Orleans.Client 7.x |
Microsoft.Orleans.Client 10.0.0 |
Microsoft.Orleans.Sdk 7.x |
Microsoft.Orleans.Sdk 10.0.0 |
Microsoft.Orleans.Streaming.EventHubs 7.x |
Microsoft.Orleans.Streaming.EventHubs 10.0.0 |
Microsoft.Orleans.Streaming.AzureStorage 7.x |
Microsoft.Orleans.Streaming.AzureStorage 10.0.0 |
Microsoft.Orleans.Persistence.AzureStorage 7.x |
Microsoft.Orleans.Persistence.AzureStorage 10.0.0 |
Microsoft.Orleans.Clustering.AzureStorage 7.x |
Microsoft.Orleans.Clustering.AzureStorage 10.0.0 |
Zásadní změna: AddGrainCallFilter nahrazeno AddIncomingGrainCallFilter
Metoda rozšíření AddGrainCallFilter na IServiceCollection byla odebrána. Nahraďte ho AddIncomingGrainCallFilter na ISiloBuilder nebo IClientBuilder.
// Orleans 7.x (no longer works)
services.AddGrainCallFilter(new MyFilter());
services.AddGrainCallFilter<MyFilter>();
// Orleans 10.0
siloBuilder.AddIncomingGrainCallFilter(new MyFilter());
siloBuilder.AddIncomingGrainCallFilter<MyFilter>();
// Or using a delegate
siloBuilder.AddIncomingGrainCallFilter(async context =>
{
// Before grain call
await context.Invoke();
// After grain call
});
Pro odchozí volání od klientů použijte AddOutgoingGrainCallFilter:
siloBuilder.AddOutgoingGrainCallFilter<MyOutgoingFilter>();
clientBuilder.AddOutgoingGrainCallFilter<MyOutgoingFilter>();
Zásadní změna: LeaseAquisitionPeriod oprava překlepu
Chybně napsaná vlastnost LeaseAquisitionPeriod v LeaseBasedQueueBalancerOptions byla opravena na LeaseAcquisitionPeriod.
// Orleans 7.x (typo)
options.LeaseAquisitionPeriod = TimeSpan.FromSeconds(30);
// Orleans 10.0 (corrected)
options.LeaseAcquisitionPeriod = TimeSpan.FromSeconds(30);
Změna způsobující chybu: LoadSheddingLimit přejmenováno na CpuThreshold
Vlastnost LoadSheddingLimit v LoadSheddingOptions byla přejmenována na CpuThreshold, aby lépe odrážela svůj účel.
// Orleans 7.x
siloBuilder.Configure<LoadSheddingOptions>(options =>
{
options.LoadSheddingEnabled = true;
options.LoadSheddingLimit = 95; // No longer works
});
// Orleans 10.0
siloBuilder.Configure<LoadSheddingOptions>(options =>
{
options.LoadSheddingEnabled = true;
options.CpuThreshold = 95; // Use this instead
});
Kritická změna: CancelRequestOnTimeout výchozí nastavení bylo změněno
Výchozí hodnota MessagingOptions.CancelRequestOnTimeout se změnila z true hodnoty na false. To znamená, že ve výchozím nastavení Orleans již po vypršení časového limitu volání grainu neodesílá zprávu o zrušení.
Pokud vaše aplikace závisí na předchozím chování, explicitně nastavte tuto možnost:
siloBuilder.Configure<SiloMessagingOptions>(options =>
{
options.CancelRequestOnTimeout = true;
});
// For clients
clientBuilder.Configure<ClientMessagingOptions>(options =>
{
options.CancelRequestOnTimeout = true;
});
Zásadní změna: Poskytovatel ADO.NET vyžaduje Microsoft.Data.SqlClient
Poskytovatelé ADO.NET (clustering, trvalost, připomenutí) teď místo Microsoft.Data.SqlClient vyžadují System.Data.SqlClient. Aktualizace odkazů na projekt:
<!-- Remove -->
<PackageReference Include="System.Data.SqlClient" Version="..." />
<!-- Add -->
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.0" />
Invariantní název se také změnil:
// Orleans 7.x
options.Invariant = "System.Data.SqlClient";
// Orleans 10.0
options.Invariant = "Microsoft.Data.SqlClient";
Zásadní změna: [Unordered] atribut zastaralý
Atribut [Unordered] pro rozhraní grain je nyní zastaralý a nemá žádný vliv. Řazení zpráv nebylo nikdy zaručeno bez ohledu na tento atribut. Odeberte atribut z kódu:
// Orleans 7.x
[Unordered]
public interface IMyGrain : IGrainWithStringKey
{
Task DoSomething();
}
// Orleans 10.0 - just remove the attribute
public interface IMyGrain : IGrainWithStringKey
{
Task DoSomething();
}
Zásadní změna: OrleansConstructorAttribute zastaralé
Bylo OrleansConstructorAttribute prohlášeno za zastaralé. Použijte GeneratedActivatorConstructorAttribute nebo ActivatorUtilitiesConstructorAttribute místo toho. Tyto atributy použijte pouze u konstruktorů, které vyžadují vložení služeb prostřednictvím injektáže závislostí. Nepoužívejte je k označení, jak Orleans by měly být nastaveny serializované vlastnosti nebo pole dat.
public interface IMyDependency
{
}
// Orleans 7.x
[GenerateSerializer]
public class MyClass
{
[Id(0)]
public string Value { get; set; }
[OrleansConstructor] // Obsolete and ignored
public MyClass(IMyDependency dependency)
{
Dependency = dependency;
}
[field: NonSerialized]
public IMyDependency Dependency { get; }
}
// Orleans 10.0
[GenerateSerializer]
public class MyClass
{
[Id(0)]
public string Value { get; set; }
[GeneratedActivatorConstructor]
public MyClass(IMyDependency dependency)
{
Dependency = dependency;
}
[field: NonSerialized]
public IMyDependency Dependency { get; }
}
Zásadní změna: RegisterTimer zastaralé
Metoda Grain.RegisterTimer je zastaralá. Místo toho použijte nové RegisterGrainTimer metody rozšíření, které poskytují lepší kontrolu nad chováním časovače.
// Orleans 7.x
public override Task OnActivateAsync(CancellationToken cancellationToken)
{
RegisterTimer(
callback: DoWork,
state: null,
dueTime: TimeSpan.FromSeconds(1),
period: TimeSpan.FromSeconds(10));
return Task.CompletedTask;
}
// Orleans 10.0
public override Task OnActivateAsync(CancellationToken cancellationToken)
{
this.RegisterGrainTimer(
callback: DoWork,
state: (object?)null,
options: new GrainTimerCreationOptions
{
DueTime = TimeSpan.FromSeconds(1),
Period = TimeSpan.FromSeconds(10),
Interleave = true // Set to true for same behavior as old RegisterTimer
});
return Task.CompletedTask;
}
Důležité
Ve výchozím nastavení RegisterGrainTimer používá Interleave = false, což zabraňuje časování zpětného volání v prolínání s jinými voláními grán. Pokud potřebujete staré chování, kdy zpětná volání časovače se mohou překrývat, explicitně nastavte Interleave = true.
Nové funkce ve verzi Orleans 10.0
Po migraci můžete využít tyto nové funkce:
- Orleans Řídicí panel: Integrované webové monitorování clusteru
Migrace z Orleans verze 8.0 na 9.0
Pokud upgradujete z Orleans verze 8.x, všimněte si těchto dalších změn zavedených ve Orleans verzi 9.0:
Adresář grainů s vysokou konzistencí: Výchozí adresář grainů nyní poskytuje silnější záruky konzistence. - Úplná podpora CancellationToken: Metody grain nyní plně podporují parametry CancellationToken
- Odsazení aktivace na základě paměti: Automatická deaktivace agregace pod tlakem paměti
- Rychlejší protokol členství: Výchozí doba detekce selhání se zkrátila z 10 minut na 90 sekund.
- Výchozí umístění se změnilo na ResourceOptimized (9.2+): Výchozí strategie umístění zrna se změnila z RandomPlacement na ResourceOptimizedPlacement
Pokud vaše aplikace spoléhá na náhodné umístění, explicitně ji nakonfigurujte:
siloBuilder.Services.AddSingleton<PlacementStrategy, RandomPlacement>();
// Or on specific grains
[RandomPlacement]
public class MyGrain : Grain, IMyGrain { }
Migrace z Orleans verze 7.0 na 8.0
Pokud upgradujete z Orleans verze 7.x, všimněte si těchto změn zavedených ve Orleans verzi 8.0:
-
Nové rozhraní API časovače: RegisterGrainTimer bylo zavedeno pro nahrazení
RegisterTimer - .NET Aspire integration: Prvotřídní podpora pro .NET Aspire
- Resource-Optimized umístění: Nová strategie umístění na základě využití procesoru a paměti
- Aktivace znovurozdělení (8.2+): Experimentální funkce pro automatické vyvážení zrna
Postupné upgrady
Postupné upgrady z Orleans verze 7.x na 10.0 se nedoporučují kvůli významným změnám protokolu a rozhraní API. Namísto:
- Nasazení nového clusteru se systémem Orleans 10.0
- V případě potřeby migrujte data o stavu.
- Přepnutí provozu do nového clusteru
- Vyřazení starého clusteru z provozu
Migrace skriptů ADO.NET
Pokud používáte ADO.NET pro clustering, trvalost nebo připomenutí, použijte příslušné skripty migrace:
Migrace z Orleans verze 3.x na 7.0
Orleans 7.0 představuje několik výhodných změn, včetně vylepšení hostování, vlastní serializace, neměnnosti a abstrakce zrnitosti.
Migrace
Vzhledem ke změnám způsobu Orleans identifikace zrn a datových proudů není migrace stávajících aplikací pomocí připomenutí, datových proudů nebo trvalosti zrn na Orleans verzi 7.0 v současné době jednoduchá.
Bezproblémový upgrade aplikací s předchozími Orleans verzemi prostřednictvím postupného upgradu na Orleans verzi 7.0 není možný. Proto použijte jinou strategii upgradu, například nasazení nového clusteru a vyřazení předchozího clusteru z provozu. Orleans 7.0 mění protokol přenosu nekompatibilně, což znamená, že klastry nemohou obsahovat kombinaci Orleans serverů 7.0 a serverů s předchozími Orleans verzemi.
Bylo po mnoho let vyhýbáno takovým zásadním změnám, dokonce i v hlavních verzích. Proč teď? Existují dva hlavní důvody: identity a serializace. Pokud jde o identity, grain identity a identita proudu se nyní skládají z řetězců. To umožňuje správné kódování informací o obecném typu a usnadňuje mapování datových proudů do domény aplikace.
Orleans Dříve jsme identifikovali typy zrn pomocí komplexní datové struktury, která nemohla představovat obecná zrnka, což vedlo k rohovým případům. Streamy byly identifikovány oborem string názvů a Guid klíčem, který byl efektivní, ale obtížně namapován na doménu aplikace. Serializace je nyní tolerantní k verzím. To znamená, že typy lze upravit určitými kompatibilními způsoby podle sady pravidel s jistotou, že aplikaci lze upgradovat bez chyb serializace. Tato funkce je užitečná hlavně v případě, že typy aplikací zůstávají v datových proudech nebo v úložišti zrnitých dat. V následujících částech jsou podrobně popsány hlavní změny a podrobněji je probírají.
Změny balení
Při upgradu projektu na Orleans verzi 7.0 proveďte následující akce:
- Všichni klienti by měli odkazovat na Microsoft.Orleans. Client.
- Všechna Sila (servery) by měla odkazovat na Microsoft.Orleans.Server.
- Všechny ostatní balíčky by měly odkazovat na Microsoft.Orleans. Sdk
- Balíčky client i server obsahují odkaz na Microsoft.Orleans. Sdk
- Odeberte všechny odkazy na
Microsoft.Orleans.CodeGenerator.MSBuildaMicrosoft.Orleans.OrleansCodeGenerator.Build.- Nahraďte použití
KnownAssemblyparametrem GenerateCodeForDeclaringAssemblyAttribute. - Balíček
Microsoft.Orleans.Sdkodkazuje na balíček C# Source Generator (Microsoft.Orleans.CodeGenerator).
- Nahraďte použití
- Odeberte všechny odkazy na
Microsoft.Orleans.OrleansRuntime.-
Microsoft.Orleans. Serverové balíčky odkazují na jeho náhradu
Microsoft.Orleans.Runtime.
-
Microsoft.Orleans. Serverové balíčky odkazují na jeho náhradu
- Odeberte volání
ConfigureApplicationParts. Části aplikace byly odebrány. Zdrojový generátor pro Orleans je přidán do všech balíčků (včetně klienta a serveru) a automaticky generuje ekvivalent Částí aplikace. - Nahraďte odkazy na
Microsoft.Orleans.OrleansServiceBuss Microsoft.Orleans.Streaming.EventHubs. - Pokud používáte připomenutí, přidejte odkaz na Microsoft.Orleans. Připomenutí
- Pokud používáte streamy, přidejte odkaz na Microsoft.Orleans. Streamování
Návod
Orleans Všechny ukázky byly upgradovány na Orleans verzi 7.0 a lze je použít jako referenci na provedené změny. Další informace najdete v tématu Orleans problém č. 8035 , který uvádí změny provedené v každé ukázce.
Orleans globální direktivy using
Všechny projekty Orleans přímo nebo nepřímo odkazují na balíček NuGet Microsoft.Orleans.Sdk.
Orleans Pokud je projekt nakonfigurovaný tak, aby <ImplicitUsings>enable</ImplicitUsings> implicitní použití (například), projekt implicitně používá jak prostor názvů Orleans, tak prostor názvů Orleans.Hosting. To znamená, že kód aplikace nepotřebuje tyto using direktivy.
Další informace najdete v tématu ImplicitUsings a dotnet/orleans/src/Orleans. Sdk/build/Microsoft.Orleans. Sdk.targets
Hosting
Typ ClientBuilder je nahrazen metodou UseOrleansClient rozšíření na IHostBuilder. Typ IHostBuilder pochází z Microsoft. Extensions.Hosting balíček NuGet. To znamená, že Orleans klienta lze přidat do existujícího hostitele bez vytvoření samostatného kontejneru injektáže závislostí. Klient se připojí ke clusteru během spuštění. Po IHost.StartAsync dokončení se klient automaticky připojí. Služby přidané na IHostBuilder začátek v pořadí registrace. Volání UseOrleansClient před voláním ConfigureWebHostDefaults například zajišťuje spuštění Orleans před spuštěním ASP.NET Core, což umožňuje okamžitý přístup ke klientovi z aplikace ASP.NET Core.
Pokud chcete emulovat předchozí ClientBuilder chování, vytvořte samostatné HostBuilder a nakonfigurujte ho klientem Orleans. Může být IHostBuilder nakonfigurován buď s klientem Orleans nebo se silem Orleans. Všechna sila registrují instanci IGrainFactory a IClusterClient, které může aplikace použít, takže konfigurace klienta není tedy nutná ani podporovaná.
OnActivateAsync a OnDeactivateAsync změna podpisu
Orleans umožňuje grainům spouštět kód během aktivace a deaktivace. Pomocí této funkce můžete provádět úlohy, jako je čtení stavu z úložiště nebo protokolování zpráv životního cyklu. V Orleans 7.0 se podpis těchto metod životního cyklu změnil:
- OnActivateAsync() teď přijímá CancellationToken parametr. Po zrušení CancellationToken přerušte proces aktivace.
-
OnDeactivateAsync() nyní přijímá DeactivationReason parametr a CancellationToken parametr. Označuje
DeactivationReason, proč se aktivace deaktivuje. Tyto informace použijte pro účely protokolování a diagnostiky. Když je CancellationToken zrušeno, okamžitě dokončete proces deaktivace. Mějte na paměti, že vzhledem k tomu, že jakýkoli hostitel může kdykoli selhat, nedoporučuje se spoléhat na OnDeactivateAsync provádění důležitých akcí, jako je zachování kritického stavu.
Zvažte následující příklad instance, která přepisuje tyto nové metody:
public sealed class PingGrain : Grain, IPingGrain
{
private readonly ILogger<PingGrain> _logger;
public PingGrain(ILogger<PingGrain> logger) =>
_logger = logger;
public override Task OnActivateAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("OnActivateAsync()");
return Task.CompletedTask;
}
public override Task OnDeactivateAsync(DeactivationReason reason, CancellationToken token)
{
_logger.LogInformation("OnDeactivateAsync({Reason})", reason);
return Task.CompletedTask;
}
public ValueTask Ping() => ValueTask.CompletedTask;
}
POCO objekty a IGrainBase
Zrna už v Orleans nemusí dědit ze Grain základní třídy ani z jakékoli jiné třídy. Tato funkce se označuje jako zrnka POCO . Přístup k rozšiřujícím metodám, jako je některý z následujících způsobů:
- DeactivateOnIdle
- AsReference
- Cast
- GetPrimaryKey
- GetReminder
- GetReminders
- RegisterOrUpdateReminder
- UnregisterReminder
- GetStreamProvider
Granule musí buď implementovat IGrainBase, nebo dědit z Grain. Tady je příklad implementace IGrainBase na třídě zrno:
public sealed class PingGrain : IGrainBase, IPingGrain
{
public PingGrain(IGrainContext context) => GrainContext = context;
public IGrainContext GrainContext { get; }
public ValueTask Ping() => ValueTask.CompletedTask;
}
IGrainBase také definuje OnActivateAsync a OnDeactivateAsync s výchozími implementacemi, což umožňuje granu zapojit se do životního cyklu, pokud je to žádoucí:
public sealed class PingGrain : IGrainBase, IPingGrain
{
private readonly ILogger<PingGrain> _logger;
public PingGrain(IGrainContext context, ILogger<PingGrain> logger)
{
_logger = logger;
GrainContext = context;
}
public IGrainContext GrainContext { get; }
public Task OnActivateAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("OnActivateAsync()");
return Task.CompletedTask;
}
public Task OnDeactivateAsync(DeactivationReason reason, CancellationToken token)
{
_logger.LogInformation("OnDeactivateAsync({Reason})", reason);
return Task.CompletedTask;
}
public ValueTask Ping() => ValueTask.CompletedTask;
}
Serializace
Nejtěžnější změnou ve verzi Orleans 7.0 je zavedení serializátoru odolného proti verzi. Tato změna byla provedena, protože aplikace mají tendenci se vyvíjet, což vedlo k významnému nástrahám pro vývojáře, protože předchozí serializátor nemohl tolerovat přidávání vlastností do existujících typů. Na druhou stranu byl předchozí serializátor flexibilní a umožňoval reprezentaci většiny typů .NET bez úprav, včetně funkcí, jako jsou obecné typy, polymorfismus a sledování odkazů. Náhrada byla dávno očekávaná, ale věrné zobrazení typů je stále potřebné. Proto Orleans 7.0 zavádí náhradní serializátor podporující vysoce věrnou reprezentaci typů .NET a zároveň umožňuje vývoj typů. Nový serializátor je mnohem efektivnější než předchozí, což vede až k 170% vyšší koncové propustnosti.
Další informace najdete v následujících článcích, které se týkají Orleans verze 7.0:
Identita zrn
Každá zrna má jedinečnou identitu, která se skládá z typu zrnka a jeho klíče. Předchozí Orleans verze používaly složený typ pro GrainIds pro podporu klíčů zrnitosti:
Tento přístup zahrnuje určitou složitost při práci s datovými klíči. Identity zrní se skládá ze dvou součástí: typu a klíče. Součást typu se dříve skládala z číselného kódu typu, kategorie a 3 bajtů obecných informací o typu.
Identita zrna nyní má podobu type/key, kde oba type a key jsou řetězce. Nejčastěji používané zrnitostní klíčové rozhraní je IGrainWithStringKey. To výrazně zjednodušuje fungování identity jednotlivých částic a zlepšuje podporu obecných typů částic.
Rozhraní grainů jsou nyní reprezentována také pomocí čitelného názvu, nikoli kombinace kódu hash a řetězcové reprezentace jakýchkoli parametrů obecného typu.
Nový systém je lépe přizpůsobitelný a tato přizpůsobení je možné řídit pomocí atributů.
-
GrainTypeAttribute(String) na zrno
classurčuje část Typu jeho id zrna. -
DefaultGrainTypeAttribute(String)v agregačním intervalu určuje
interfaceagregace, který IGrainFactory se má ve výchozím nastavení vyřešit při získání odkazu na agregační interval. Například při voláníIGrainFactory.GetGrain<IMyGrain>("my-key")továrna na zrno vrátí odkaz na zrno"my-type/my-key", pokudIMyGrainmá uvedený atribut zadaný. - GrainInterfaceTypeAttribute(String) umožňuje změnu názvu rozhraní. Explicitním zadáním názvu pomocí tohoto mechanismu umožní přejmenování typu rozhraní bez narušení kompatibility s existujícími odkazy na objekty. Všimněte si, že rozhraní by mělo mít AliasAttribute také v tomto případě, protože jeho identita může být serializována. Další informace o zadání aliasu typu najdete v části o serializaci.
Jak je uvedeno výše, přepsání výchozí třídy zrnitosti a názvů rozhraní pro typy umožňuje přejmenování základních typů bez narušení kompatibility s existujícími nasazeními.
Identifikátory streamu
Při prvním vydání Orleans bylo možné datové proudy identifikovat pouze pomocí Guid. Tento přístup byl efektivní z hlediska přidělování paměti, ale vytváření smysluplných identit datových proudů bylo obtížné, často vyžaduje určité kódování nebo nepřímé určení vhodné identity datového proudu pro daný účel.
Ve Orleans verzi 7.0 se streamy identifikují pomocí řetězců. Obsahuje Orleans.Runtime.StreamIdstruct tři vlastnosti: StreamId.Namespace, StreamId.Keya StreamId.FullKey. Tyto hodnoty vlastností jsou kódované řetězce UTF-8. Podívejte se například na StreamId.Create(String, String).
Nahrazení SimpleMessageStreams pomocí BroadcastChannel
SimpleMessageStreams (označuje se také jako SMS) se odebere ve verzi 7.0. SMS měla stejné rozhraní jako Orleans.Providers.Streams.PersistentStreams, ale jeho chování bylo velmi odlišné, protože se spoléhalo na přímé volání od grain-to-grain. Aby nedošlo k nejasnostem, SMS byla odstraněna a byla představena nová náhrada Orleans.BroadcastChannel.
BroadcastChannel podporuje pouze implicitní předplatná a v tomto případě může být přímým nahrazením. Pokud jsou potřeba explicitní předplatná nebo je nutné použít rozhraní PersistentStream (například pokud se v testech používala SMS a v produkčním prostředí EventHub), pak je MemoryStream nejlepším kandidátem.
BroadcastChannel má stejné chování jako SMS, zatímco MemoryStream se chová jako ostatní poskytovatelé datových proudů. Představte si následující příklad použití kanálu broadcastu:
// Configuration
builder.AddBroadcastChannel(
"my-provider",
options => options.FireAndForgetDelivery = false);
// Publishing
var grainKey = Guid.NewGuid().ToString("N");
var channelId = ChannelId.Create("some-namespace", grainKey);
var stream = provider.GetChannelWriter<int>(channelId);
await stream.Publish(1);
await stream.Publish(2);
await stream.Publish(3);
// Simple implicit subscriber example
[ImplicitChannelSubscription]
public sealed class SimpleSubscriberGrain : Grain, ISubscriberGrain, IOnBroadcastChannelSubscribed
{
// Called when a subscription is added to the grain
public Task OnSubscribed(IBroadcastChannelSubscription streamSubscription)
{
streamSubscription.Attach<int>(
item => OnPublished(streamSubscription.ChannelId, item),
ex => OnError(streamSubscription.ChannelId, ex));
return Task.CompletedTask;
// Called when an item is published to the channel
static Task OnPublished(ChannelId id, int item)
{
// Do something
return Task.CompletedTask;
}
// Called when an error occurs
static Task OnError(ChannelId id, Exception ex)
{
// Do something
return Task.CompletedTask;
}
}
}
Migrace na MemoryStream je jednodušší, protože je třeba změnit pouze konfiguraci. Zvažte následující MemoryStream konfiguraci:
builder.AddMemoryStreams<DefaultMemoryMessageBodySerializer>(
"in-mem-provider",
_ =>
{
// Number of pulling agent to start.
// DO NOT CHANGE this value once deployed, if you do rolling deployment
_.ConfigurePartitioning(partitionCount: 8);
});
OpenTelemetry
Systém telemetrie se aktualizuje v Orleans 7.0 a předchozí systém se odebere ve prospěch standardizovaných rozhraní API .NET, jako jsou .NET Metrics pro metriky a ActivitySource pro trasování.
V této části se odeberou existující balíčky Microsoft.Orleans.TelemetryConsumers.*. Nová sada balíčků je zvažována pro usnadnění integrace metrik emitovaných Orleans do zvoleného monitorovacího řešení. Jako vždy vítáme zpětnou vazbu a příspěvky.
Nástroj dotnet-counters nabízí monitorování výkonu pro monitorování stavu ad hoc a prošetření výkonu na první úrovni. Pro Orleans čítače použijte nástroj dotnet-counters k jejich monitorování.
dotnet counters monitor -n MyApp --counters Microsoft.Orleans
Podobně přidejte metriky Microsoft.Orleans do metrik OpenTelemetry, jak je znázorněno v následujícím kódu:
builder.Services.AddOpenTelemetry()
.WithMetrics(metrics => metrics
.AddPrometheusExporter()
.AddMeter("Microsoft.Orleans"));
Pokud chcete povolit distribuované trasování, nakonfigurujte OpenTelemetry, jak je znázorněno v následujícím kódu:
builder.Services.AddOpenTelemetry()
.WithTracing(tracing =>
{
tracing.SetResourceBuilder(ResourceBuilder.CreateDefault()
.AddService(serviceName: "ExampleService", serviceVersion: "1.0"));
tracing.AddAspNetCoreInstrumentation();
// Good baseline for general Orleans observability
tracing.AddSource(Orleans.Diagnostics.ActivitySources.ApplicationGrainActivitySourceName);
tracing.AddSource(Orleans.Diagnostics.ActivitySources.LifecycleActivitySourceName);
/*
// Other source also available
// Persistence spans
tracing.AddSource(Orleans.Diagnostics.ActivitySources.StorageActivitySourceName);
// Internal Runtime spans
tracing.AddSource(Orleans.Diagnostics.ActivitySources.RuntimeActivitySourceName);
*/
/*
// Optionally add all Microsoft.Orleans.* Sources at once
tracing.AddSource(Orleans.Diagnostics.ActivitySources.AllActivitySourceName);
*/
tracing.AddZipkinExporter(options =>
{
options.Endpoint = new Uri("http://localhost:9411/api/v2/spans");
});
});
V předchozím kódu je OpenTelemetry nakonfigurovaná tak, aby monitorovala:
Microsoft.Orleans.ApplicationMicrosoft.Orleans.Lifecycle
Pokud chcete aktivitu rozšířit, zavolejte AddActivityPropagation:
builder.Host.UseOrleans((_, clientBuilder) =>
{
clientBuilder.AddActivityPropagation();
});
Přesunutí vlastností ze základního balíčku do samostatných balíčků
Ve verzi Orleans 7.0 byla rozšíření rozdělena do samostatných balíčků, které nejsou závislé na Orleans.Core. Konkrétně , Orleans.Streaminga Orleans.RemindersOrleans.Transactions byly odděleny od jádra. To znamená, že tyto balíčky jsou zcela placené za to, co se používá, a žádný kód v jádru Orleans není vyhrazený pro tyto funkce. Tento přístup snižuje plochu a velikost základního rozhraní API, zjednodušuje jádro a zlepšuje výkon. Pokud jde o výkon, transakce Orleans dříve vyžadovaly provádění určitého kódu pro každou metodu, aby se koordinovaly potenciální transakce. Tato koordinační logika je nyní přesunuta na úroveň jednotlivých metod.
Jedná se o změnu narušující kompilaci. Stávající kód, který komunikuje s připomenutími nebo datovými proudy voláním metod dříve definovaných v Grain základní třídě, může přestat fungovat, protože se teď jedná o rozšiřující metody. Aktualizujte volání, která nezadávají this (např. GetReminders), tak, aby zahrnovala this (např. this.GetReminders()), protože metody rozšíření musí být kvalifikované. K chybě kompilace dochází, pokud tato volání nejsou aktualizována a požadovaná změna kódu nemusí být zřejmé, aniž byste věděli, co se změnilo.
Klient transakcí
Orleans7.0 zavádí novou abstrakci pro koordinace transakcí: Orleans.ITransactionClient Dříve mohly transakce koordinovat pouze zrnka. S ITransactionClient, dostupným prostřednictvím injekce závislostí, mohou klienti také koordinovat transakce bez potřeby zprostředkující složky. Následující příklad stáhne kredity z jednoho účtu a uloží je do jiné v rámci jedné transakce. Tento kód volejte z gránu nebo z externího klienta, který ji načetl z kontejneru pro injektáž závislostí.
await transactionClient.RunTransaction(
TransactionOption.Create,
() => Task.WhenAll(from.Withdraw(100), to.Deposit(100)));
U transakcí koordinovaných klientem musí klient během konfigurace přidat požadované služby:
clientBuilder.UseTransactions();
Ukázka BankAccount ukazuje použití ITransactionClient. Další informace naleznete v tématu Orleans transakce.
Znovuvstupnost řetězce volání
Ve výchozím nastavení jsou instance jednovláknové a zpracovávají požadavky jeden po druhém od začátku do konce. Jinými slovy, vlákna nejsou ve výchozím nastavení znovuvstupná. Přidání ReentrantAttribute do třídy zrnitosti umožňuje zrnitosti zpracovávat více požadavků souběžně způsobem střídavého zpracování, zatímco stále běží na jednom vláknu. Tato funkce může být užitečná pro zrní, která nemají žádný vnitřní stav nebo provádějí mnoho asynchronních operací, jako je vydávání volání HTTP nebo zápis do databáze. Při prokládání požadavků je potřeba zvláštní péče: je možné, že stav agregačního intervalu pozorovaný před provedením await příkazu se změní v době, kdy se asynchronní operace dokončí, a metoda obnoví provádění.
Například následující jednotka reprezentuje čítač. Je označený ReentrantAttribute, což umožňuje prokládání více volání. Metoda Increment() by měla zvýšit vnitřní čítač a vrátit pozorovanou hodnotu. Vzhledem k tomu, že Increment() tělo metody sleduje stav zrna před await bodem a následně jej aktualizuje, může několik proložených provedení Increment() způsobit, že _value bude menší než celkový počet přijatých Increment() volání. Jedná se o chybu způsobenou nesprávným použitím znovuvstupu.
Odebrání ReentrantAttribute je dostatečné k vyřešení tohoto problému.
[Reentrant]
public sealed class CounterGrain : Grain, ICounterGrain
{
int _value;
/// <summary>
/// Increments the grain's value and returns the previous value.
/// </summary>
public Task<int> Increment()
{
// Do not copy this code, it contains an error.
var currentVal = _value;
await Task.Delay(TimeSpan.FromMilliseconds(1_000));
_value = currentVal + 1;
return currentValue;
}
}
Aby se předešlo těmto chybám, jsou zrna ve výchozím nastavení nereentrantní. Nevýhodou je snížená propustnost pro zrnka, která provádějí asynchronní operace v implementaci, protože zrnko nemůže zpracovávat jiné požadavky během čekání na dokončení asynchronní operace. Chcete-li to zmírnit, Orleans nabízí několik možností, jak v některých případech umožnit opakované zařazení:
- Pro celou třídu: Umístění ReentrantAttribute na granulu umožňuje jakýkoli požadavek prolínat se s jakýmkoli jiným požadavkem.
- Pro podmnožinu metod: Umístění AlwaysInterleaveAttribute na metodě rozhraní mezi zrnky umožňuje prokládání požadavků této metody s jakýmkoli jiným požadavkem a umožňuje jakýmkoli jiným požadavkům prokládání požadavků na tuto metodu.
- Pro podmnožinu metod: Umístění ReadOnlyAttribute na rozhraní zrna metody umožňuje prokládání žádostí k této metodě s jakýmkoli jiným požadavkem a umožňuje jakémukoli jinému ReadOnlyAttribute požadavku prokládání žádostí k dané metodě. V tomto smyslu je to omezenější forma AlwaysInterleaveAttribute.
- Pro všechny žádosti v rámci řetězu volání: RequestContext.AllowCallChainReentrancy() a RequestContext.SuppressCallChainReentrancy() umožňují přepínání mezi povolením a zamítnutím, aby následné požadavky znovu vstoupily do procesu. Obě volání vrací hodnotu, která musí být uvolněna při ukončení požadavku. Proto je použijte takto:
public Task<int> OuterCall(IMyGrain other)
{
// Allow call-chain reentrancy for this grain, for the duration of the method.
using var _ = RequestContext.AllowCallChainReentrancy();
await other.CallMeBack(this.AsReference<IMyGrain>());
}
public Task CallMeBack(IMyGrain grain)
{
// Because OuterCall allowed reentrancy back into that grain, this method
// will be able to call grain.InnerCall() without deadlocking.
await grain.InnerCall();
}
public Task InnerCall() => Task.CompletedTask;
Povolit znovuvstup do řetězce volání po jednotlivých jednotkách a jednotlivých řetězcích volání. Představme si například dva grains, A a B. Pokud grain A umožňuje reentrantnost řetězce volání před voláním grain B, může se grain B vrátit zavoláním do grain A v tomto volání. Zrno A však nemůže volat zpět do zrna B, pokud zrno B také nepovolilo znovuzavázání řetězce volání. Je povoleno pro každé zrno, pro každý řetězec volání.
Zrna mohou také potlačit informace o znovuvstupu do řetězce volání, aby zabránila jejich toku dolů řetězcem volání pomocí using var _ = RequestContext.SuppressCallChainReentrancy(). Tím se zabrání opětovnému zadání dalších volání.
Migrace skriptů ADO.NET
K zajištění kompatibility s Orleans clusteringem, trvalostí a připomenutími závislými na ADO.NET je potřeba příslušný skript migrace SQL:
Vyberte soubory pro použitou databázi a použijte je v pořadí.
Migrace z Orleans verze 3.x na 7.0
Pro Orleans uživatele verze 3.x postupujte podle pokynů k migraci v Orleans části dokumentace 7.0 pomocí výše uvedeného selektoru verzí.
Důležité
Orleans Verze 3.x již není podporována. Zvažte migraci na Orleans verzi 10.0 pro nejnovější funkce a aktualizace zabezpečení.