c# - 依赖有状态服务来获取配置值?

标签 c# .net azure azure-service-fabric

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

这将成为一场配置噩梦。

探索之后this ,有人建议:

You can keep configs inside stateful service, then change parameters through your API.

我看到的问题是,现在存在单点故障:提供配置值的服务。

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

最佳答案

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

enter image description here

Service Fabric 附带了版本配置功能,您应该使用它,但不要按照 Service Fabric 推荐的方式使用。对于我的项目,我使用 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();
    }

您现在可以使用 .Net 配置与配置进行交互。最后要介绍的是配置文件的格式。在包根目录中 | Config 目录,您只需包含您的配置文件即可。我碰巧使用了服务名称+数据中心。 Configuration Directory

文件内部如下所示,其中每个服务结构类都有一个 JSON 属性。

    {
  "Logging": {
    "SeqUri": "http://localhost:5341",
    "MaxFileSizeMB": "100",
    "DaysToKeep": "1",
    "FlushInterval": "00:01:00",
    "SeqDefaultLogLevel": "Verbose",
    "FileDefaultLogLevel": "Verbose"
  },

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

如果您坚持了这么久,这样做的一大优点是配置与代码同时部署,如果代码回滚,配置也会回滚,让您处于了解状态。

关于c# - 依赖有状态服务来获取配置值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46966636/

相关文章:

c# - wcf 服务(REST 或 SOAP 或 WEB API)接受任何结构的任何数据

c# - 在 C# 中将 Access 图像 OLE 对象转换为原始图像字节数组

c# - 如何获取上传进度?

c# - Visual Studio 中的 TestContext - 它有什么作用?

c# - 缓存信息存储在 ASP.NET 中的什么位置?

c# - XmlTextReader 在不识别的情况下传递了 XML 文档的末尾

azure - Azure 的 IPv6 支持

c# - webkitbrowser 在网络上加载共享文件

c# - 接收错误 "The type or namespace name ' LayoutsPageBase' 找不到”

azure - 从 Terraform 获取数据库 URL `azurerm_postgresql_flexible_server`