Orleans 的大部分API在2.0中保持不变,或者这些API的实现保留旧版类中,以实现向后兼容。同时,新引入的API提供了一些新功能或更好的方法,来完成这些任务。在.NET SDK工具和Visual Studio支持方面,还有一些更多细微的差别,这有助于大家了解它。本文档提供了将应用程序代码迁移到Orleans 2.0的指导。
Orleans 2.0.0构建于.NET Standard 2.0之上。因此,您需要升级开发工具,以确保自己获得愉快的开发体验。我们建议使用Visual Studio 2017或更高版本,来开发Orleans 2.0.0应用程序。根据我们的经验,15.5.2及更高版本效果最佳。.NET Standard 2.0.0与.NET 4.6.1及更高版本、.NET Core 2.0,以及一些其他的框架列表相兼容。Orleans 2.0.0继承了兼容性。有关.NET Standard与其他框架兼容性的更多信息,请参阅.NET标准文档:如果您正在使用Orleans开发.NET Core或.NET应用程序,则需要按照特定步骤设置环境,例如安装.NET Core SDK。有关更多信息,请参阅他们的文档。
Orleans 2.0中有许多新的选项类,为配置silo提供了一种新的方式。为了便于迁移到新API,有一个可选的向后兼容包Microsoft.Orleans.Runtime.Legacy
,它提供了从旧的1.x配置API到新的API的桥梁。
如果添加Microsoft.Orleans.Runtime.Legacy
包,仍然可以通过遗留的ClusterConfiguration
对象以编程方式配置silo,然后可以将其传递SiloHostBuilder
,以构建并启动silo。
您仍然需要通过ConfigureApplicationParts
调用,来指定grain类的程序集。
以下是如何以传统方式,配置本地silo的示例:
public class Program
{
public static async Task Main(string[] args)
{
try
{
var host = await StartSilo();
Console.WriteLine("Press Enter to terminate...");
Console.ReadLine();
await host.StopAsync();
return 0;
}
catch (Exception ex)
{
Console.WriteLine(ex);
return 1;
}
}
private static async Task StartSilo()
{
// define the cluster configuration (temporarily required in the beta version,
// will not be required by the final release)
var config = ClusterConfiguration.LocalhostPrimarySilo();
// add providers to the legacy configuration object.
config.AddMemoryStorageProvider();
var builder = new SiloHostBuilder()
.UseConfiguration(config)
// Add assemblies to scan for grains and serializers.
// For more info read the Application Parts section
.ConfigureApplicationParts(parts =>
parts.AddApplicationPart(typeof(HelloGrain).Assembly)
.WithReferences())
// Configure logging with any logging framework that supports Microsoft.Extensions.Logging.
// In this particular case it logs using the Microsoft.Extensions.Logging.Console package.
.ConfigureLogging(logging => logging.AddConsole());
var host = builder.Build();
await host.StartAsync();
return host;
}
}
Orleans 2.0中有许多新的选项类,它们为配置客户端提供了一种新方法。为了便于迁移到新API,有一个可选的向后兼容包Microsoft.Orleans.Core.Legacy
,它提供了从旧的1.x配置API到新的API的桥接。
如果添加了Microsoft.Orleans.Core.Legacy
包,则仍可以通过旧ClientConfiguration
对象,以编程的方式配置客户端,然后可以将该对象传递ClientBuilder
,构建并连接客户端。
您仍需要通过ConfigureApplicationParts
调用,指定grain接口的程序集。
以下是如何以传统方式,配置本地silo的示例:
// define the client configuration (temporarily required in the beta version,
// will not be required by the final release)
var config = ClientConfiguration.LocalhostSilo();
var builder = new ClientBuilder()
.UseConfiguration(config)
// Add assemblies to scan for grains interfaces and serializers.
// For more info read the Application Parts section
.ConfigureApplicationParts(parts => parts.AddApplicationPart(typeof(IHello).Assembly))
.ConfigureLogging(logging => logging.AddConsole())
var client = builder.Build();
await client.Connect();
Orleans 2.0使用与ASP.NET Core 2.0相同的日志记录抽象。您可以在ASP.NET Core日志记录中,找到大多数Orleans日志记录功能的替代品。Orleans特定的日志记录功能(例如ILogConsumer
和Message Bulking)仍然保留在Microsoft.Orleans.Logging.Legacy
包中,因此您仍然可以选择使用它们。但是如何用2.0中的更改,来配置您的Orleans日志记录,接下来,让我带您了解迁移过程。
在1.5中,日志配置是通过ClientConfiguration
和NodeConfiguration
来完成的。您可以通过它们来配置DefaultTraceLevel
、TraceFileName
、TraceFilePattern
、TraceLevelOverrides
、TraceToConsole
、BulkMessageLimit
、LogConsumers
等等。在2.0中,日志记录配置与ASP.NET Core 2.0日志记录一致,这意味着大多数配置都是通过Microsoft.Extensions.Logging.ILoggingBuilder
来完成的。
要配置DefaultTraceLevel
和TraceLevelOverrides
,则需要将日志过滤应用到ILoggingBuilder
。例如,要在Orleans运行时将跟踪级别设置为“Debug”,可以使用下面的示例,
siloBuilder.AddLogging(builder=>builder.AddFilter("Orleans", LogLevel.Debug));
您可以以相同的方式,为应用程序代码配置日志级别。如果要将默认最小跟踪级别设置为Debug,请使用下面的示例
siloBuilder.AddLogging(builder=>builder.SetMinimumLevel(LogLevel.Debug);
有关日志过滤的更多信息,请参阅https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging上的文档;
要将TraceToConsole配置为true
,您需要引用Microsoft.Extensions.Logging.Console
包,然后在ILoggingBuilder
上使用AddConsole()
扩展方法。与TraceFileName
和TraceFilePattern
一样,如果要将消息记录到文件,则需要在ILoggingBuilder
上使用AddFile("file name")
方法。
如果您仍想使用“Message Bulking”功能,则还需要通过ILoggingBuilder
对其进行配置。Message Bulking功能存在于Microsoft.Orleans.Logging.Legacy
包中。所以你需要首先添加对该包的依赖。然后通过ILoggingBuilder
进行配置。以下是如何用ISiloHostBuilder
配置它的示例
siloBuiler.AddLogging(builder => builder.AddMessageBulkingLoggerProvider(new FileLoggerProvider("mylog.log")));
此方法将使用默认bulking配置,将Message Bulking功能应用于FileLoggerProvider
。
由于我们将来最终会弃用并删除LogConsumer功能支持,因此我们强烈建议您尽快迁移此功能。您可以采取几种方法来迁移。一种选择是维护自己的ILoggerProvider
,它会创建ILogger
,来记录到所有现存的日志消费者。这与我们在Microsoft.Orleans.Logging.Legacy
包装中所做的非常相似。您可以查看LegacyOrleansLoggerProvider
并从中借用逻辑。另一个选择是,用Nuget上提供了等价或类似功能的ILoggerProvider
现有实现,来替换您的ILogConsumer
,或者实现您自己的ILoggerProvider
,以满足您的特定日志记录要求。并使用ILoggerProvider
配置这些ILoggingBuilder
。
但是,如果您在短期内无法迁移日志消费者,您仍然可以使用它。对ILogConsumer
的支持存在于Microsoft.Orleans.Logging.Legacy
。所以,你需要首先添加对该包的依赖性,然后通过ILoggingBuilder
上的扩展方法AddLegacyOrleansLogging
,再配置日志消费者。ASP.NET在IServiceCollection
上提供了本地的AddLogging
方法,供您配置ILoggingBuilder
。我们还将该方法包装在ISiloHostBuilder
和IClientBuilder
的扩展方法下。因此,您也可以在Silo构建器和客户端构建器上,调用AddLogging
方法,来配置ILoggingBuilder
。下面是一个例子:
var severityOverrides = new OrleansLoggerSeverityOverrides();
severityOverrides.LoggerSeverityOverrides.Add(typeof(MyType).FullName, Severity.Warning);
siloBuilder.AddLogging(builder => builder.AddLegacyOrleansLogging(new List()
{
new LegacyFileLogConsumer($"{this.GetType().Name}.log")
}, severityOverrides));
如果您已在ILogConsumer
自定义实现上有所花费,并且在短期内无法将其转换为ILoggerProvider
的实现,则可以使用此功能。
Grain
的基类和IProviderRuntime
上的方法Logger GetLogger(string loggerName)
,以及IStorageProvider上的方法Logger Log { get; }
,在2.0中仍然作为弃用的功能而保留。您仍然可以在迁移传统的日志记录的过程中使用它。但我们建议您尽快迁移它们。
在Orleans 2.0中,所包含的提供程序的配置已经标准化,来从为silo或客户端配置的ClusterOptions
中,获取服务ID和集群ID。
服务ID是一个服务或者应用程序(由集群体现)的稳定标识符。随着时间的推移,在实现服务的集群的部署和升级期间,服务ID不会发生变化。
与服务ID不同,集群ID仅在silo集群的生命周期内保持不变。如果一个正在运行的集群关闭,并且为同一个服务部署了一个新的集群,那么新的集群将具有新的唯一的集群ID,但会保留旧集群的服务ID。
服务ID通常用作键的一部分,用于持久化需要在服务的整个生命周期内保持持续性的数据。例如,grain状态、提醒和持久流队列。另一方面,集群成员资格表中的数据,仅在其集群范围内有意义,因此通常会与集群ID进行切断。
在2.0之前,Orleans提供程序的行为,有时与使用服务ID和群集ID(以前也称为部署ID)不一致。由于这种统一以及提供程序配置API的整体更改,某些提供程序写入存储的数据可能会更改位置或键。对此更改敏感的提供程序的示例,是Azure队列流提供程序。
如果要将现有服务从1.x迁移到2.0,并且需要保持与您在服务中使用的提供程序所持有的数据的位置或键的向后兼容性,请验证数据是否在您的服务或提供程序期望的位置。如果您的服务恰好依赖于1.x提供程序对服务ID和群集ID的不正确使用,您可以通过调用ISiloHostBuilder.AddProviderClusterOptions()
或IClientBuilder.AddProviderClusterOptions()
,来为特定的提供程序重写ClusterOptions
,并强制它从/向1.x的存储位置,读取/写入数据。