5.Nacos 配置中心化改造与短信 Debug 模式动态切换实践

Nacos 配置中心化改造与短信 Debug 模式动态切换实践

1. 第一步将配置文件迁移到Nacos

1.1 创建ivy-service-sys.yml

在Nacos配置中心创建服务专属配置文件,定义调试开关与服务端口基础配置,具体内容如下:

yaml 复制代码
ivy:
  auth:
    debug: false
server:
  port: 8101

服务启动后,配置正常加载,运行日志如下:

1.2 提取公用的配置

为解决配置冗余、多服务重复维护的问题,将项目中通用的中间件配置抽离为独立公共配置文件,统一管理、全局复用。

1.2.1 将mysql配置文件提出来,放在mybatis.yml中

抽离MySQL数据库连接、Druid连接池、MyBatis相关通用配置,独立为mybatis.yml配置文件:

yaml 复制代码
ivy:
  mysql:
    ip:  192.168.55.140 
    port:  3306 
    driverClassName: com.mysql.cj.jdbc.Driver
    database:  ivy-simple 
    username: root 
    password:  Ivy@2024 
spring:
  datasource:
    url: jdbc:mysql://${ivy.mysql.ip}:${ivy.mysql.port}/${ivy.mysql.database}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useUnicode=true&useSSL=false&autoReconnect=true&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&nullCatalogMeansCurrent=true
    username: ${ivy.mysql.username}
    password: ${ivy.mysql.password}
    db-type: mysql
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: ${ivy.mysql.driverClassName}
    druid:
      initial-size: 10
      max-active: 100
      min-idle: 10
      max-wait: 60000
      pool-prepared-statements: true
      max-pool-prepared-statement-per-connection-size: 20
      time-between-eviction-runs-millis: 60000
      min-evictable-idle-time-millis: 300000
      validation-query: SELECT 1 FROM DUAL
      test-while-idle: true
      test-on-borrow: true
      test-on-return: false
      db-type: mysql
mybatis:
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  mapperLocations: classpath*:mapper/*Mapper.xml
1.2.2 同样提取redis.yml

抽离Redis基础连接配置与Redisson分布式锁配置,独立为redis.yml通用配置文件:

yaml 复制代码
ivy:
  redis:
    ip:  192.168.55.140 
    port: 6379 
    password: wayhua 
    database: 2 
spring:
  data:
    redis:
      host: ${ivy.redis.ip}
      password: ${ivy.redis.password}
      port: ${ivy.redis.port}
      database: ${ivy.redis.database}
    redisson:
      enabled: true
      mode: SINGLE

1.3 修改原来的application.yml

修改项目本地application.yml,移除冗余配置,仅保留Nacos连接配置,并通过配置导入规则,加载Nacos上的公共配置与服务专属配置:

yaml 复制代码
ivy:
  nacos:
    ip: 192.168.55.140
    port: 8848
    namespace: ivy-simple
    username: nacos
    password: nacos
spring:
  application:
    name: ivy-service-sys
  config:
    import:
      - optional:nacos:redis.yml
      - optional:nacos:mybatis.yml
      - optional:nacos:${spring.application.name}.yml
  cloud:
    nacos:
      config:
        server-addr: ${ivy.nacos.ip}:${ivy.nacos.port}
        namespace:  ${ivy.nacos.namespace}
        group: DEFAULT_GROUP
        enabled: true
      discovery:
        server-addr: ${ivy.nacos.ip}:${ivy.nacos.port}
        namespace:  ${ivy.nacos.namespace}
        group: DEFAULT_GROUP
      username:  ${ivy.nacos.username}
      password:  ${ivy.nacos.password}

1.4 测试确保运行结果

完成所有配置迁移与修改后,启动项目进行测试,服务正常启动、Nacos配置加载生效,运行结果如下:

2. 增加动态Debug

原项目中isDebug调试开关变量在多个业务类中重复使用,且仅能在服务启动时加载生效,无法动态修改。因此需抽离统一配置类,结合Nacos配置动态刷新能力,实现无需重启服务、动态切换调试模式的效果。

2.1 增加配置文件AuthConfig

新建统一授权调试配置类,添加Nacos动态刷新注解,绑定配置文件中的debug开关参数,实现配置动态感知:

java 复制代码
package vip.wayhua.ivy.sys.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
@Component
@RefreshScope
public class AuthConfig {
    @Value("${ivy.auth.debug:false}")
    private boolean isDebug;
    public boolean isDebug() {
        return isDebug;
    }
    public void setDebug(boolean debug) {
        isDebug = debug;
    }
}

2.2 修改使用的两个地方

改造原使用调试开关的两个业务实现类,注入新建的AuthConfig配置类,将原有硬编码的isDebug变量,统一替换为配置类动态获取的参数,具体修改类为AuthServiceImpl、AbstractSmsServiceImpl:

java 复制代码
@Service
public class AuthServiceImpl implements AuthService {
    private static final Logger log = LoggerFactory.getLogger(AuthServiceImpl.class);
    @Autowired
    AuthConfig authConfig;
    
    
    //...
    
    
public class AbstractSmsServiceImpl implements SmsService {
    private static final Logger log = LoggerFactory.getLogger(AbstractSmsServiceImpl.class);
    @Autowired
    AuthConfig authConfig;
    //...
    
   //调用处将isDebug->authConfig.isDebug()   

核心修改:所有原调试开关的调用位置,均替换为 authConfig.isDebug() 动态获取配置值。

2.3 重新调整AuthServiceImpl

原业务逻辑基于单例模式实现,仅在服务启动时初始化一次短信服务实现类,配置变更后无法实时生效。本次改造取消启动时固定初始化逻辑,改为通过SpringUtils动态从容器获取Bean,实现每次调用接口时实时读取最新配置,适配动态切换需求:

java 复制代码
package vip.wayhua.ivy.sys.service.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import vip.wayhua.ivy.core.utils.SpringUtils;
import vip.wayhua.ivy.sys.config.AuthConfig;
import vip.wayhua.ivy.sys.dto.VerifyResDto;
import vip.wayhua.ivy.sys.service.AuthService;
import vip.wayhua.ivy.sys.service.SmsService;
@Service
public class AuthServiceImpl implements AuthService {
    private static final Logger log = LoggerFactory.getLogger(AuthServiceImpl.class);
    @Autowired
    AuthConfig authConfig;
    @Override
    public VerifyResDto getSmsCode(String mobile) {
        SmsService   service = getCurrentService();
        return service.getSmsCode(mobile);
    }
    @Override
    public String smsVerify(String mobile, String code, String verify) {
        SmsService service = getCurrentService();
        return service.smsVerify(mobile, code, verify);
    }
    /**
     * 动态注入对应环境的短信实现类
     */
    private SmsService getCurrentService() {
        log.error("isDebug->" + authConfig.isDebug());
        if (authConfig.isDebug()) {
            return SpringUtils.getBean(DebugSmsServiceImpl.class);
        } else {
            return SpringUtils.getBean(SmsServiceImpl.class);
        }
    }
}

