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

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 本文极简地介绍了一下Spring Cloud Config,并快速构建了一个用于演示的Config Server,然后通过Steeltoe OSS提供的Config客户端将ASP.NET Core与Spring Cloud Config进行集成,最后进行了验证能够正常地从Config Server中获取最新的配置内容。

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

一、关于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来获取对应的配置。

二、快速构建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一下,如下图所示: 

  这里也提一下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

目录
相关文章
|
5天前
|
负载均衡 Java API
Java一分钟之-Spring Cloud OpenFeign:声明式服务调用
【6月更文挑战第9天】Spring Cloud OpenFeign是声明式服务调用库,简化了微服务间调用。通过动态代理,它允许开发者用Java接口调用HTTP服务,支持服务发现、负载均衡。本文介绍了OpenFeign的基本概念,展示了如何添加依赖、开启客户端和定义服务接口。还讨论了接口调用失败、超时重试和日志配置等问题及其解决方案,并提供了自定义Feign配置的代码示例。通过学习,读者可以更好地在微服务架构中使用OpenFeign进行服务通信。
155 4
|
6天前
|
消息中间件 负载均衡 Java
Java一分钟之-Spring Cloud:微服务架构工具集
【6月更文挑战第8天】本文介绍了Spring Cloud的核心组件,包括Eureka(服务注册与发现)、Ribbon(客户端负载均衡)、Zuul(API网关)、Hystrix(断路器)、Spring Cloud Config(配置中心)和Spring Cloud Bus(事件总线)。文中强调了各组件的易错点,如Eureka的服务注册失败、Ribbon的配置、Zuul的路由错误、Hystrix的启用及配置、Config Server的加载失败和Bus的通讯问题,并给出了相应的代码示例和解决建议。在实际开发中,关注日志和使用调试工具是保证微服务系统稳定运行的关键。
85 6
|
2天前
|
负载均衡 前端开发 Java
OpenFeign:Spring Cloud声明式服务调用组件
该文本是关于OpenFeign在Spring Cloud中的使用的问答总结。涉及的问题包括:OpenFeign是什么,Feign与OpenFeign的区别,如何使用OpenFeign进行远程服务调用,OpenFeign的超时控制以及日志增强。OpenFeign被描述为Spring官方的声明式服务调用和负载均衡组件,它支持使用注解进行接口定义和服务调用,如@FeignClient和@EnableFeignClients。OpenFeign与Feign的主要区别在于OpenFeign支持Spring MVC注解。超时控制通过Ribbon进行设置,默认超时时间为1秒。
|
4天前
|
Java API 开发者
Java一分钟之-Spring Cloud Gateway:API网关
【6月更文挑战第10天】Spring Cloud Gateway是Spring Cloud生态中的API网关组件,基于Spring Framework 5、Reactor和Spring Boot 2.0,支持响应式编程。它提供路由转发、过滤器链(包括预处理、路由和后处理)和断言功能。快速入门涉及添加相关依赖和配置路由规则。常见问题包括路由冲突、过滤器顺序和性能瓶颈。通过动态路由和过滤器示例,展示了其灵活性。Spring Cloud Gateway是微服务架构的有力工具,可提升系统稳定性和开发效率。
110 0
|
5天前
|
监控 Java UED
Java一分钟之-Spring Cloud Netflix Hystrix:容错管理
【6月更文挑战第9天】Spring Cloud Hystrix是用于微服务容错管理的库,通过断路器模式防止服务雪崩。本文介绍了Hystrix的基本概念,如断路器、线程隔离和fallback机制,并展示了如何快速上手,包括添加依赖、启用注解和编写Hystrix命令。此外,还讨论了常见问题(如断路器打开、资源泄漏和不当的Fallback策略)及其解决方案。通过自定义Hystrix指标监控,可以进一步优化系统性能。理解Hystrix工作原理并适时调整配置,对于构建健壮的微服务至关重要。
110 3
|
5天前
|
缓存 负载均衡 Java
Java一分钟之-Spring Cloud Netflix Ribbon:客户端负载均衡
【6月更文挑战第9天】Spring Cloud Netflix Ribbon是客户端负载均衡器,用于服务间的智能路由。本文介绍了Ribbon的基本概念、快速入门步骤,包括添加依赖、配置服务调用和使用RestTemplate。此外,还讨论了常见问题,如服务实例选择不均、超时和重试设置不当、服务列表更新不及时,并提供了相应的解决策略。最后,展示了如何自定义负载均衡策略。理解并正确使用Ribbon能提升微服务架构的稳定性和效率。
74 3
|
6天前
|
安全 Java 开发者
Java一分钟之-Spring Cloud Netflix Eureka:服务注册与发现
【6月更文挑战第8天】Spring Cloud Eureka是微服务架构的关键,提供服务注册与发现功能。本文讲解Eureka工作原理、配置、常见问题及解决方案。Eureka包含Server(管理服务状态)和Client(注册服务实例并发现服务)。快速入门包括启动Eureka Server和创建Eureka Client。常见问题涉及服务注册不上、服务下线和客户端注册信息不准确,可通过检查网络、理解自我保护机制和配置元数据解决。此外,文中还提及健康检查、安全配置和集群部署等高级实践,以增强系统健壮性和扩展性。
54 8
|
6天前
|
存储 消息中间件 Java
Java一分钟之-Spring Cloud Config:外部化配置
【6月更文挑战第8天】Spring Cloud Config提供外部化配置,通过Config Server管理和版本控制微服务配置。本文涵盖Config Server与Client的配置、常见错误、多环境配置、实时更新及使用示例。注意配置服务器URL、环境变量设置、Bus配置以及安全问题。使用Config能提升系统灵活性和可维护性,但要留意日志以确保配置正确和安全。
86 10
|
7天前
|
监控 Java 数据库连接
Java一分钟之-Spring Boot:快速开发微服务
【6月更文挑战第7天】本文探讨了Spring Boot开发中的常见问题,包括起步依赖与版本管理、自动配置、启动类位置、日志配置、数据库连接、错误处理和Actuator监控。建议使用最新稳定版Spring Boot,通过`spring-boot-starter-parent`管理版本,理解自动配置原理,正确放置启动类,配置日志级别,准确设置数据库连接参数,自定义全局异常处理器,以及启用Actuator进行监控。不断学习和实践是应对各种问题的关键。
22 1
|
8天前
|
运维 负载均衡 Java
认识微服务,认识Spring Cloud
认识微服务,认识Spring Cloud
62 2