Cách lắng nghe sự thay đổi cấu hình từ Nacos trong Spring Boot
Trong Spring Boot, bạn có thể theo dõi các thay đổi cấu hình từ Nacos thông qua ba cách chính: sử dụng @RefreshScope, @NacosConfigListener hoặc cách lập trình với ConfigService. Dưới đây là các phương pháp chi tiết:
Phương pháp lắng nghe động
1. Dùng @RefreshScope và @Value (dành cho cấu hình đơn giản)
Phù hợp để làm mới các giá trị được đánh dấu bằng @Value.
Bước thực hiện
- Thêm thư viện Nacos vào dự án:
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <version>${spring-cloud-alibaba.version}</version> </dependency> - Cấu hình kết nối Nacos trong
application.yml:spring: application: name: your-service-name cloud: nacos: config: server-addr: 127.0.0.1:8848 file-extension: yaml - Tạo cấu hình trong bảng điều khiển Nacos:
- Data ID:
your-service-name.yaml - Group:
DEFAULT_GROUP - Nội dung mẫu:
config: key: "initial-value"
- Data ID:
- Sử dụng
@Valuevà@RefreshScopetrong lớp controller: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("${config.key}") private String configKey; @GetMapping("/config") public String getConfig() { return configKey; } } - Kiểm tra cập nhật:
- Thay đổi giá trị
config.keytrong Nacos và lưu lại. - Gọi endpoint
/actuator/refreshhoặc truy cập trực tiếp vào/configđể kiểm tra.
- Thay đổi giá trị
2. Sử dụng @NacosConfigListener (được khuyến nghị)
Phù hợp khi bạn muốn lắng nghe sự thay đổi của một dataId cụ thể và xử lý logic tùy chỉnh.
Bước thực hiện
- Thêm thư viện như trên.
- Tạo listener:
import com.alibaba.nacos.api.config.annotation.NacosConfigListener; import org.springframework.stereotype.Component; @Component public class NacosConfigListener { @NacosConfigListener( dataId = "your-service-name.yaml", groupId = "DEFAULT_GROUP", type = ConfigType.YAML ) public void onConfigChanged(String newConfig) { System.out.println("Cấu hình đã thay đổi: " + newConfig); // Phân tích cấu hình mới và cập nhật logic tại đây } } - Xử lý nội dung mới:
newConfiglà chuỗi cấu hình mới.- Có thể dùng
SnakeYAMLhoặcJacksonđể parse.
3. Lắng nghe theo cách lập trình với ConfigService
Cho phép kiểm soát hoàn toàn việc lắng nghe sự kiện.
Bước thực hiện
- Inject
ConfigService:import com.alibaba.nacos.api.config.ConfigService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class ManualNacosListener { @Autowired private ConfigService configService; public void addListener() throws NacosException { configService.addListener( "your-service-name.yaml", "DEFAULT_GROUP", new Listener() { @Override public void receiveConfigInfo(String configInfo) { System.out.println("Cấu hình mới: " + configInfo); } @Override public Executor getExecutor() { return null; } } ); } } - Đăng ký listener khi khởi động ứng dụng:
import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; @Component public class NacosListenerInitializer implements ApplicationRunner { @Autowired private ManualNacosListener manualNacosListener; @Override public void run(ApplicationArguments args) throws Exception { manualNacosListener.addListener(); } }
4. Kết hợp với @ConfigurationProperties để làm mới động
Phù hợp cho cấu hình phức tạp dưới dạng đối tượng.
Bước thực hiện
- Xây dựng lớp cấu hình:
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.stereotype.Component; @Component @RefreshScope @ConfigurationProperties(prefix = "config") public class MyConfig { private String key; private int timeout; public String getKey() { return key; } public void setKey(String key) { this.key = key; } public int getTimeout() { return timeout; } public void setTimeout(int timeout) { this.timeout = timeout; } } - Cấu hình trong Nacos:
config: key: "dynamic-value" timeout: 5000 - Sử dụng trong controller:
@RestController public class ConfigController { @Autowired private MyConfig myConfig; @GetMapping("/config") public MyConfig getConfig() { return myConfig; } }
5. Bật endpoint /actuator/refresh (tùy chọn)
Nếu bạn dùng @RefreshScope, hãy bật endpoint này:
management:
endpoints:
web:
exposure:
include: refresh,health,info
Sau đó gọi thủ công /actuator/refresh hoặc tự động qua message bus.
Tổng kết các phương pháp
| Phương pháp | Ứng dụng | Đặc điểm |
|---|---|---|
@RefreshScope + @Value | Cấu hình đơn giản | Phải gọi thủ công /actuator/refresh |
@NacosConfigListener | Lắng nghe tùy chỉnh | Lắng nghe trực tiếp dataId |
Programmatic ConfigService | Kiểm soát hoàn toàn | Linh hoạt nhưng phức tạp hơn |
@ConfigurationProperties | Đối tượng cấu hình | Hỗ trợ cấu trúc dữ liệu |
Khuyến nghị:
- Dùng
@RefreshScope+@Valuecho trường hợp đơn giản. - Dùng
@NacosConfigListenerkhi cần xử lý riêng biệt. - Dùng
@ConfigurationPropertiescho cấu hình phức tạp.
Sử dụng ConfigService trong Spring Boot
ConfigService không được tự động inject trong Spring Boot vì nó không thuộc quản lý của Spring Container. Bạn phải cấu hình thủ công hoặc dùng NacosConfigManager.
Giải pháp
1. Tự đăng ký ConfigService với @Bean
- Thêm dependency như trên.
- Định nghĩa bean:
import com.alibaba.nacos.api.config.ConfigService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.alibaba.cloud.nacos.NacosConfigProperties; @Configuration public class NacosConfig { @Autowired private NacosConfigProperties nacosConfigProperties; @Bean public ConfigService configService() throws Exception { return nacosConfigProperties.configServiceInstance(); } } - Inject vào lớp khác:
import com.alibaba.nacos.api.config.ConfigService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class AutoDelayJob { @Autowired private ConfigService configService; public void someMethod() { try { String config = configService.getConfig("dataId", "group", 5000); System.out.println("Nội dung cấu hình: " + config); } catch (Exception e) { e.printStackTrace(); } } }
2. Dùng NacosConfigManager (khuyến nghị)
import com.alibaba.cloud.nacos.NacosConfigManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class AutoDelayJob {
@Autowired
private NacosConfigManager nacosConfigManager;
public void someMethod() {
try {
ConfigService configService = nacosConfigManager.getConfigService();
String config = configService.getConfig("dataId", "group", 5000);
System.out.println("Nội dung cấu hình: " + config);
} catch (Exception e) {
e.printStackTrace();
}
}
}
3. Kiểm tra cấu hình Nacos
- Đảm bảo
application.ymlcấu hình đúng địa chỉ Nacos. - Đảm bảo đã thêm thư viện
spring-cloud-starter-alibaba-nacos-config. - Kiểm tra xem máy chủ Nacos có khả dụng không.
Tổng kết
| Phương pháp | Ứng dụng | Ưu điểm |
|---|---|---|
Đăng ký thủ công ConfigService | Kiểm soát trực tiếp | Linh hoạt nhưng phức tạp |
Dùng NacosConfigManager | Phương pháp chính | Đơn giản, được khuyến nghị |
| Kiểm tra cấu hình | Xử lý lỗi cơ bản | Đảm bảo kết nối Nacos |
Khuyến nghị:
- Sử dụng
NacosConfigManagerđể lấyConfigServicemột cách dễ dàng. - Nếu gặp lỗi khi inject
ConfigService, kiểm tra lại cấu hình và phụ thuộc.