Tip: 此篇已加入.NET Core微服务基础系列文章索引

=>  Steeltoe目录快速导航

1. 基于Steeltoe使用Spring Cloud Eureka

2. 基于Steeltoe使用Spring Cloud Zuul

3. 基于Steeltoe使用Spring Cloud Hystrix

4. 基于Steeltoe使用Spring Cloud Config

  在分布式系统中,每一个功能模块都能拆分成一个独立的服务,一次请求的完成,可能会调用很多个服务协调来完成,为了方便服务配置文件统一管理,更易于部署、维护,所以就需要分布式配置中心组件了,在Spring Cloud中,就有这么一个分布式配置中心组件 — Spring Cloud Config。

  Spring Cloud Config 为分布式系统中的外部配置提供服务器和客户端支持。使用Config Server,我们可以为所有环境中的应用程序管理其外部属性。它非常适合spring应用,也可以使用在其他语言的应用上。随着应用程序通过从开发到测试和生产的部署流程,我们可以管理这些环境之间的配置,并确定应用程序具有迁移时需要运行的一切。服务器存储后端的默认实现使用git,因此它轻松支持标签版本的配置环境,以及可以访问用于管理内容的各种工具。

  Spring Cloud Config的原理图大致如下图(此图来自mazen1991)所示:

 

  我们将配置文件放入git或者svn等服务中,通过一个Config Server服务来获取git中的配置数据,而我们需要使用的到配置文件的Config Client系统可以通过Config Server来获取对应的配置。

  示例版本:Spring Boot 1.5.15.RELEASE,Spring Cloud Edgware.SR3

  (1)添加Spring Cloud Config相关依赖包

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter</artifactId>
  5. </dependency>
  6.  
  7. <!-- 热启动,热部署依赖包,为了调试方便,加入此包 -->
  8. <dependency>
  9. <groupId>org.springframework.boot</groupId>
  10. <artifactId>spring-boot-devtools</artifactId>
  11. <optional>true</optional>
  12. </dependency>
  13.  
  14. <!-- spring cloud config -->
  15. <dependency>
  16. <groupId>org.springframework.cloud</groupId>
  17. <artifactId>spring-cloud-config-server</artifactId>
  18. </dependency>
  19. </dependencies>
  20.  
  21. <!-- spring cloud dependencies -->
  22. <dependencyManagement>
  23. <dependencies>
  24. <dependency>
  25. <groupId>org.springframework.cloud</groupId>
  26. <artifactId>spring-cloud-dependencies</artifactId>
  27. <version>Edgware.SR3</version>
  28. <type>pom</type>
  29. <scope>import</scope>
  30. </dependency>
  31. </dependencies>
  32. </dependencyManagement>

  (2)启动类添加注解

  1. @SpringBootApplication
  2. @EnableConfigServer
  3. public class ConfigServiceApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(ConfigServiceApplication.class, args);
  6. }
  7. }

  (3)Config相关配置项

  1. server:
  2. port: 8888
  3. spring:
  4. application:
  5. name: config-server
  6. cloud:
  7. config:
  8. server:
  9. git:
  10. # 配置Git仓库地址
  11. uri: https://github.com/EdisonChou/Microservice.PoC.Steeltoe
  12. # 配置搜索目录
  13. search-paths: config
  14. # Git仓库账号(如果需要认证)
  15. username:
  16. # Git仓库密码(如果需要认证)
  17. password:

  这里我在GitHub中(https://github.com/EdisonChou/Microservice.PoC.Steeltoe/config目录中)放了一个sample-service-foo.properties的配置文件,里面只有两行内容:

  1. info.profile=default-1.0
  2. info.remarks=this is a remarks of default profile

  此外,对于Spring Cloud Config,端点与配置文件的映射规则如下:

/{application}/{profile}[/{label}]

/{application}-{profile}.yml

/{label}/{application}-{profile}.yml

/{application}-{profile}.properties

/{label}/{application}-{profile}.properties

其中,application: 表示微服务的虚拟主机名,即配置的spring.application.name

profile: 表示当前的环境,dev, test or production?

label: 表示git仓库分支,master or relase or others repository name? 默认是master

  (1)快速准备一个ASP.NET Core WebAPI项目(示例版本:2.1),这里以上一篇示例代码中的AgentService为例

  (2)通过NuGet安装Config相关包:

PM>Install-Package Steeltoe.Extensions.Configuration.ConfigServerCore

  (3)改写Program类

  1. public class Program
  2. {
  3. public static void Main(string[] args)
  4. {
  5. CreateWebHostBuilder(args).Build().Run();
  6. }
  7. public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
  8. WebHost.CreateDefaultBuilder(args)
  9. .AddConfigServer() // Add config server via steeltoe
  10. .UseUrls("http://*:8010")
  11. .UseStartup<Startup>();
  12. }

  (3)改写Starup类

  1. public class Startup
  2. {
  3. public Startup(IConfiguration configuration)
  4. {
  5. Configuration = configuration;
  6. }
  7. public IConfiguration Configuration { get; }
  8. // This method gets called by the runtime. Use this method to add services to the container.
  9. public void ConfigureServices(IServiceCollection services)
  10. {
  11. services.AddOptions();
  12. // Add Steeltoe Discovery Client service client
  13. services.AddDiscoveryClient(Configuration);
  14. // Add Steeltoe Config Client service container
  15. services.AddConfiguration(Configuration);
  16. services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
  17. // Add Configuration POCO
  18. services.Configure<ConfigServerData>(Configuration);
  19. }
  20. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
  21. public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  22. {
  23. if (env.IsDevelopment())
  24. {
  25. app.UseDeveloperExceptionPage();
  26. }
  27. app.UseMvc();
  28. // Add Steeltoe Discovery Client service
  29. app.UseDiscoveryClient();
  30. }
  31. }

  (4)为自定义配置内容封装一个类

  1. public class ConfigServerData
  2. {
  3. public Info Info { get; set; }
  4. }
  5. public class Info
  6. {
  7. public string Profile { get; set; }
  8. public string Remarks { get; set; }
  9. }

  对应:info.profile 以及 info.remarks

  (5)改写Controller,通过依赖注入获取Config内容

  1. [Route("api/[controller]")]
  2. [ApiController]
  3. public class ValuesController : ControllerBase
  4. {
  5. private IOptionsSnapshot<ConfigServerData> IConfigServerData { get; set; }
  6. private IConfigurationRoot Config { get; set; }
  7. public ValuesController(IConfigurationRoot config, IOptionsSnapshot<ConfigServerData> configServerData)
  8. {
  9. if (configServerData != null)
  10. {
  11. IConfigServerData = configServerData;
  12. }
  13. Config = config;
  14. }
  15. [HttpGet]
  16. [Route("/refresh")]
  17. public IActionResult Refresh()
  18. {
  19. if (Config != null)
  20. {
  21. Config.Reload();
  22. }
  23. return Ok("Refresh Config Successfully!");
  24. }
  25. // GET api/values
  26. [HttpGet]
  27. public ActionResult<IEnumerable<string>> Get()
  28. {
  29. var config = IConfigServerData.Value;
  30. return new string[] { $"Profile : {config.Info.Profile}",
  31. $"Remarks : {config.Info.Remarks}" };
  32. }
  33. }

  这里提供了一个刷新Config的方法Refresh,由于在没有借助消息总线的情况下,Config Server的Config刷新之后不会推送到各个Config Client,因此需要各个Config Client手动Refresh一下,如下图所示: 

  这里也提一下Spring Cloud Config推荐的刷新配置的方式,即集成Spring Cloud Bus,如下图所示:

  

  从上图中我们可以看出,它将Config Server加入消息总线之中,并使用Config Server的/bus/refersh端点来实现配置的刷新(一个观察者模式的典型应用)。这样,各个微服务只需要关注自身的业务逻辑,而无需再自己手动刷新配置。但是,遗憾的是,Pivotal目前在Steeltoe中还没有为.NET应用程序提供Spring Cloud Bus的集成,不过可以研究其机制,通过消息队列的客户端如RabbitMQ.Client去自己定制响应事件。

  (1)从Config Server中获取sampleservice-foo.properties配置文件

  

  (2)启动AgentService,验证是否能从ConfigServer获取到正确的配置内容

  

  (3)修改配置文件的属性值:info.profile改为default-1.1

  

  (4)验证Config Server是否已经获取到最新的info.profile

  

  (5)手动刷新AgentService的Config对象

  

  (6)验证是否能够获取最新的info.profile

  

  本文极简地介绍了一下Spring Cloud Config,并快速构建了一个用于演示的Config Server,然后通过Steeltoe OSS提供的Config客户端将ASP.NET Core与Spring Cloud Config进行集成,最后进行了验证能够正常地从Config Server中获取最新的配置内容。当然,关于Spring Cloud Config的内容还有许多,如果要真正使用Spring Cloud Config还需要考虑如何实现自动刷新的问题。从Spring Cloud Config与Apollo的使用体验上来说,本人是更加喜欢Apollo的,无论是功能的全面性和使用的体验来说,Apollo更胜一筹,而且国内的落地案例也更多。因此,如果项目中需要使用或集成统一配置中心,Apollo会是首选。

  Click => https://github.com/EdisonChou/Microservice.PoC.Steeltoe/tree/master/src/Chapter3-ConfigServer

Steeltoe官方文档:《Steeltoe Doc

Steeltoe官方示例:https://github.com/SteeltoeOSS/Samples

蟋蟀,《.NET Core 微服务架构 Steeltoe的使用

周立,《Spring Cloud与Docker 微服务架构实战

mazhen1991,《使用Spring Cloud Config来统一管理配置文件

冰与火IAF,《Spring Cloud:分布式配置中心 Config

 

版权声明:本文为edisonchou原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/edisonchou/p/dotnet_core_microservice_integrate_with_springcloud_config.html