Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否依赖有状态服务获取配置值?_C#_.net_Azure_Azure Service Fabric - Fatal编程技术网

C# 是否依赖有状态服务获取配置值?

C# 是否依赖有状态服务获取配置值?,c#,.net,azure,azure-service-fabric,C#,.net,Azure,Azure Service Fabric,我们有大约100个微服务在运行。每个微服务都有一整套配置文件,如applicationmanifest.xml、settings.xml、node1.xml等 这将成为一场配置噩梦 经过探索,有人建议: 您可以将配置保存在有状态服务中,然后更改参数 通过你的API 我看到的问题是,现在只有一个故障点:提供配置值的服务 是否有一个集中的解决方案来维护每个微服务的这么多配置数据? 注意:您的问题似乎在使用单一配置服务是可靠的还是使用静态配置还是动态配置之间模糊不清 有关静态配置与动态配置的讨论,请参

我们有大约100个微服务在运行。每个微服务都有一整套配置文件,如applicationmanifest.xml、settings.xml、node1.xml等

这将成为一场配置噩梦

经过探索,有人建议:

您可以将配置保存在有状态服务中,然后更改参数 通过你的API

我看到的问题是,现在只有一个故障点:提供配置值的服务

是否有一个集中的解决方案来维护每个微服务的这么多配置数据?


注意:您的问题似乎在使用单一配置服务是可靠的还是使用静态配置还是动态配置之间模糊不清

有关静态配置与动态配置的讨论,请参阅


一个配置服务听起来很合理,尤其是当您认为服务结构被设计成可实现的,甚至是有状态服务时。 MSDN:

Service Fabric使您能够构建和管理可扩展且可靠的
应用程序,这些应用程序由在共享的计算机池(称为群集)上以高密度运行的微服务组成

开发高度可靠的无状态和有状态的微服务

有状态服务将状态存储在一个事务中,该事务保证在事务成功时存储数据

作品:

我看到的问题是,现在只有一个故障点:提供配置值的服务

不一定。它不是真正的单点故障服务,而是由服务结构和您选择的Azure数据中心部署选项定义的“故障域”

MSDN:

故障域是协调故障的任何区域。单台机器是一个故障域(因为它可能会因各种原因自行发生故障,从电源故障到驱动器故障,再到NIC固件损坏)。连接到同一以太网交换机的机器处于同一故障域,共享单一电源或位于同一位置的机器也处于同一故障域。由于硬件故障自然会重叠,因此故障域本质上是分层的,并在服务结构中表示为URI

正确设置容错域非常重要,因为服务结构使用此信息安全地放置服务。服务结构不希望放置服务,从而导致容错域的丢失(由某些组件的故障引起)导致服务停机。在Azure环境中,服务结构使用环境提供的容错域信息代表您正确配置群集中的节点。对于Service Fabric Standalone,容错域是在设置群集时定义的

因此,您可能希望在两个单独的容错域上运行至少两个配置服务

更多

虽然中央配置服务似乎是一种解决方法,但如果您这样做,就会带来一些问题,每次都必须纠正这些问题)。当您有一个中央配置服务时,在开始代码升级之前,必须使用正确的配置对其进行更新,当然,您必须保留以前的配置,以防部署回滚。这是我在Service Fabric团队时展示的配置幻灯片

ServiceFabric附带了版本配置功能,您应该使用该功能,但不能使用ServiceFabric推荐的方式。对于我的项目,我使用Microsoft.Extensions.Configuration进行配置。捕获配置事件

            context.CodePackageActivationContext.ConfigurationPackageAddedEvent += CodePackageActivationContext_ConfigurationPackageAddedEvent;
        context.CodePackageActivationContext.ConfigurationPackageModifiedEvent += CodePackageActivationContext_ConfigurationPackageModifiedEvent;
        context.CodePackageActivationContext.ConfigurationPackageRemovedEvent += Context_ConfigurationPackageRemovedEvent;
这些事件处理程序中的每一个都可以像这样调用来加载配置

        protected IConfigurationRoot LoadConfiguration()
    {
        ConfigurationBuilder builder = new ConfigurationBuilder();

        // Get the name of the environment this service is running within.
        EnvironmentName = Environment.GetEnvironmentVariable(EnvironmentVariableName);
        if (string.IsNullOrWhiteSpace(EnvironmentName))
        {
            var err = $"Environment is not defined using '{EnvironmentVariableName}'.";
            _logger.Fatal(err);
            throw new ArgumentException(err);
        }

        // Enumerate the configuration packaged. Look for the service type name, service name or settings.
        IList<string> names = Context?.CodePackageActivationContext?.GetConfigurationPackageNames();
        if (null != names)
        {
            foreach (string name in names)
            {
                if (name.Equals(GenericStatelessService.ConfigPackageName, StringComparison.InvariantCultureIgnoreCase))
                {
                    var newPackage = Context.CodePackageActivationContext.GetConfigurationPackageObject(name);

                    // Set the base path to be the configuration directory, then add the JSON file for the service name and the service type name.
                    builder.SetBasePath(newPackage.Path)                            
                        .AddJsonFile($"{ServiceInstanceName}-{EnvironmentName}.json", true, true)
                        .AddJsonFile($"{Context.ServiceTypeName}-{EnvironmentName}.json", true, true);

                    // Load the settings into memory.
                    builder.AddInMemoryCollection(LoadSettings(newPackage));
                }
            }
        }

        // Swap in a new configuration.
        return builder.Build();
    }
受保护的IConfigurationRoot LoadConfiguration()
{
ConfigurationBuilder=新的ConfigurationBuilder();
//获取运行此服务的环境的名称。
EnvironmentName=Environment.GetEnvironmentVariable(EnvironmentVariableName);
if(string.IsNullOrWhiteSpace(EnvironmentName))
{
var err=$“未使用{EnvironmentVariableName}定义环境。”;
_记录器。致命(错误);
抛出新的ArgumentException(err);
}
//枚举打包的配置。查找服务类型名称、服务名称或设置。
IList name=Context?.CodePackageActivationContext?.GetConfigurationPackageNames();
if(null!=名称)
{
foreach(名称中的字符串名称)
{
if(name.Equals(GenericStatelessService.ConfigPackageName、StringComparison.InvariantCultureIgnoreCase))
{
var newPackage=Context.CodePackageActivationContext.GetConfigurationPackageObject(名称);
//将基本路径设置为配置目录,然后为服务名称和服务类型名称添加JSON文件。
builder.SetBasePath(newPackage.Path)
.AddJsonFile($“{ServiceInstanceName}-{EnvironmentName}.json”,true,true)
.AddJsonFile($“{Context.ServiceTypeName}-{EnvironmentName}.json”,true,true);
//将设置加载到内存中。
AddInMemoryCollection(LoadSettings(newPackage));
}
}
}
//在新配置中交换。
返回builder.Build();
}
您现在可以使用.Net配置与配置交互。最后要介绍的是配置文件的格式。在PackageRoot | Config目录中,只需包含配置文件。我碰巧没有
    {
  "Logging": {
    "SeqUri": "http://localhost:5341",
    "MaxFileSizeMB": "100",
    "DaysToKeep": "1",
    "FlushInterval": "00:01:00",
    "SeqDefaultLogLevel": "Verbose",
    "FileDefaultLogLevel": "Verbose"
  },

  "ApplicationOperations": {
     "your values here": "<values>"
  },