网站怎么留住用户,在什么地方可以接到做网站的活,泰安58同城二手房,网站建设招标书模板第 9 章 微服务系统的配置微服务系统中的配置需要关注更多其他方面的因素#xff0c;包括#xff1a;配置值的安全读写值变更的审计能力配置信息源本身的韧性和可靠性少量的环境变量难以承载大型、复杂的配置信息应用要决定是否支持配置值的在线更新和实时变更#xff0c;还… 第 9 章 微服务系统的配置微服务系统中的配置需要关注更多其他方面的因素包括配置值的安全读写值变更的审计能力配置信息源本身的韧性和可靠性少量的环境变量难以承载大型、复杂的配置信息应用要决定是否支持配置值的在线更新和实时变更还要决定如何实现对功能开关和层级化设置的支持对敏感信息以及加密密钥本身进行存储和读取支持本章首先讨论在应用中使用环境变量的机制并演示 Docker 的支持情况接着探索一个来自 Netflix OSS 技术栈的配置服务器产品最后将运用 etcd它是一个常用于配置管理的开源分布式键值数据库在 Docker 中使用环境变量为配置提供默认值时还应该考虑哪些设置在应用启动期间需要通过环境变量进行覆盖为配置设置值时可使用键值对显示指定如下所示$ sudo docker run -e SOME_VARfoo \ -e PASSWORDfoo \
-e USERbar \
-e DB_NAMEmydb \
-p 3000:3000 \
--name container_name microservices-aspnetcore/image:tag或者如果不希望在命令行中显示传入值也可以把来自启动环境的环境变量转发到容器内部只要不传入包含值的等式即可例如$ docker run -e PORT -e CLIENTSCRET -e CLIENTKEY [...]这一命令将把命令行所在终端中的 PORT、CLIENTSECRET 和 CLIENTKEY 环境变量的值传入 Docker 容器中在这个过程中它们的值不会在命令行文本中公开以防范潜在的安全漏洞和敏感信息泄露如果需要向容器传入大量的环境变量可以向 docker 命令指定一个包含键值对列表的文件$ docker run --env-file ./myenv.file [...]使用 Spring Cloud 配置服务器围绕服务的配置管理的最大难题之一并非如何将值注入到环境变量而在于这些值本身的日常维护当配置的原始源处的值发生变更时我们如何得到通知更进一步当值发生变更时我们如何回溯并查看之前的值你可能发现这似乎可用使用类似于 Git 仓库的方法来管理配置值Spring Cloud 配置服务器SCCS的开发人员也持相同看法要在 .NET Core 应用中添加 SCCS 客户端的支持只需要在项目中添加对 Steeltoe.Extensions.Configuration.ConfigServer NuGet 包的引用接着我们需要配置应用让它从正确的位置获取设置信息我们需要定义一个 Spring 应用名称并在 appsettings.json 文件中添加配置服务器的 URL{spring: {application: {name: foo},cloud: {config: {uri: http://localhost:8888}}},Logging: {IncludeScopes: false,LogLevel: {Default: Debug,System: Information,Microsoft: Information}}
}配置完成后Startup 构造方法仍然与其他应用几乎一致public Startup(IHostingEnvironment env)
{var builder new ConfigurationBuilder().SetBasePath(env.ContentRootPath).AddJsonFile(appsettings.json, optional: true, reloadOnChange: false).AddEnvironmentVariables().AddConfigServer(env);Configuration builder.Build();
}要添加对配置服务器的支持接下来需要修改 ConfigureServices 方法首先调用 AddConfigServer 向依赖注入子系统加入配置客户端接着指定泛型参数并调用 Configure 方法这一操作能把从配置服务器获取的配置信息包装为一个 IOptionsSnapshot 对象然后可由控制器和其他代码使用public void ConfigureServices(IServiceCollection services)
{services.AddConfigServer(Configuration);services.AddMvc();services.ConfigureConfigServerData(Configuration);
}此处用于表示从配置服务器获取的数据的数据模型是基于 Spring Cloud 服务器示例仓库中的示例配置进行建模的public class ConfigServerData
{public string Bar { get; set; }public string Foo { get; set; }public Info Info { get; set; }
}public class Info
{public string Description { get; set; }public string Url { get; set; }
}然后在需要时就可注入这个类的实例以及配置服务器的客户端参数public class MyController : MyController
{private IOptionsSnapshotConfigServerData MyConfiguration { get; set; }private ConfigServerClientSettingsOptions ConfigServerClientSettingsOptions { get; set; }public MyController(IOptionsSnapShotConfigServerData opts, IOptionsConfigServerClientSettingsOptions clientOpts){...}...
}上述配备完成后如果配置服务器已处于运行状态构造器中的 opts 变量将包含应用所有的相关配置启动配置服务器最简单的方法就是直接通过 Docker 镜像运行以下代码$ docker run -p 8888:8888 \
-e SPRING_CLOUD_CONFIG_SERVER_GET_URIhttp://github.com/spring-cloud-samples/ \config-repohyness/spring-cloud-config-server如果服务器运行正确应该能通过以下命令获取配置信息curl http://localhost:8888/foo/development在本地用 Docker 镜像启动配置服务器后使用上面展示的 C# 代码就能体验将外部配置数据提供给 .NET Core 微服务的过程使用 etcd 配置微服务Spring Cloud 配置服务器的替代品不计其数etcd 是其中很流行的一个上一章简单提到etcd 是一个轻量级的分布式键值数据库它就是为你存储分布式系统所需要的最关键信息的位置etcd 是一个集群产品其节点之间的通信是基于 Raft 共识算法实现的etcd 的一个最常见运用场景就是存储和检索配置信息以及功能标志在本章的例子里我访问 compose.io 并注册了一个免费试用的托管 etcd创建 etcd 配置提供程序GitHub链接https://github.com/microservices-aspnetcore/etcd-client创建配置源using System;
using Microsoft.Extensions.Configuration;namespace ConfigClient
{public class EtcdConfigurationSource : IConfigurationSource{public EtcdConnectionOptions Options { get; set; }public EtcdConfigurationSource(EtcdConnectionOptions options){this.Options options;}public IConfigurationProvider Build(IConfigurationBuilder builder){return new EtcdConfigurationProvider(this);}}
}创建配置构建器using System;
using System.Collections.Generic;
using EtcdNet;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Primitives;namespace ConfigClient
{public class EtcdConfigurationProvider : ConfigurationProvider{private EtcdConfigurationSource source;public EtcdConfigurationProvider(EtcdConfigurationSource source){this.source source;}public override void Load(){EtcdClientOpitions options new EtcdClientOpitions(){Urls source.Options.Urls,Username source.Options.Username,Password source.Options.Password,UseProxy false,IgnoreCertificateError true};EtcdClient etcdClient new EtcdClient(options);try{EtcdResponse resp etcdClient.GetNodeAsync(source.Options.RootKey,recursive: true, sorted: true).Result;if (resp.Node.Nodes ! null){foreach (var node in resp.Node.Nodes){// child nodeData[node.Key] node.Value;}}}catch (EtcdCommonException.KeyNotFound){// key does notConsole.WriteLine(key not found exception);}}}
}借助如下扩展方法using Microsoft.Extensions.Configuration;namespace ConfigClient
{public static class EtcdStaticExtensions{public static IConfigurationBuilder AddEtcdConfiguration(this IConfigurationBuilder builder,EtcdConnectionOptions connectionOptions){return builder.Add(new EtcdConfigurationSource(connectionOptions));}}public class EtcdConnectionOptions{public string[] Urls { get; set; }public string Username { get; set; }public string Password { get; set; }public string RootKey { get; set; }}
}便能在 Startup 类中把 etcd 添加为配置源using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;namespace ConfigClient
{public class Startup{public Startup(IHostingEnvironment env){var builder new ConfigurationBuilder().SetBasePath(env.ContentRootPath).AddJsonFile(appsettings.json, optional: false, reloadOnChange: true).AddJsonFile($appsettings.{env.EnvironmentName}.json, optional: true).AddEtcdConfiguration(new EtcdConnectionOptions{Urls new string[] {https://portal1934-21.euphoric-etcd-31.capital-one-3.composedb.com:17174,https://portal2016-22.euphoric-etcd-31.capital-one-3.composedb.com:17174},Username root,Password changeme,RootKey /myapp}).AddEnvironmentVariables();Configuration builder.Build();}public static IConfigurationRoot Configuration { get; set; }// This method gets called by the runtime. Use this method to add services to the container.public void ConfigureServices(IServiceCollection services){// Add framework services.services.AddMvc();}// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory){loggerFactory.AddConsole();loggerFactory.AddDebug();app.UseMvc();}}
}使用来自 etcd 的配置值using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using EtcdNet;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Configuration;namespace ConfigClient.Controllers
{[Route(api/[controller])]public class ValuesController : Controller{private ILogger logger;public ValuesController(ILoggerValuesController logger){this.logger logger;}// GET api/values[HttpGet]public IEnumerablestring Get(){Liststring values new Liststring();values.Add(Startup.Configuration.GetSection(/myapp/hello).Value);values.Add(Startup.Configuration.GetSection(/myapp/rate).Value);return values;}// GET api/values/5[HttpGet({id})]public string Get(int id){return value;}// POST api/values[HttpPost]public void Post([FromBody]string value){}// PUT api/values/5[HttpPut({id})]public void Put(int id, [FromBody]string value){}// DELETE api/values/5[HttpDelete({id})]public void Delete(int id){}}
}现在访问 http://localhost:3000/api/values 端点将返回这些值{world, 12.5}这些正是本节前面面向 etcd 服务器添加的值只使用了少数几行代码我们便创建了一个由远程配置服务器支持的、稳定而符合标准的 ASP.NET 配置源