2.4 动态修改nacos

完成代码改造后,无需重启项目,直接在Nacos控制台动态修改 ivy.auth.debug 的布尔值,即可实现调试模式与正式模式的实时切换,通过项目日志可清晰验证切换效果:

shell 复制代码
[15:00:22.519] ERROR v.w.i.s.s.i.AuthServiceImpl - isDebug->false
 [15:00:22.986] ERROR v.w.i.s.s.i.SmsServiceImpl - 【正式环境-发送短信】-【手机号:+8613866155391】-【验证码:null】-【验证信息:$2a$10$Op24G8GqrSTahvcQ9E56OuUDZF7gf2A4SFGwdPbk1QgCtVdF88uK6】
 [15:00:45.031] ERROR v.w.i.s.s.i.AuthServiceImpl - isDebug->true
 [15:00:45.134] ERROR v.w.i.s.s.i.DebugSmsServiceImpl - 【测试环境-发送短信】-【手机号:+8613866155391】-【验证码:217480】-【验证信息:$2a$10$18FojcVd.C4x84i3lNAcg.VOFvxh9BS29sPX1bbp2EeeFOx5BEj1m】
 [15:00:57.570] ERROR v.w.i.s.s.i.AuthServiceImpl - isDebug->false
 [15:00:57.675] ERROR v.w.i.s.s.i.SmsServiceImpl - 【正式环境-发送短信】-【手机号:+8613866155391】-【验证码:null】-【验证信息:$2a$10$NvcI/.cckWyBZKKohqawz.pEvi7rcnrdNdNtmccXcd3fT3w4lOtQy】
 [15:01:06.862] ERROR v.w.i.s.s.i.AuthServiceImpl - isDebug->true
 [15:01:06.958] ERROR v.w.i.s.s.i.DebugSmsServiceImpl - 【测试环境-发送短信】-【手机号:+8613866155391】-【验证码:066940】-【验证信息:$2a$10$jvHoD5bjNreb30yixK71g./mVwCxp1zl4uniq7m2IpVkmOqJ0GBsu】

日志可直观证明:修改Nacos配置后,项目可实时感知参数变化,自动切换短信发送的正式环境与测试环境逻辑,动态调试功能生效。

虽然实现了配置动态切换的功能,但结合实际业务场景来看,该功能的实用场景比较有限。正常的生产架构中,正式环境和测试环境一般是物理隔离、独立部署的,不会共用一套服务动态切换环境。我最初开发这个功能的核心初衷是为了在测试环境规避真实短信发送、节省短信服务资费成本,后续开发过程中才延伸出Nacos动态配置切换的实现思路。

end

相关推荐
PinkSun2 小时前
上线第一天,Redis和Docker联手给我上了一课
后端
清秋冷雨2 小时前
Harness Engineer系列(三):Harness工程化——AI编程的最后一里地
后端
Csvn2 小时前
itertools —— Python 最强迭代器工具箱实战
后端
冰暮流星2 小时前
flask之定义URL
后端·python·flask
程序员爱钓鱼3 小时前
为什么学习 Rust?Rust 能做什么?
后端·rust
二宝哥4 小时前
创建Gradle多模块SpringBoot项目
java·spring boot·后端
掘金者阿豪4 小时前
Docker命令太多记不住?用Portainer把容器管理变成可视化操作
后端
用户69371750013844 小时前
AI Agent 里的 Loop 到底是什么?
android·前端·后端
Rain的Java大神之路4 小时前
高并发下的抢优惠券如何设计
后端