Orleans průvodci migrací

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:

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:

  1. Nasazení nového clusteru se systémem Orleans 10.0
  2. V případě potřeby migrujte data o stavu.
  3. Přepnutí provozu do nového clusteru
  4. 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:

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:

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ů:

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 class určuje část Typu jeho id zrna.
  • DefaultGrainTypeAttribute(String)v agregačním intervalu určuje interface agregace, 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", pokud IMyGrain má 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.Application
  • Microsoft.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í.