Consul配置中心

配置中心案例演示

需求

通用全局配置信息,直接注册进Consul服务器,从Consul获取。

添加依赖

8001模块添加如下依赖

<!--SpringCloud consul config-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-consul-config</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>

新增yaml配置文件

application.ymlbootstrap.yml 的区别

在 Spring Cloud 架构中,配置文件不仅仅存放在本地,还可能来自远程配置中心(如 Nacos、Consul、Spring Cloud Config)。为了实现外部化配置的加载与管理,Spring Cloud 在应用启动过程中引入了两个上下文:Bootstrap ContextApplication Context

  1. application.yml

    是用户级配置文件,主要用于定义业务相关的配置信息,如:端口号、数据源、日志级别、服务名等。这些配置属于应用自身的资源定义。

  2. bootstrap.yml

    是系统级配置文件,主要用于定义应用启动初期所需的系统级参数,如:配置中心地址、注册中心地址、加密解密密钥等。它的加载优先级高于 application.yml

  3. Bootstrap Context 的作用

    Spring Cloud 启动时,会首先创建一个独立的 Bootstrap Context,它是 Application Context 的父上下文。在应用初始化阶段,Bootstrap Context 会负责:

    • 从外部配置中心加载配置信息;
    • 解析远程属性并注入到共享的 Environment 中;
    • 将这些配置优先注入到应用环境。
  4. 配置优先级机制

    Bootstrap 加载的属性具有更高优先级,默认情况下不会被 application.yml 覆盖。通过这种机制,Spring Cloud 能够确保系统级配置(如远程配置中心的连接信息)优先生效,从而正确加载应用的后续配置。

  5. 文件使用方式

    在实际项目中,bootstrap.ymlapplication.yml 可以:

    • 单独使用(推荐分离系统级与业务级配置);
    • 或者共存(系统级配置放入 bootstrap.yml,业务配置放入 application.yml)。
  6. 加载顺序

    启动流程中,bootstrap.yml 总是在 application.yml 之前加载,以保证外部配置能够优先生效并正确注入。

增加bootstrap.yml

spring:
  application:
    name: cloud-payment-service
  #### Spring Cloud Consul for Service Discovery
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        service-name: ${spring.application.name}
      config:
        profile-separator: '-' # default value is ",",we update '-'
        format: YAML

修改application.yml

  1. 将服务名称和consul相关配置删除。
  2. 增加profiles.active配置项,设置激活哪个配置文件。
server:
  port: 8001
 
# ==========applicationName + druid-mysql8 driver===================
spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss  # 日期格式化
    time-zone: GMT+8 # 时区
 
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db2025?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
    username: root
    password: 12345678
 
  profiles:
    active: dev # 多环境配置加载内容dev/prod,不写就是默认default配置
# ========================mybatis===================
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.sun.cloud.entities
  configuration:
    map-underscore-to-camel-case: true

consul服务器key/value配置填写

img
创建config文件夹,以/结尾
img
config文件夹下分别创建其它3个文件夹,以/结尾
config/cloud-payment-service/
config/cloud-payment-service-dev/
config/cloud-payment-service-prod/
img
上述3个文件夹下分别创建data内容,data不再是文件夹
imgimgimg

测试

8001创建一个controller,进行测试
package com.sun.cloud.controller;
 
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class ConsulController {
 
    @Value("${server.port}")
    private String port;
 
    @Value("${author.info}")
    private String info;
 
    @GetMapping(value = "/consul/info")
    private String getInfoByConsul() {
        return "consul配置:" + info + "。本机端口:" + port;
    }
}

因为在application.yaml中配置了profiles.active=dev,所以默认激活的是dev环境的配置。

image.png
修改application.yaml,激活prod环境
server:
  port: 8001
 
# ==========applicationName + druid-mysql8 driver===================
spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss  # 日期格式化
    time-zone: GMT+8 # 时区
 
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db2025?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true
    username: root
    password: 12345678
 
  profiles:
    active: prod # 多环境配置加载内容dev/prod,不写就是默认default配置
