我们正在运行大约 100 个微服务。每个微服务都有一整套配置文件,如applicationmanifest.xml、settings.xml、node1.xml等。
这将成为一场配置噩梦。
探索之后this ,有人建议:
You can keep configs inside stateful service, then change parameters through your API.
我看到的问题是,现在存在单点故障:提供配置值的服务。
是否有一个集中式解决方案来为每个微服务维护如此多的配置数据?
最佳答案
虽然中央配置服务似乎是一种可行的方法,但如果您这样做,则会带来一些每次都必须正确解决的问题。当您拥有中央配置服务时,在开始代码升级之前,必须使用正确的配置进行更新,并且您当然必须保留以前的配置,以防部署回滚。这是我在 Service Fabric 团队工作时展示的配置幻灯片。
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 目录,您只需包含您的配置文件即可。我碰巧使用了服务名称+数据中心。
文件内部如下所示,其中每个服务结构类都有一个 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/