Khi chuyển từ kiến trúc đơnolithic sang microservices, việc quản lý cấu hình trở nên phức tạp hơn nhiều. Mỗi dịch vụ có thể cần các cấu hình riêng biệt và đôi khi cần được cập nhật động để thực hiện các chức năng như giảm tải động, điều hướng lưu lượng, mở rộng hoặc thu hẹp quy mô.
Cấu Hình Địa Phương
Trong phát triển Spring Boot, cấu hình có thể được đặt trong file config hoặc sử dụng annotation @Value để lấy từ file yaml. Ví dụ:
public class AppConfig {
public static final String SUCCESS_CODE = "0000";
public static final String ERROR_CODE = "0001";
}
Hoặc:
@Component
public class HttpConfig {
public static String CORE_POOL_SIZE;
@Value("${async.corePoolSize}")
public void setCorePoolSize(String corePoolSize) {
HttpConfig.CORE_POOL_SIZE = corePoolSize;
}
}
Cả hai cách trên đều giữ cấu hình trong ứng dụng địa phương. Để thay đổi cấu hình, cần phải dừng ứng dụng đang chạy trên máy chủ Linux, chỉnh sửa cấu hình sau đó khởi động lại ứng dụng. Việc này khá phức tạp và dễ gây lỗi nếu có nhiều cấu hình cần thay đổi.
Cấu Trình Trung Tâm
Cấu trình trung tâm giúp quản lý tập trung các cấu hình ứng dụng. Các cấu hình bao gồm thông tin kết nối cơ sở dữ liệu, địa chỉ dịch vụ bên ngoài, cấp độ ghi log, thiết lập thời gian chờ, v.v. Cấu trình trung tâm tăng tính linh hoạt và khả năng bảo trì của ứng dụng.
Khi ứng dụng khởi động, nó có thể tự động lấy các cấu hình từ cấu trình trung tâm. Nếu cấu hình thay đổi, ứng dụng cũng sẽ tự động cập nhật mà không cần phải tái triển khai.
Ví Dụ Với Nacos
- Thông tin cấu trình thường được đặt trong file bootstrap.yml.
- Bootstrap Context chịu trách nhiệm tải cấu hình từ nguồn bên ngoài và phân tích.
- Thuộc tính Bootstrap có mức ưu tiên cao, chúng không bị ghi đè bởi cấu hình địa phương.
- Sau đó đọc cấu hình từ application.yml, tiến hành hợp nhất và hoàn thành khởi động dự án.
Các cấu hình quan trọng cần cập nhật động mới cần được quản lý bởi Nacos. Những cấu hình ít thay đổi hơn nên được lưu trữ địa phương trong microservice.
Chế Độ Pull
Nacos sử dụng chế độ Pull để lấy dữ liệu từ phía server, client sử dụng long polling để gửi yêu cầu Pull định kỳ kiểm tra sự thay đổi của cấu hình.
- Client gửi yêu cầu long polling, lắng nghe thay đổi của dataId+group.
- Server nhận yêu cầu từ client, tạm giữ yêu cầu đó.
- Nếu không có sự thay đổi trong 29.5s, server kích hoạt cơ chế kiểm tra tự động, trả về phản hồi cho client bất kể có thay đổi hay không.
- Nếu có thay đổi trong 29.5s, server kích hoạt cơ chế sự kiện, đẩy dữ liệu thay đổi đến client.
Nacos Như Một Đăng Ký Dịch Vụ
Một số dịch vụ đăng ký vào Nacos, trước khi gọi, client lấy thông tin từ Nacos, sau đó thực hiện cuộc gọi thực tế.
Dịch vụ 1 và dịch vụ 2 duy trì mối quan hệ tim-tic với Nacos mỗi 5 giây. Nếu Nacos không nhận được tim-tic trong 5 giây, dịch vụ đó sẽ bị đánh dấu offline. Nếu không nhận được tim-tic trong 15 giây, thuộc tính healthy của dịch vụ sẽ được đặt là false, client không thể gọi dịch vụ đó. Nếu không nhận được tim-tic trong 30 giây, dịch vụ sẽ bị loại bỏ khỏi danh sách.
Client có thể chủ động ngừng đăng ký.
Khi dịch vụ 1 gọi dịch vụ 2, nó sẽ lấy danh sách các dịch vụ trực tuyến từ Nacos thông qua công việc định kỳ, đảm bảo rằng dịch vụ được gọi luôn trực tuyến và khỏe mạnh.
Sau khi lấy được, client lưu trữ thông tin bằng bộ nhớ đệm và sử dụng cân bằng tải để gọi dịch vụ 2.
Các Chức Năng Của Cấu Trình Trung Tâm
- Quản Lý Cấu Hình: Hỗ trợ thêm, xuất bản, sửa đổi cấu hình, quản lý phiên bản, hỗ trợ phát hành nóng, phát hành xám, tách biệt môi trường, cung cấp API và giao diện người dùng.
- Quản Lý Quyền Truy Cập: Kiểm soát truy cập vào cấu hình, phân quyền đọc và ghi.
- Nhật Ký Hoạt Động: Ghi lại các hành động của người dùng.
- Theo Dõi Thay Đổi Cấu Hình: Theo dõi và xử lý các thay đổi cấu hình.
- Đẩy Cấu Hình: Sử dụng mô hình đăng ký/thông báo để đẩy cấu hình tới các dịch vụ tiêu thụ.
- Quản Lý Phiên Bản Lịch Sử: Lưu trữ tất cả các phiên bản cấu hình, hỗ trợ truy vấn và so sánh, dễ dàng quay lại bất kỳ phiên bản nào.
- Phát Triển Xám: Thực hiện phát hành cấu hình mới trong một số môi trường, quan sát trong một thời gian trước khi phát hành tới tất cả các môi trường.
- Theo Dõi Thay Đổi Cấu Hình: Ghi lại các thay đổi cấu hình, thuận tiện cho việc theo dõi và quản lý.
Cách Hoạt Động Cấu Trình Trung Tâm
Đăng Ký Cấu Hình
Quá trình đăng ký cấu hình thường bao gồm các bước:
- Dịch vụ cung cấp đăng ký thông tin cấu hình khi khởi động, bao gồm IP, cổng, thông tin kết nối cơ sở dữ liệu, v.v.
- Cấu trình trung tâm nhận và lưu trữ thông tin cấu hình.
- Dịch vụ tiêu thụ lấy thông tin cấu hình từ cấu trình trung tâm khi cần.
Ví dụ mã Java:
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import java.util.Properties;
import java.util.concurrent.Executor;
public class NacosConfigExample {
public static void main(String[] args) throws NacosException {
Properties properties = new Properties();
properties.put("serverAddr", "localhost:8848");
ConfigService configService = NacosFactory.createConfigService(properties);
String dataId = "example";
String group = "DEFAULT_GROUP";
String content = "useLocalCache=false";
configService.publishConfig(dataId, group, content);
String configInfo = configService.getConfig(dataId, group, 5000);
System.out.println(configInfo);
configService.addListener(dataId, group, new Listener() {
@Override
public Executor getExecutor() {
return null;
}
@Override
public void receiveConfigInfo(String configInfo) {
System.out.println("Received config: " + configInfo);
}
});
}
}
Hủy Đăng Ký Cấu Hình
Quá trình hủy đăng ký cấu hình bao gồm:
- Khởi tạo client Nacos.
- Gọi phương thức hủy đăng ký cấu hình.
Ví dụ mã Java:
configService.removeConfig(dataId, group);
Xem Cấu Hình
Quá trình xem cấu hình bao gồm:
- Khởi tạo client Nacos.
- Gọi phương thức lấy cấu hình.
Ví dụ mã Java:
String configInfo = configService.getConfig(dataId, group, 5000);
System.out.println(configInfo);
Theo Dõi Thay Đổi Cấu Hình
Quá trình theo dõi thay đổi cấu hình bao gồm:
- Khởi tạo client Nacos.
- Đăng ký lắng nghe thay đổi cấu hình.
Ví dụ mã Java:
configService.addListener(dataId, group, new Listener() {
@Override
public Executor getExecutor() {
return null;
}
@Override
public void receiveConfigInfo(String configInfo) {
System.out.println("Received config change: " + configInfo);
}
});