# ========================mybatis===================
mybatis:
  mapper-locations: classpath:mapper/*.xml
  type-aliases-package: com.sun.cloud.entities
  configuration:
    map-underscore-to-camel-case: true
image.png

动态刷新

现在,如果在Consul中,对配置文件进行修改,会发现新的配置并没有生效,除非重新启动8001。

主启动类添加@RefreshScope

package com.sun.cloud;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import tk.mybatis.spring.annotation.MapperScan;
 
@RefreshScope
@EnableDiscoveryClient
@SpringBootApplication
@MapperScan("com.sun.cloud.mapper")
public class Main8001 {
    public static void main(String[] args) {
        SpringApplication.run(Main8001.class, args);
    }
}

参数说明

watch.delay

spring.cloud.consul.config.watch.delay

  • 作用‌:定义轮询检查Consul配置变化的间隔时间(单位为毫秒)
  • ‌默认值‌:通常为1000(即1秒),具体取决于Spring Cloud版本。
  • 工作机制‌:通过定时任务周期性地向Consul发起请求,检测配置是否发生变更。例如,若设置为5000,则每5秒检查一次配置更新‌。
  • 使用场景‌:需根据业务对配置实时性的要求调整该值。较小的值(如1秒)能更快感知变化,但会增加Consul服务端压力;较大的值(如30秒)适用于对实时性要求较低的场景‌。

watch.wait-time

spring.cloud.consul.config.watch.wait-time

  • 作用‌:指定每次查询Consul配置时,请求的最大阻塞等待时间(单位为秒)
  • 默认值‌:通常为55秒,接近Consul Agent默认的会话超时时间(60秒)以避免超时中断‌。
  • 工作机制‌:基于Consul的长轮询(Long Polling)机制,客户端发起请求后,若在此期间配置未变化,请求会阻塞直到超时或配置更新。例如,设置为30秒时,若配置在30秒内变化,请求立即返回;否则30秒后返回无变更结果‌。
  • 使用场景‌:调整此值可平衡响应速度和资源占用。较长的等待时间(如默认55秒)减少频繁轮询,但可能导致客户端线程阻塞;较短的等待时间(如10秒)适用于需要快速重试的场景‌。
两者协同作用

delay决定检查频率,而wait-time优化单次请求的效率。例如,若设置delay=5000(5秒)和wait-time=30,则每5秒发起一次最长阻塞30秒的请求,实际间隔可能因wait-time的阻塞而动态调整‌。

参数设置

下面设置delay为10s,进行测试

spring:
  application:
    name: cloud-payment-service
  #### Spring Cloud Consul for Service Discovery
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        service-name: ${spring.application.name}
      config:
        profile-separator: '-' # default value is ",",we update '-'
        format: YAML
        watch:
          delay: 10000

测试

  1. 重启服务,请求测试
image.png
  1. 修改consul配置
image.png
  1. 再次请求
image.png
注意

watch.delay=10000,并不是说修改配置10秒后,才触发更新。

📝 这笔记是之前学习的时候写的,我又重新跑了一遍项目,这次动态刷新居然没有生效了😭,先记录一下,后续再进行排查。

配置持久化

  1. 重启Consul,发现之前的配置全部丢失。
  2. 在Consul中,数据持久化主要是指如何确保在Consul服务重启或故障恢复后,其存储的数据(如键值对、服务注册信息等)能够被恢复。
img

持久化的方法

选择合适的数据持久化方案取决于你的具体需求,包括:可靠性、性能和成本等因素。对于大多数生产环境,建议使用外部存储系统或Consul Enterprise的集成存储功能,以获得更好的数据持久性和可管理性。同时,定期的数据备份也是不可或缺的。

方法一:使用本地文件系统

Consul默认使用本地文件系统来存储数据。这种方式简单易用,但依赖于底层文件系统的可靠性。当Consul作为服务器运行时,它会将数据存储在本地磁盘上,通常是在/opt/consul/data目录下(位置可能根据安装方式和操作系统有所不同)。

配置方法:在Consul的配置文件中(通常是consul.hclconsul.json),可以通过设置data_dir来指定数据存储目录。

data_dir = "/path/to/your/data/dir"

方法二:使用外部存储系统

为了增强数据的可靠性和可扩展性,Consul支持将数据存储在外部存储系统中,如Consul的集成存储(如Consul Enterprise的集成存储功能)或第三方存储系统(如Amazon S3, Google Cloud Storage, Azure Blob Storage等)。

配置方法:对于外部存储系统,通常需要在Consul的配置文件中进行相应的配置。例如,使用Amazon S3作为后端存储:

storage "s3" {
  bucket   = "your-bucket-name"
  region   = "your-region"
  access_key = "your-access-key"
  secret_key = "your-secret-key"
  encrypt  = true # 可选,使用加密
  acl_token = "your-acl-token" # 可选,用于访问控制
}

方法三:使用Consul Enterprise的集成存储

如果你使用的是Consul Enterprise版本,你可以利用其集成的存储解决方案,如Consul的集成数据库(如PostgreSQL, MySQL, CockroachDB等)。这为数据提供了更高级的持久化和备份功能。

配置方法:使用集成数据库时,你需要在Consul的配置文件中指定数据库连接信息:

storage "consul" {
  address = "127.0.0.1:8500" # Consul agent地址
  scheme = "http" # 或者 "https"
}

数据备份与恢复

无论使用哪种持久化方法,定期备份数据都是非常重要的。Consul提供了工具和API来帮助你备份和恢复数据。例如,你可以使用consul snapshot命令来创建快照,并使用该快照进行恢复。

  1. 创建快照
consul snapshot save /path/to/backup.snap
  1. 从快照恢复
consul snapshot restore /path/to/backup.snap

演示持久化

Windows下配置持久化

创建配置文件存储文件夹

consul.exe同级目录新建data文件夹。

编写bat文件
  1. 将 Consul 配置成系统服务,以后台的方式运行,指定绑定的地址,并且指定配置文件存放目录,服务自动启动。
  2. Consul 的内置存储默认是启用并持久化的。你可以在启动 Consul 时不指定额外的配置文件或命令行参数,因为 Consul 会自动处理数据的持久化。
  3. -dev 参数是用于开发模式,它在内存中运行,不进行持久化。对于生产环境,你应该去掉 -dev 参数,并通过配置文件或环境变量来指定节点的角色(server 或 client)和其他配置。
@echo.服务启动......  
@echo off  
@sc create Consul binpath= "D:\devSoft\consul_1.17.0_windows_386\consul.exe agent -server -ui -bind=127.0.0.1 -client=0.0.0.0 -bootstrap-expect  1  -data-dir D:\devSoft\consul_1.17.0_windows_386\mydata   "
@net start Consul
@sc config Consul start= AUTO  
@echo.Consul start is OK......success
@pause
运行bat脚本文件

以管理员权限打开

MacOS下配置持久化

创建持久化存储目录
mkdir -p consul/data
chmod 700 consul/data
启动Consul
consul agent -server -ui -bind=127.0.0.1 -client=0.0.0.0 -bootstrap-expect 1 -data-dir 存储目录

相关文章

评论区