Cấu trúc Dự án Minh Họa
sentinel-integration/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── service/
│ │ │ ├── sentinel/
│ │ │ │ ├── FlowControlSetup.java
│ │ │ │ ├── CircuitBreakerSetup.java
│ │ │ │ └── SentinelExceptionHandler.java
│ │ │ ├── web/
│ │ │ │ └── ApiController.java
│ │ │ └── AppLauncher.java
│ │ └── resources/
│ │ └── application.yml
Triển Khai Chi Tiết
1. Lớp Khởi Tạo Ứng Dụng (AppLauncher.java)
@SpringBootApplication
public class AppLauncher {
public static void main(String[] args) {
SpringApplication.run(AppLauncher.class, args);
}
}
2. Thiết Lập Quy Tắc Giới Hạn Lưu Lượng (FlowControlSetup.java)
@Configuration
public class FlowControlSetup implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
List<FlowRule> flowRules = new ArrayList<>();
// Quy tắc cơ bản: giới hạn QPS cho API đơn giản
FlowRule basicRule = new FlowRule();
basicRule.setResource("apiSimpleCall");
basicRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
basicRule.setCount(3); // Chỉ cho phép 3 yêu cầu mỗi giây
basicRule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER);
// Quy tắc theo tham số: giới hạn tần suất theo userId
FlowRule paramRule = new FlowRule();
paramRule.setResource("apiUserSpecific");
paramRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
paramRule.setCount(1); // Mỗi người dùng chỉ được gọi 1 lần/giây
paramRule.setParamIdx(0); // Áp dụng cho tham số đầu tiên
flowRules.add(basicRule);
flowRules.add(paramRule);
FlowRuleManager.loadRules(flowRules);
}
}
3. Cấu Hình Ngắt Mạch (CircuitBreakerSetup.java)
@Configuration
public class CircuitBreakerSetup implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
List<DegradeRule> degradeRules = new ArrayList<>();
DegradeRule rule = new DegradeRule();
rule.setResource("unstableServiceCall");
rule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);
rule.setCount(4); // Ngắt mạch nếu có 4 ngoại lệ
rule.setTimeWindow(15); // Thời gian chờ phục hồi: 15 giây
degradeRules.add(rule);
DegradeRuleManager.loadRules(degradeRules);
}
}
4. Bộ Xử Lý API (ApiController.java)
@RestController
@RequestMapping("/api")
public class ApiController {
private final Random faultInjector = new Random();
// Gọi dịch vụ ổn định - bị giới hạn QPS
@GetMapping("/simple")
@SentinelResource(
value = "apiSimpleCall",
blockHandler = "onRequestBlocked"
)
public String simpleEndpoint() {
return "Thành công: Yêu cầu được xử lý";
}
// Gọi cá nhân hóa - giới hạn theo người dùng
@GetMapping("/user/{id}")
@SentinelResource(
value = "apiUserSpecific",
blockHandler = "onUserRateLimited"
)
public String userEndpoint(@PathVariable Long id) {
return "Xin chào người dùng " + id;
}
// Dịch vụ không ổn định - có thể kích hoạt ngắt mạch
@GetMapping("/faulty")
@SentinelResource(
value = "unstableServiceCall",
blockHandler = "onCircuitOpen",
fallback = "serviceFallback"
)
public String faultyEndpoint() {
if (faultInjector.nextDouble() < 0.7) {
throw new IllegalStateException("Lỗi dịch vụ tạm thời");
}
return "Dịch vụ hoạt động bình thường";
}
// Xử lý khi bị chặn do vượt giới hạn
public String onRequestBlocked(BlockException ex) {
return "❌ Đã đạt ngưỡng giới hạn lưu lượng. Vui lòng thử lại sau.";
}
// Xử lý khi người dùng cụ thể bị giới hạn
public String onUserRateLimited(Long id, BlockException ex) {
return "⏳ Người dùng " + id + " đang bị tạm dừng do quá tải.";
}
// Xử lý khi mạch bị ngắt
public String onCircuitOpen(BlockException ex) {
return "🔌 Dịch vụ đang tạm ngừng để bảo trì.";
}
// Fallback khi có lỗi nghiệp vụ
public String serviceFallback(Throwable t) {
return "🔄 Đang sử dụng chế độ dự phòng: " + t.getMessage();
}
}
Giải Thích Cơ Chế Hoạt Động
Tài Nguyên và Gắn Nhãn
Annotation @SentinelResource đánh dấu một đoạn mã cần được bảo vệ. Giá trị value là định danh duy nhất dùng để áp dụng quy tắc.
Phân Biệt Xử Lý Lỗi
- BlockHandler: Xử lý các trường hợp bị từ chối bởi Sentinel (vượt QPS, ngắt mạch...). Nhận tham số bổ sung là
BlockException. - Fallback: Xử lý lỗi phát sinh trong logic nghiệp vụ (ngoại lệ thông thường). Nhận tham số
Throwable.
Kiểm Thử Thực Tế
- Thử nghiệm giới hạn QPS: Gọi nhanh
/api/simplehơn 3 lần/giây → nhận phản hồi chặn. - Thử nghiệm theo người dùng: Gọi
/api/user/123liên tục → bị chặn sau lần thứ hai. - Thử nghiệm ngắt mạch: Gọi
/api/faultykhoảng 6-8 lần → mạch sẽ ngắt trong 15 giây.
Nguyên Tắc Triển Khai Tốt Nhất
- Đặt tên tài nguyên rõ ràng: Dùng định dạng mô tả như
serviceName#operation. - Không xử lý nặng trong handler: BlockHandler và Fallback nên trả về kết quả nhanh, tránh I/O hay tính toán phức tạp.
- Dùng Console để cấu hình động: Trên môi trường production, nên dùng Sentinel Dashboard thay vì hard-code rule.
- Giám sát và cảnh báo: Tích hợp với hệ thống metrics (Prometheus, Grafana) để theo dõi trạng thái tài nguyên.
- Phân tầng bảo vệ: Áp dụng cả giới hạn lưu lượng và ngắt mạch cho các dịch vụ quan trọng.