微服务配置中心实战:Nacos 动态配置更新不重启服务的实现(附代码)

在微服务架构中,Nacos 作为配置中心,支持动态配置更新,无需重启服务即可生效。这提升了系统的灵活性和可用性。下面我将逐步解释实现原理,并提供完整代码示例。实现基于 Java 和 Spring Cloud Alibaba(兼容 Nacos),确保真实可靠。

实现原理
  1. Nacos 配置中心:Nacos 服务器存储配置(如数据库连接信息),客户端服务启动时拉取配置。
  2. 监听机制:客户端注册监听器(Listener),当 Nacos 中的配置变化时,服务器主动推送通知。
  3. 动态更新:客户端在收到通知后,实时更新内存中的配置变量(例如,通过 Spring 的 @RefreshScope 注解),无需重启服务。
  4. 关键点
    • 使用 Nacos 的 ConfigService 管理配置。
    • 监听器回调函数处理更新逻辑。
    • 配置项(如 $database.url$)在变化时自动刷新。
实现步骤

以下是详细步骤,假设您已部署 Nacos 服务器(默认地址 localhost:8848)。

  1. 添加依赖
    在 Maven 项目中,添加 Spring Cloud Alibaba 和 Nacos 客户端依赖:

    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>2022.0.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    

  2. 配置 Nacos 连接
    application.properties 中设置 Nacos 服务器地址和应用配置:

    spring.application.name=example-service
    spring.cloud.nacos.config.server-addr=localhost:8848
    # 指定配置的 dataId 和 group
    spring.cloud.nacos.config.data-id=example-config
    spring.cloud.nacos.config.group=DEFAULT_GROUP
    

  3. 编写服务代码
    创建一个 Spring Boot 服务,使用 @RefreshScope 注解实现动态更新:

    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RefreshScope // 关键:启用配置刷新
    public class ConfigController {
    
        @Value("${database.url}") // 注入配置项,如 $database.url$
        private String databaseUrl;
    
        @GetMapping("/config")
        public String getConfig() {
            return "Current database URL: " + databaseUrl;
        }
    }
    

  4. 注册监听器(可选,增强可靠性)
    在 Spring Boot 主类中添加自定义监听器,确保配置变化时触发更新:

    import com.alibaba.nacos.api.config.ConfigService;
    import com.alibaba.nacos.api.config.listener.Listener;
    import com.alibaba.nacos.api.exception.NacosException;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Bean;
    
    @SpringBootApplication
    public class Application implements CommandLineRunner {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
        @Autowired
        private ConfigService configService; // 自动注入 ConfigService
    
        @Override
        public void run(String... args) throws Exception {
            // 注册监听器
            configService.addListener("example-config", "DEFAULT_GROUP", new Listener() {
                @Override
                public void receiveConfigInfo(String configInfo) {
                    // 配置变化时执行
                    System.out.println("Config updated: " + configInfo);
                    // 这里可以添加自定义逻辑,如日志记录
                }
    
                @Override
                public Executor getExecutor() {
                    return null; // 使用默认线程池
                }
            });
        }
    }
    

测试动态更新
  1. 启动服务:运行 Spring Boot 应用。
  2. 修改 Nacos 配置
    • 登录 Nacos 控制台(http://localhost:8848/nacos)。
    • 在配置列表中,编辑 example-config(Data ID),例如将 database.url 的值从 jdbc:mysql://old-url 改为 jdbc:mysql://new-url
  3. 验证效果
    • 访问服务的 /config 端点(如 http://localhost:8080/config)。
    • 输出会立即更新为 Current database URL: jdbc:mysql://new-url,无需重启服务。
    • 控制台日志显示 Config updated: ...,证明监听器生效。
完整代码示例

以下是一个可运行的 Spring Boot 应用代码(基于上述步骤):

// 文件:src/main/java/com/example/Application.java
package com.example;

import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.Executor;

@SpringBootApplication
public class Application implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Autowired
    private ConfigService configService;

    @Override
    public void run(String... args) throws Exception {
        configService.addListener("example-config", "DEFAULT_GROUP", new Listener() {
            @Override
            public void receiveConfigInfo(String configInfo) {
                System.out.println("Config updated: " + configInfo);
            }

            @Override
            public Executor getExecutor() {
                return null;
            }
        });
    }

    @RestController
    @RefreshScope
    public static class ConfigController {
        @Value("${database.url}")
        private String databaseUrl;

        @GetMapping("/config")
        public String getConfig() {
            return "Current database URL: " + databaseUrl;
        }
    }
}

注意事项
  • 依赖版本:确保 Spring Cloud Alibaba 和 Nacos 版本兼容(参考官方文档)。
  • 配置格式:Nacos 支持 YAML、Properties 等;示例中使用 Properties 格式。
  • 性能影响:频繁更新可能增加网络开销,建议对关键配置项(如 $timeout$)设置合理刷新间隔。
  • 错误处理:添加异常捕获(如 NacosException),确保配置拉取失败时服务降级。
  • 扩展性:可结合 Spring Cloud Bus 实现批量服务更新,提升效率。

通过以上实现,您的微服务可以实现零停机配置更新。如果有更多细节问题(如 Kubernetes 集成),欢迎进一步提问!

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