10.5、动态配置刷新
动态配置刷新
动态配置刷新是配置中心的核心功能之一。本节将学习如何实现动态配置刷新。
本节将学习:@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 ID:
product-service.yaml - Group:
DEFAULT_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:测试动态配置刷新
测试步骤:
-
启动商品服务:
cd mall-microservices/product-service mvn spring-boot:run -
查看当前配置:
curl http://localhost:8082/api/products/config应该返回:
low-stock-threshold: 10 -
在 Nacos 控制台修改配置:
- 进入"配置管理" -> "配置列表"
- 找到
product-service.yaml - 点击"编辑"
- 修改
low-stock-threshold: 20 - 点击"发布"
-
验证配置刷新:
- 等待几秒钟(Nacos 会推送配置变更)
- 再次调用接口查看配置
- 应该返回:
low-stock-threshold: 20 - 无需重启服务
配置变更监听
监听机制
Nacos 配置变更监听流程:
- 客户端长轮询:Nacos 客户端定期向服务器查询配置是否有变化
- 配置变更推送:服务器检测到配置变更后,立即推送给客户端
- 触发刷新事件:客户端收到变更后,触发 Spring Cloud 的刷新事件
- 更新 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:调整库存阈值
- 业务需求:根据业务情况动态调整低库存阈值
- 实现方式:
- 在 Nacos 中修改
product.low-stock-threshold配置 - 配置自动刷新,无需重启服务
- 商品服务立即使用新的阈值
- 在 Nacos 中修改
场景2:调整分页大小
- 业务需求:根据系统负载调整默认分页大小
- 实现方式:
- 在 Nacos 中修改
product.default-page-size配置 - 配置自动刷新
- 新的分页请求立即使用新配置
- 在 Nacos 中修改
场景3:开关功能
- 业务需求:动态开启/关闭缓存功能
- 实现方式:
- 在 Nacos 中修改
product.cache-enabled配置 - 配置自动刷新
- 缓存功能立即生效或失效
- 在 Nacos 中修改
配置刷新验证接口
文件路径: 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); } }
配置刷新最佳实践
使用建议
配置刷新的最佳实践:
-
合理使用 @RefreshScope:
- 只对需要动态刷新的 Bean 使用
- 避免过度使用,影响性能
-
配置变更通知:
- 记录配置变更日志
- 通知相关人员配置已变更
-
配置验证:
- 在配置变更时验证配置的有效性
- 无效配置应该回滚
-
灰度发布:
- 重要配置变更可以先在测试环境验证
- 再发布到生产环境
常见问题
可能遇到的问题:
-
配置不刷新:
- 问题:修改 Nacos 配置后,应用配置没有更新
- 解决:
- 检查是否使用了
@RefreshScope注解 - 检查 Nacos 配置的 Data ID 和 Group 是否正确
- 查看应用日志,确认是否收到配置变更通知
- 检查是否使用了
-
刷新后 Bean 丢失:
- 问题:配置刷新后,某些 Bean 的状态丢失
- 解决:
- 避免在
@RefreshScopeBean 中存储状态 - 使用外部存储(如 Redis)保存状态
- 避免在
官方资源
- Nacos 动态配置:https://nacos.io/docs/use-nacos-with-spring-cloud.html
- Spring Cloud Config Refresh:https://spring.io/projects/spring-cloud-config
本节小结
在本节中,我们学习了动态配置刷新:
第一个是 @RefreshScope 注解。 使用 @RefreshScope 标记需要刷新的 Bean,配置变更时自动刷新。
第二个是配置变更监听。 实现了配置变更监听器,监听配置变化事件并处理。
第三个是自动刷新机制。 了解了 Nacos 配置变更的监听机制和自动刷新流程。
第四个是手动刷新。 使用 Actuator 的 RefreshEndpoint 手动触发配置刷新。
第五个是在商城项目中的实际应用。 在商品服务中实现了库存阈值的动态配置刷新,无需重启服务即可生效。
第六个是配置刷新最佳实践。 了解了配置刷新的使用建议和常见问题解决方案。
这就是动态配置刷新。通过动态配置刷新,我们可以在不重启服务的情况下调整系统配置,提高了系统的灵活性和可用性。在下一节,我们将学习多环境配置。