Time Limit pattern

Time Limit pattern
Time Limit Pattern là một kỹ thuật đặt giới hạn thời gian chờ xử lý (timeout) cho các yêu cầu (request) hoặc xử lý trong hệ thống, nhằm tránh treo ứng dụng hoặc làm chậm toàn bộ hệ thống do một service phản hồi chậm.
Mục đích chính:
Bảo vệ tài nguyên: Ngăn chặn service bị quá tải do chờ response quá lâu.
Tăng tốc độ phản hồi: Nếu một request bị treo quá lâu, hệ thống có thể hủy request và xử lý fallback.
Cải thiện trải nghiệm người dùng: Hạn chế tình trạng ứng dụng phản hồi chậm.
Ví dụ:
API thanh toán chỉ cho phép chờ tối đa 3 giây. Nếu quá thời gian này, hệ thống sẽ hủy yêu cầu và trả về lỗi timeout.
Một truy vấn database mất hơn 5 giây sẽ bị hủy để tránh làm chậm các truy vấn khác.
Cơ chế hoạt động
Time Limit hoạt động bằng cách đặt giới hạn thời gian (timeout) cho một quá trình xử lý. Nếu quá thời gian đó mà chưa có phản hồi, hệ thống sẽ hủy yêu cầu và thực hiện fallback hoặc retry.
Các loại Time Limit trong hệ thống
Request Timeout – Giới hạn thời gian phản hồi của API.
Database Query Timeout – Giới hạn thời gian thực thi truy vấn database.
Thread Execution Timeout – Giới hạn thời gian chạy của một luồng.
Asynchronous Task Timeout – Giới hạn thời gian chạy của các tác vụ nền.
Trường hợp sử dụng
API Gateway Timeout: Khi một API gọi service khác, cần đặt timeout để không bị treo nếu service backend chậm.
Query Database Timeout: Hạn chế thời gian truy vấn để tránh query phức tạp làm quá tải hệ thống.
External API Call Timeout: Khi gọi API bên thứ ba, cần đặt timeout để tránh treo nếu API chậm hoặc lỗi.
Worker Task Timeout: Nếu một công việc chạy quá lâu, cần hủy để giải phóng tài nguyên.
Cách triển khai
1. Cấu hình Timeout trong API Gateway
Ví dụ cấu hình Timeout với Kong API Gateway:
services:
- name: my-service
url: http://backend-service
connect_timeout: 3000 # 3 giây
read_timeout: 5000 # 5 giây
write_timeout: 5000 # 5 giây
Nếu service phản hồi chậm hơn 3 giây, API Gateway sẽ tự động hủy request.
2. Đặt Timeout trong Spring Boot (RestTemplate, WebClient, Feign Client)
Ví dụ cấu hình Timeout với RestTemplate
@Bean
public RestTemplate restTemplate() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(3000); // 3 giây
factory.setReadTimeout(5000); // 5 giây
return new RestTemplate(factory);
}
Nếu API backend phản hồi chậm hơn 3 giây, request sẽ bị hủy.
Ví dụ cấu hình Timeout với WebClient
WebClient webClient = WebClient.builder()
.baseUrl("http://backend-service")
.clientConnector(new ReactorClientHttpConnector(
HttpClient.create().responseTimeout(Duration.ofSeconds(3))
))
.build();
Ví dụ cấu hình Timeout với Feign Client
@FeignClient(name = "backend-service", url = "http://backend-service", configuration = FeignConfig.class)
public interface BackendClient {
@GetMapping("/data")
String getData();
}
@Configuration
public class FeignConfig {
@Bean
public Request.Options options() {
return new Request.Options(3000, 5000); // 3s connect, 5s read
}
}
Nếu gọi API mất quá 3 giây để kết nối hoặc quá 5 giây để đọc dữ liệu, request sẽ bị hủy.
3. Timeout trong Database (PostgreSQL, MySQL, MongoDB)
Ví dụ cấu hình Query Timeout trong PostgreSQL
SET statement_timeout = 5000; -- 5 giây
SELECT * FROM large_table;
Nếu query mất hơn 5 giây, nó sẽ bị hủy
Ví dụ cấu hình Timeout trong Spring Boot (JPA)
spring.datasource.hikari.connection-timeout=3000
spring.datasource.hikari.validation-timeout=5000
Nếu kết nối database mất hơn 3 giây hoặc query lâu hơn 5 giây, nó sẽ bị hủy.
4. Timeout trong Circuit Breaker (Resilience4j)
@Bean
public TimeLimiterConfig timeLimiterConfig() {
return TimeLimiterConfig.custom()
.timeoutDuration(Duration.ofSeconds(3)) // 3 giây timeout
.build();
}
Nếu một service mất hơn 3 giây để phản hồi, Circuit Breaker sẽ hủy request.
5. Timeout trong Asynchronous Tasks (ExecutorService, CompletableFuture)
Timeout với ExecutorService
ExecutorService executor = Executors.newFixedThreadPool(10);
Future<String> future = executor.submit(() -> callSlowService());
try {
String result = future.get(3, TimeUnit.SECONDS); // Timeout sau 3 giây
} catch (TimeoutException e) {
System.out.println("Request timeout!");
}
Nếu service phản hồi chậm hơn 3 giây, request sẽ bị hủy.
Timeout với CompletableFuture
CompletableFuture.supplyAsync(() -> callSlowService())
.orTimeout(3, TimeUnit.SECONDS)
.exceptionally(ex -> "Fallback response");
Nếu service mất hơn 3 giây, nó sẽ trả về fallback.
Subscribe to my newsletter
Read articles from Dương Tiến directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
