10.5动态配置刷新

分类: Nacos配置中心

动态配置刷新

动态配置刷新是配置中心的核心功能之一。本节将学习如何实现动态配置刷新。

本节将学习:@RefreshScope 注解、配置变更监听、自动刷新机制,以及手动刷新。

在商城项目中实现动态配置刷新

步骤1:使用 @RefreshScope 注解

文件路径: mall-microservices/product-service/src/main/java/com/mall/productservice/config/ProductConfig.java

package com.mall.productservice.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.stereotype.Component; @Component @RefreshScope @ConfigurationProperties(prefix = "product") public class ProductConfig { private Integer defaultPageSize = 10; private Integer maxPageSize = 100; private Boolean cacheEnabled = true; private Integer cacheTtl = 3600; // 库存阈值配置(用于动态刷新) private Integer lowStockThreshold = 10; // getters and setters public Integer getDefaultPageSize() { return defaultPageSize; } public void setDefaultPageSize(Integer defaultPageSize) { this.defaultPageSize = defaultPageSize; } public Integer getMaxPageSize() { return maxPageSize; } public void setMaxPageSize(Integer maxPageSize) { this.maxPageSize = maxPageSize; } public Boolean getCacheEnabled() { return cacheEnabled; } public void setCacheEnabled(Boolean cacheEnabled) { this.cacheEnabled = cacheEnabled; } public Integer getCacheTtl() { return cacheTtl; } public void setCacheTtl(Integer cacheTtl) { this.cacheTtl = cacheTtl; } public Integer getLowStockThreshold() { return lowStockThreshold; } public void setLowStockThreshold(Integer lowStockThreshold) { this.lowStockThreshold = lowStockThreshold; } }

步骤2:在 Nacos 中添加配置

在 Nacos 控制台添加/更新配置:

  • Data IDproduct-service.yaml
  • GroupDEFAULT_GROUP
  • 配置内容
product: default-page-size: 10 max-page-size: 100 cache-enabled: true cache-ttl: 3600 low-stock-threshold: 10 # 低库存阈值

步骤3:在代码中使用配置

文件路径: mall-microservices/product-service/src/main/java/com/mall/productservice/service/impl/ProductServiceImpl.java

package com.mall.productservice.service.impl; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.mall.productservice.config.ProductConfig; import com.mall.productservice.entity.Product; import com.mall.productservice.mapper.ProductMapper; import com.mall.productservice.service.ProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService { @Autowired private ProductConfig productConfig; @Override public Page<Product> getProducts(Integer page, Integer size, Long categoryId, String keyword) { // 使用配置中的默认分页大小 if (size == null || size <= 0) { size = productConfig.getDefaultPageSize(); } // 限制最大分页大小 if (size > productConfig.getMaxPageSize()) { size = productConfig.getMaxPageSize(); } Page<Product> productPage = new Page<>(page, size); // 查询逻辑... return productPage; } /** * 检查低库存商品 * 使用动态配置的低库存阈值 */ public boolean isLowStock(Integer stock) { return stock <= productConfig.getLowStockThreshold(); } }

步骤4:测试动态配置刷新

测试步骤:

  1. 启动商品服务

    cd mall-microservices/product-service mvn spring-boot:run
  2. 查看当前配置

    curl http://localhost:8082/api/products/config

    应该返回:low-stock-threshold: 10

  3. 在 Nacos 控制台修改配置

    • 进入"配置管理" -> "配置列表"
    • 找到 product-service.yaml
    • 点击"编辑"
    • 修改 low-stock-threshold: 20
    • 点击"发布"
  4. 验证配置刷新

    • 等待几秒钟(Nacos 会推送配置变更)
    • 再次调用接口查看配置
    • 应该返回:low-stock-threshold: 20
    • 无需重启服务

配置变更监听

监听机制

Nacos 配置变更监听流程:

  1. 客户端长轮询:Nacos 客户端定期向服务器查询配置是否有变化
  2. 配置变更推送:服务器检测到配置变更后,立即推送给客户端
  3. 触发刷新事件:客户端收到变更后,触发 Spring Cloud 的刷新事件
  4. 更新 Bean 属性:@RefreshScope 标记的 Bean 会被重新创建,使用新配置

在商城项目中监听配置变更

文件路径: mall-microservices/product-service/src/main/java/com/mall/productservice/listener/ConfigChangeListener.java

package com.mall.productservice.listener; import org.springframework.cloud.context.environment.EnvironmentChangeEvent; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; import java.util.Set; @Component public class ConfigChangeListener implements ApplicationListener<EnvironmentChangeEvent> { @Override public void onApplicationEvent(EnvironmentChangeEvent event) { Set<String> changedKeys = event.getKeys(); System.out.println("Configuration changed: " + changedKeys); // 可以在这里处理配置变更后的逻辑 // 例如:清除缓存、重新初始化等 for (String key : changedKeys) { if (key.startsWith("product.")) { System.out.println("Product config changed: " + key); // 处理商品配置变更 } } } }

自动刷新机制

刷新流程

手动刷新配置

使用 Actuator 刷新

启用 RefreshEndpoint:

文件路径: mall-microservices/product-service/src/main/resources/application.yml

management: endpoints: web: exposure: include: health,info,metrics,refresh endpoint: refresh: enabled: true

手动触发刷新:

# 调用刷新端点 curl -X POST http://localhost:8082/actuator/refresh # 响应示例 ["product.low-stock-threshold"]

在商城项目中的实际应用场景

场景1:调整库存阈值

  1. 业务需求:根据业务情况动态调整低库存阈值
  2. 实现方式
    • 在 Nacos 中修改 product.low-stock-threshold 配置
    • 配置自动刷新,无需重启服务
    • 商品服务立即使用新的阈值

场景2:调整分页大小

  1. 业务需求:根据系统负载调整默认分页大小
  2. 实现方式
    • 在 Nacos 中修改 product.default-page-size 配置
    • 配置自动刷新
    • 新的分页请求立即使用新配置

场景3:开关功能

  1. 业务需求:动态开启/关闭缓存功能
  2. 实现方式
    • 在 Nacos 中修改 product.cache-enabled 配置
    • 配置自动刷新
    • 缓存功能立即生效或失效

配置刷新验证接口

文件路径: mall-microservices/product-service/src/main/java/com/mall/productservice/controller/ConfigController.java

package com.mall.productservice.controller; import com.mall.productservice.common.Result; import com.mall.productservice.config.ProductConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; @RestController @RequestMapping("/api/products/config") public class ConfigController { @Autowired private ProductConfig productConfig; @GetMapping public Result<Map<String, Object>> getConfig() { Map<String, Object> config = new HashMap<>(); config.put("defaultPageSize", productConfig.getDefaultPageSize()); config.put("maxPageSize", productConfig.getMaxPageSize()); config.put("cacheEnabled", productConfig.getCacheEnabled()); config.put("cacheTtl", productConfig.getCacheTtl()); config.put("lowStockThreshold", productConfig.getLowStockThreshold()); return Result.success(config); } }

配置刷新最佳实践

使用建议

配置刷新的最佳实践:

  1. 合理使用 @RefreshScope

    • 只对需要动态刷新的 Bean 使用
    • 避免过度使用,影响性能
  2. 配置变更通知

    • 记录配置变更日志
    • 通知相关人员配置已变更
  3. 配置验证

    • 在配置变更时验证配置的有效性
    • 无效配置应该回滚
  4. 灰度发布

    • 重要配置变更可以先在测试环境验证
    • 再发布到生产环境

常见问题

可能遇到的问题:

  1. 配置不刷新

    • 问题:修改 Nacos 配置后,应用配置没有更新
    • 解决:
      • 检查是否使用了 @RefreshScope 注解
      • 检查 Nacos 配置的 Data ID 和 Group 是否正确
      • 查看应用日志,确认是否收到配置变更通知
  2. 刷新后 Bean 丢失

    • 问题:配置刷新后,某些 Bean 的状态丢失
    • 解决:
      • 避免在 @RefreshScope Bean 中存储状态
      • 使用外部存储(如 Redis)保存状态

官方资源

本节小结

在本节中,我们学习了动态配置刷新:

第一个是 @RefreshScope 注解。 使用 @RefreshScope 标记需要刷新的 Bean,配置变更时自动刷新。

第二个是配置变更监听。 实现了配置变更监听器,监听配置变化事件并处理。

第三个是自动刷新机制。 了解了 Nacos 配置变更的监听机制和自动刷新流程。

第四个是手动刷新。 使用 Actuator 的 RefreshEndpoint 手动触发配置刷新。

第五个是在商城项目中的实际应用。 在商品服务中实现了库存阈值的动态配置刷新,无需重启服务即可生效。

第六个是配置刷新最佳实践。 了解了配置刷新的使用建议和常见问题解决方案。

这就是动态配置刷新。通过动态配置刷新,我们可以在不重启服务的情况下调整系统配置,提高了系统的灵活性和可用性。在下一节,我们将学习多环境配置。