第三章 分布式配置中心
为什么需要分布式配置中心
分布式配置中心是为了解决在分布式系统中进行配置管理的需求而引入的。在传统的单体应用中,通常使用配置文件集中管理系统的配置信息。然而,在分布式系统中,由于系统规模变大、节点众多,并且可能部署在不同的服务器上,传统的配置文件方式会面临一些挑战。
首先,配置文件的修改和发布需要手动操作,如果系统规模庞大则变得非常繁琐和容易出错。其次,配置文件不易实现动态更新,如果需要修改某项配置,需要重新部署整个应用。而对于分布式系统来说,这样的操作会带来不可忽视的停机时间和影响。
因此,引入分布式配置中心可以解决这些问题。分布式配置中心提供了一个集中式的管理界面,可以方便地进行配置修改和发布。同时,它支持实时动态更新配置,可以使得配置的修改立即生效,无需重启应用或重新部署。此外,分布式配置中心还提供了配置的版本管理、权限控制、配置项的灰度发布等功能,能够更好地满足分布式系统的配置管理需求。
什么是分布式配置中心
分布式配置中心是一种用于管理和集中存储分布式系统配置信息的工具或服务。它提供了一个集中化的平台,方便开发人员对系统配置进行统一管理和调整,以满足不同环境下的需求。
.Net 分布式配置中心通常具有以下特点:
-
集中管理:分布式配置中心将系统中各个组件或节点的配置信息集中存储在一个地方,方便开发人员进行查看、修改和更新。
-
实时更新:分布式配置中心支持动态更新配置信息,当配置项发生改变时,可以实时通知系统中的节点或组件,使得配置的修改能够立即生效,无需重启应用。
-
版本控制:配置中心通常支持配置版本管理,可以记录每次配置的修改历史,并支持回滚到之前的版本。
-
权限控制:为了保证配置的安全性,分布式配置中心提供了权限管理机制,可以限制不同角色或用户对配置的访问和修改权限。
-
灰度发布:部分分布式配置中心还支持配置的灰度发布,即将配置变更只应用于部分节点或用户,以便逐步验证和测试新的配置。
-
支持IConfiguration,IOptions模式读取配置,原程序几乎可以不用改造
通过使用分布式配置中心,团队可以更加高效地管理和维护分布式系统的配置,降低系统配置管理的复杂度,提高系统的可维护性和灵活性。
2. Nacos 配置中心
文档地址:
安装
略
如何使用
-
nuget 安装:
-
nacos-sdk-csharp
-
nacos-sdk-csharp.AspNetCore
-
nacos-sdk-csharp.Extensions.Configuration
-
-
appsetting.json 配置:
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*", // 配置中心 "NacosConfig": { "Listeners": [ // 配置文件,至少要有一个 { "Optional": true, // 是否可选,true:可以不创建,但控制台会给出警告,false:必须要有 "DataId": "app1-dev.json", // 配置文件 "Group": "DEFAULT_GROUP" } ], "Namespace": "netcore",// 此处不要写public,必须设置一个你自己的命名空间 "ServerAddresses": [ "http://localhost:8848/" ], // 服务器地址 "UserName": "nacos", // nacos 登录账号 "Password": "nacos", // nacos 登录密码 "ConfigUseRpc": false, // 配置中心是否使用Rpc协议通信 "NamingUseRpc": false // 注册中心是否使用RPC协议通信 } }
-
Program.cs 中添加服务
var builder = WebApplication.CreateBuilder(args); // ... builder.Host.UseNacosConfig("NacosConfig"); // NacosConfig 是appsetting.json 配置中心节点的名称
-
创建配置文件
-
如何使用
private readonly IConfiguration _configuration; public UserController(IConfiguration configuration) { _configuration = configuration; } [HttpGet] public IActionResult GetUserList() { var s = _configuration["JwtTokenOption:TokenExpireTime"]; return Ok(s); }
配置公共部分
如果是做微服务项目,其实每个项目的配置有很多东西都是共用的,例如:jwt 配置,日志配置等等。
修改NacosConfig节点配置
"NacosConfig": { "Listeners": [ { "Optional": true, "DataId": "app1-dev.json", "Group": "DEFAULT_GROUP" }, // 公共配置 { "Optional": true, "DataId": "app-common.json", "Group": "DEFAULT_GROUP" } ], "Namespace": "NetCloud", "serverAddresses": [ "http://101.43.242.9:8848" ], "UserName": "nacos", "Password": "nacos", "ConfigUseRpc": false, "NamingUseRpc": false }
使用方式
同上。
直接使用IConfiguration 接口注入获取配置即可
Nacos 多环境问题
当我们所有的环境都共用一套配置中心的时候,最让我们苦恼的问题应该是要怎么样去隔离这些不同的环境!
手段有如下几种:
-
通过Namespace来区别
例如:可以建立三个命名命名空间分别代表
开发(dev),测试(test),生产(production)
-
通过Group来区别
默认的分组是
DEFAULT_GROUP
, 也可创建不同的分组代表不同的环境:开发(DEV_GROUP),测试(TEST_GROUP),生产(PRODUCTION_GROUP)
-
通过DataID来区别
DataID 顾名思义,就是数据文件ID,就是用于存放配置内容的配置文件名,可以创建不同的文件名来区分不同的环境。例如:
开发(app-dev.json),测试(app-test.json),生产(app-production.json)
在Nacos中,推荐的做法是用NameSpace来区分。
使用步骤
-
首先要为每个环境建一个命名空间,用作区分的标识。
可以考虑用应用名.环境名
的形式,只要统一就好。
-
为了演示,往每个命名空间都加一个test的配置,对应的值是环境名。
-
下面要做的就是在不同环境的配置文件中指定对应的命名空间,这里要用那个命名空间ID。
3. Appolo
官方文档:
官方 GitHub:
官方 Gitee:
Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用于微服务配置管理场景。
安装步骤
1. 下载安装包(官方提供的)
-
下载
apollo-quick-start.zip
:此压缩包由官方提供的下载链接
-
准备一台
linux centos 7
服务器,安装open-jdk 1.8,mysql
-
将下载好的
apollo
上传至linux
服务器,解压。# 解压 unzip apollo-quick-start.zip
-
执行
apollo
解压后下的sql
文件夹下的两个mysql文件ApolloConfigDb.sql 与 ApolloPortalDb.sql
导入成功后,可以通过执行以下sql语句来验证:
select `NamespaceId`, `Key`, `Value`, `Comment` from ApolloConfigDB.Item;
NamespaceId Key Value Comment 1 timeout 100 sample timeout配置 select `Id`, `AppId`, `Name` from ApolloPortalDB.App;
Id AppId Name 1 SampleApp Sample App
2、配置数据库连接信息
Apollo服务端需要知道如何连接到你前面创建的数据库,所以需要编辑
注意:填入的用户需要具备对ApolloPortalDB和ApolloConfigDB数据的读写权限。
#apollo config db info apollo_config_db_url="jdbc:mysql://localhost:3306/ApolloConfigDB?characterEncoding=utf8&serverTimezone=Asia/Shanghai" apollo_config_db_username=用户名 apollo_config_db_password=密码(如果没有密码,留空即可) # apollo portal db info apollo_portal_db_url="jdbc:mysql://localhost:3306/ApolloPortalDB?characterEncoding=utf8&serverTimezone=Asia/Shanghai" apollo_portal_db_username=用户名 apollo_portal_db_password=密码(如果没有密码,留空即可)点击复制错误复制成功
注意:不要修改demo.sh的其它部分
3. 安装open-jdk 1.8
-
在线安装
open-jdk1.8
yum install -y java-1.8.0-openjdk-devel.x86_64
-
配置环境变量
1. vi /etc/profile 2. 在末尾行添加 #set java environment JAVA_HOME=/usr/lib/jvm/java-11-openjdk-11.0.11.0.9-1.el7_9.x86_64 CLASSPATH=.:$JAVA_HOME/lib.tools.jar PATH=$JAVA_HOME/bin:$PATH export JAVA_HOME CLASSPATH PATH 3. 使更改的配置立即生效 source /etc/profile
-
测试是否安装成功:
java -version
4. 启动运行:
1. 解压apollo-quick-start.zip unzip apollo-quick-start.zip 2. 启动 ./demo.sh start 成功提示如下: ==== starting service ==== Service logging file is ./service/apollo-service.log Started [10768] Waiting for config service startup....... Config service started. You may visit http://localhost:8080 for service status now! Waiting for admin service startup.... Admin service started ==== starting portal ==== Portal logging file is ./portal/apollo-portal.log Started [10846] Waiting for portal startup...... Portal started. You can visit http://localhost:8070 now!
启动成功之后出提示两个运行地址:
-
http://虚拟机ip:8080
这个是注册中心地址(eureka) -
http://虚拟机ip:8070
这个是apollo
配置中心配置中心登录账号与密码默认为:账号:
apollo
, 密码:admin
-
添加应用
-
部门:选择你的部门
-
appID
(特别重要):一般与微服务名一致 -
应用名称: (建议格式
xx-yy-zz
例:apollo-server
) ,也可以使用中心进行命名 -
应用负责人:选择任意一个负责人
-
项目管理员:选择任意一个项目管理员
-
-
管理秘钥(可选)
-
添加命名空间
默认的
application
命名空间是针对于以.properties
后缀名结尾的配置文件,这种后缀名一般是Java项目中所使用的配置文件。我们需要添加咱们 .Net 中常用的Json配置文件。
-
新建配置(发布生效)
5. 卸载Apollo
-
查看apollo 进程列表,找到对应的PID
ps -ef | grep apollo
-
杀死进程
kill 进程ID
创建客户端
dotnet-git : https://github.com/ctripcorp/apollo.net/tree/dotnet-core
-
安装nuget包
Com.Ctrip.Framework.Apollo.Configuration
-
添加服务
builder.Host.ConfigureAppConfiguration((context, build) => { build.AddApollo(context.Configuration.GetSection("apollo")) // 注意:使用json配置时,需要指定命名空间类型为Json类型,见下方AddNamespace代码 // 如果有多个命名空间,可以AddNamespace 多次 .AddNamespace("app", Com.Ctrip.Framework.Apollo.Enums.ConfigFileFormat.Json) .AddDefault(); });
-
配置appsetting.json
"apollo": { "AppId": "NetCloud.Apollo", "MetaServer": "http://127.0.0.1:8080", "ConfigServer": [ "http://127.0.0.1:8080" ], "Env": "DEV", // "Secret": "764c744d92a14bc8b65c4d86f324ac15", // 有则配置 }
-
使用
[ApiController] [Route("[controller]/[action]")] public class HomeController:ControllerBase { private readonly IConfiguration _configuration; public HomeController(IConfiguration configuration) { _configuration = configuration; } [HttpGet] public IActionResult Test1() { // 读取apollo配置中心 var connectionString = _configuration.GetConnectionString("MySql"); return Ok(connectionString); } }
注意事项
-
IOptions 不能够实时获取到最新
-
IConfiguration/IOptionsMonitor 可以实时获取最新配置
4. Consul 配置中心
前面介绍到了Consul 具有Key/Value 功能,意思就是用于做分布式配置中心。
4.1 安装
省略
4.2 创建配置中心步骤
1. 单服务情况下
一般创建一个 appsettings.json
配置文件即可
2. 多服务情况下
利用文件夹分层的方式,在Consul客户端上一个项目对应一个文件夹,然后在各自文件夹下放各自的appsettings.json, 如:ConfigCenterTest/appsettings.json、GoodsService/appsettings.json,然后在Program加载配置文件的时候,动态获取项目名称,进行路径的组装即可。
(1)创建文件夹
(2) 这个是保存好的文件夹
(3) 编写配置文件
4.3 接入.Net 6
-
安装包:
Winton.Extensions.Configuration.Consul
-
在Program 中加入如下代码:
builder.WebHost.ConfigureAppConfiguration((context, config) => { var env = context.HostingEnvironment; context.Configuration = config.Build(); string consul_url = context.Configuration["Consul_Url"]; // 单服务文件命名 string configFileName = "appsettings.json"; // 多服务情况下,建议 服务名/文件名命名 ,例如 OrderService/appsettings.json // string configFileName = $"{env.ApplicationName}/appsettings.{env.EnvironmentName}.json"; config.AddConsul(configFileName, options => { options.Optional = true; options.ReloadOnChange = true; options.OnLoadException = exceptionContext => { exceptionContext.Ignore = true; }; options.ConsulConfigurationOptions = cco => { cco.Address = new Uri(consul_url); }; }); context.Configuration = config.Build(); });
其中,
context.Configuration["Consul_Url"]
需要在项目中配置。
5. SummberBoot 集成配置中心
github 文档:
SummerBoot 是将SpringBoot的先进理念与C#的简洁优雅合二为一,声明式编程,专注于”做什么”而不是”如何去做”。在更高层面写代码,更关心的是目标,而不是底层算法实现的过程,SummerBoot,致力于打造一个人性化框架,让.net开发变得更简单优雅。
SummberBoot 目前支持的配置中心只有Nacos。
如何使用
-
删除原有的Nacos配置(如果有则清除掉)
-
安装nuget 包:
SummerBoot 2.0.2
-
appsetting.json 添加如下配置
"nacos": { //--------使用nacos则serviceAddress和namespaceId必填------ //nacos服务地址,如http://172.16.189.242:8848 "serviceAddress": "http://127.0.0.1:8848/", "namespaceId": "NetCloud", //--------如果需要使用nacos配置中心,则ConfigurationOption必填------ "configurationOption": { //配置的分组 "groupName": "DEFAULT_GROUP", //配置的dataId, "dataId": "app-Development.json" } }
-
Program 注入服务
builder.Host.UseNacosConfiguration();
-
测试
[ApiController] [Route("[controller]/[action]")] public class HomeController:ControllerBase { private readonly IConfiguration _configuration; public HomeController(IConfiguration configuration) { _configuration = configuration; } [HttpGet] public IActionResult Test1() { // 读取nacos配置中心 var connectionString = _configuration.GetConnectionString("MySql"); return Ok(connectionString); } }
视频配套链接:课程简介 (cctalk.com)