ASP.NET Core微服务之基于Steeltoe使用Spring Cloud Config统一管理配置

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

一、关于Spring Cloud Config

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

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

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

ASP.NET Core微服务之基于Steeltoe使用Spring Cloud Config统一管理配置

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

二、快速构建Config Server

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

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

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!-- 热启动,热部署依赖包,为了调试方便,加入此包 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>

        <!-- spring cloud config -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
    </dependencies>

    <!-- spring cloud dependencies -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Edgware.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

  (2)启动类添加注解

@SpringBootApplication
@EnableConfigServer
public class ConfigServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigServiceApplication.class, args);
    }
}

  (3)Config相关配置项

server:
  port: 8888

spring:
  application:
    name: config-server
  cloud:
    config:
      server:
        git:
          # 配置Git仓库地址
          uri: https://github.com/EdisonChou/Microservice.PoC.Steeltoe
          # 配置搜索目录
          search-paths: config
          # Git仓库账号(如果需要认证)
          username:
          # Git仓库密码(如果需要认证)
          password:

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

info.profile=default-1.0
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

三、ASP.NET Core中集成Config Server

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

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

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

  (3)改写Program类

    public class Program
    {
        public static void Main(string[] args)
        {
            CreateWebHostBuilder(args).Build().Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .AddConfigServer()  // Add config server via steeltoe
                .UseUrls("http://*:8010")
                .UseStartup<Startup>();
    }

  (3)改写Starup类

   public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddOptions();
            // Add Steeltoe Discovery Client service client
            services.AddDiscoveryClient(Configuration);
            // Add Steeltoe Config Client service container
            services.AddConfiguration(Configuration);
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            // Add Configuration POCO 
            services.Configure<ConfigServerData>(Configuration);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();
            // Add Steeltoe Discovery Client service
            app.UseDiscoveryClient();
        }
    }

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

    public class ConfigServerData
    {
        public Info Info { get; set; }
    }

    public class Info
    {
        public string Profile { get; set; }
        public string Remarks { get; set; }
    }

  对应:info.profile 以及 info.remarks

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

    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        private IOptionsSnapshot<ConfigServerData> IConfigServerData { get; set; }

        private IConfigurationRoot Config { get; set; }

        public ValuesController(IConfigurationRoot config, IOptionsSnapshot<ConfigServerData> configServerData)
        {
            if (configServerData != null)
            {
                IConfigServerData = configServerData;
            }

            Config = config;
        }

        [HttpGet]
        [Route("/refresh")]
        public IActionResult Refresh()
        {
            if (Config != null)
            {
                Config.Reload();
            }

            return Ok("Refresh Config Successfully!");
        }

        // GET api/values
        [HttpGet]
        public ActionResult<IEnumerable<string>> Get()
        {
            var config = IConfigServerData.Value;
            return new string[] { $"Profile : {config.Info.Profile}",
                $"Remarks : {config.Info.Remarks}" };
        }
    }

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

ASP.NET Core微服务之基于Steeltoe使用Spring Cloud Config统一管理配置

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

ASP.NET Core微服务之基于Steeltoe使用Spring Cloud Config统一管理配置

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

四、快速验证

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

ASP.NET Core微服务之基于Steeltoe使用Spring Cloud Config统一管理配置

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

ASP.NET Core微服务之基于Steeltoe使用Spring Cloud Config统一管理配置

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

ASP.NET Core微服务之基于Steeltoe使用Spring Cloud Config统一管理配置

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

ASP.NET Core微服务之基于Steeltoe使用Spring Cloud Config统一管理配置

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

ASP.NET Core微服务之基于Steeltoe使用Spring Cloud Config统一管理配置

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

ASP.NET Core微服务之基于Steeltoe使用Spring Cloud Config统一管理配置

五、小结

  本文极简地介绍了一下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

上一篇:检查单个变量的摘要统计量


下一篇:在大数据时期的营销该是什么样子的