コンフィギュレーション第9章マイクロサービスシステム
マイクロサービスシステムの構成を含む、要因の他の側面にもっと注意が必要です。
- 読み取りと書き込みのセキュリティ設定値
- 監査の値を変更する機能
- 靭性と信頼性の構成情報源そのもの
- 大規模、複雑な設定情報の少量を運ぶことが難しい環境変数
- アプリケーションは、オンラインリアルタイムの更新をサポートするかどうかを決定し、設定値を変更するだけでなく、実装する方法を決定します
- そして、支援機能を階層化設けられたスイッチ
- 機密情報と暗号化キー自体は保存され、読み取りサポートあり
この章では、最初のメカニズムは、アプリケーション内の環境変数を使用について説明し、サポートケースドッカーを実証します
そして、NetflixのOSSテクノロジ・スタックから構成サーバー製品を探ります
最後に、使用がetcd、それは、分散キー値データベースの一般的に使用されるオープンソースの構成管理であります
ドッカーで使用する環境変数
デフォルト値を提供するように構成すると、あなたはまた、設定はアプリケーションの起動時に環境変数によって上書きされるために必要なものを検討すべきです
構成設定は、次のように、指定されたキーを表示するために使用することができた場合:
$ sudo docker run -e SOME_VAR='foo' \ -e PASSWORD='foo' \
-e USER='bar' \
-e DB_NAME='mydb' \
-p 3000:3000 \
--name container_name microservices-aspnetcore/image:tag
コマンドラインに入ってくる値をしたくない場合は別の方法として、環境変数は式には、例えば、受信した値が可能含まれていない限り、開始するために容器の中に環境から転送することができます。
$ docker run -e PORT -e CLIENTSCRET -e CLIENTKEY [...]
ライン端子を指揮します。このコマンドはドッカーコンテナを輸入しているPORT、値CLIENTSECRETとCLIENTKEY環境変数に配置され、それらの値は、潜在的なセキュリティの脆弱性と機密保護するために、プロセスのコマンドラインテキストに開示されていません情報開示
あなたはコンテナに環境変数の多くを渡す必要がある場合は、含まれているキーファイルのリストをドッキングウィンドウするコマンドを指定することができます。
$ docker run --env-file ./myenv.file [...]
使用春のクラウドサーバーの構成
構成管理サービス、周りの最大の課題の一つではないか、環境変数に注入された値が、値そのものの日常のメンテナンスに
コンフィギュレーションの元のソースの値が変更された場合、どのように我々は、通知を得るのですか
値の変更が発生した場合また、どのように我々は戻って、以前の値を見てください
Gitが設定値を管理するために使用するために利用できるリポジトリのようにあなたはそれが思われることかもしれません
同じビューを保持春クラウドコンフィギュレーションサーバ(SCCS)開発者
.NETのコアアプリケーションで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.Configure<ConfigServerData>(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 IOptionsSnapshot<ConfigServerData> MyConfiguration { get; set; }
private ConfigServerClientSettingsOptions ConfigServerClientSettingsOptions { get; set; }
public MyController(IOptionsSnapShot<ConfigServerData> opts, IOptions<ConfigServerClientSettingsOptions> clientOpts)
{
...
}
...
}
上述配备完成后,如果配置服务器已处于运行状态,构造器中的 opts 变量将包含应用所有的相关配置
启动配置服务器最简单的方法就是直接通过 Docker 镜像运行以下代码
$ docker run -p 8888:8888 \
-e SPRING_CLOUD_CONFIG_SERVER_GET_URI=http://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 node
Data[node.Key] = node.Value;
}
}
}
catch (EtcdCommonException.KeyNotFound)
{
// key does not
Console.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(ILogger<ValuesController> logger)
{
this.logger = logger;
}
// GET api/values
[HttpGet]
public IEnumerable<string> Get()
{
List<string> values = new List<string>();
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 配置源
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。
如有任何疑问,请与我联系 ([email protected]) 。