Hệ thống lưu trữ đám mây hiệu năng cao dựa trên Spring Boot

Đây là một hệ thống lưu trữ tệp trực tuyến được xây dựng bằng Spring Boot, tập trung vào khả năng mở rộng, bảo mật và trải nghiệm người dùng. Hệ thống hỗ trợ quản lý người dùng, tải lên/tải xuống tệp đa luồng, điều khiển phân quyền chi tiết, quản lý phiên bản tệp, mã hóa dữ liệu đầu cuối và tối ưu hóa hiệu năng thông qua bộ đệm phân tán và xử lý bất đồng bộ.

1. Tổng quan kiến trúc hệ thống

Hệ thống được thiết kế theo mô hình kiến trúc vi dịch vụ nhẹ, với các thành phần độc lập về triển khai và vận hành. Lớp giao diện người dùng sử dụng Thymeleaf để đảm bảo khả năng nhúng server-side đơn giản và an toàn, trong khi lớp nghiệp vụ được tách biệt rõ ràng thông qua các REST API chuẩn hóa. Cơ sở dữ liệu quan hệ MySQL lưu trữ metadata như cấu trúc thư mục, quyền truy cập và thông tin người dùng; Redis đảm nhiệm vai trò bộ đệm cho các truy vấn thường xuyên như danh sách thư mục hoặc trạng thái đăng nhập.

2. Triển khai Spring Boot với các tính năng cốt lõi

Ứng dụng tận dụng mạnh mẽ cơ chế tự cấu hình của Spring Boot để giảm thiểu cấu hình thủ công. Thay vì sử dụng @EnableAutoConfiguration một cách tường minh, hệ thống khai báo các starter phù hợp — ví dụ: spring-boot-starter-data-jpa cho truy vấn cơ sở dữ liệu, spring-boot-starter-security cho kiểm soát truy cập và spring-boot-starter-webflux để hỗ trợ xử lý I/O không chặn trong các tác vụ tải tệp lớn.

Dưới đây là một ví dụ về cấu hình bảo mật được tái cấu trúc để tăng tính linh hoạt và khả năng mở rộng:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {

    private final JwtAuthenticationFilter jwtAuthFilter;
    private final CustomUserDetailsService userDetailsService;

    public SecurityConfiguration(JwtAuthenticationFilter jwtAuthFilter,
                               CustomUserDetailsService userDetailsService) {
        this.jwtAuthFilter = jwtAuthFilter;
        this.userDetailsService = userDetailsService;
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
                .authorizeHttpRequests(authz -> authz
                    .requestMatchers("/api/auth/**").permitAll()
                    .requestMatchers("/api/public/**").permitAll()
                    .requestMatchers(HttpMethod.GET, "/api/files/**").hasAnyAuthority("READ", "ADMIN")
                    .requestMatchers(HttpMethod.POST, "/api/files/**").hasAnyAuthority("WRITE", "ADMIN")
                    .requestMatchers("/api/admin/**").hasRole("ADMIN")
                    .anyRequest().authenticated()
                )
            .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new Argon2PasswordEncoder(16, 32, 4, 1048576, 6);
    }
}

Chú ý rằng mã hóa mật khẩu đã được nâng cấp từ BCrypt sang Argon2 — thuật toán được NIST khuyến nghị do khả năng chống tấn công brute-force tốt hơn nhờ tiêu thụ bộ nhớ và thời gian tính toán có thể cấu hình.

3. Quản lý tệp thông minh với hỗ trợ tiếp tục tải

Cơ chế tải lên tệp lớn được thiết kế theo mô hình chia khối (chunked upload), kết hợp với bảng trạng thái tải lên trong cơ sở dữ liệu để theo dõi tiến độ và hỗ trợ tiếp tục từ điểm ngắt. Mỗi khối được gắn thẻ bằng uploadId, chunkIndexchecksum, cho phép xác thực tính toàn vẹn trước khi hợp nhất.

Mã xử lý phía máy chủ cho việc nhận khối tệp và kiểm tra trạng thái:

@RestController
@RequestMapping("/api/uploads")
public class ChunkUploadController {

    private final UploadProgressService progressService;
    private final FileStorageService storageService;

    public ChunkUploadController(UploadProgressService progressService,
                               FileStorageService storageService) {
        this.progressService = progressService;
        this.storageService = storageService;
    }

    @PostMapping("/{uploadId}/chunks/{index}")
    public ResponseEntity<UploadChunkResponse> handleChunk(
            @PathVariable String uploadId,
            @PathVariable Integer index,
            @RequestBody byte[] chunkData,
            @RequestHeader("X-Checksum") String expectedChecksum) {

        String actualChecksum = DigestUtils.md5Hex(chunkData);
        if (!actualChecksum.equals(expectedChecksum)) {
            return ResponseEntity.badRequest()
                    .body(new UploadChunkResponse(false, "Checksum không khớp"));
        }

        UploadStatus status = progressService.getOrCreate(uploadId);
        if (status.isChunkReceived(index)) {
            return ResponseEntity.ok(new UploadChunkResponse(true, "Khối đã tồn tại"));
        }

        storageService.saveChunk(uploadId, index, chunkData);
        status.markChunkReceived(index);
        progressService.update(uploadId, status);

        return ResponseEntity.ok(new UploadChunkResponse(true, "Nhận khối thành công"));
    }
}

Khi quá trình tải lên hoàn tất, một yêu cầu POST đến /api/uploads/{uploadId}/complete sẽ kích hoạt việc hợp nhất các khối và tạo bản ghi tệp hoàn chỉnh trong hệ thống.

4. Kiểm soát truy cập phân cấp và quản lý phiên bản

Hệ thống áp dụng mô hình RBAC (Role-Based Access Control) mở rộng với khả năng gán quyền theo đối tượng cụ thể (ABAC-style). Mỗi tệp hoặc thư mục có thể có danh sách người dùng/nhóm được cấp quyền đọc/ghi/xóa riêng biệt, ngoài quyền mặc định của chủ sở hữu.

Phiên bản tệp được lưu trữ dưới dạng các bản sao logic trong cơ sở dữ liệu — mỗi lần chỉnh sửa tạo ra một bản ghi mới trong bảng file_versions, chứa đường dẫn tới nội dung tệp, thời gian tạo và người thực hiện. Người dùng có thể xem lịch sử, khôi phục phiên bản cũ hoặc so sánh sự khác biệt giữa hai phiên bản thông qua API REST.

5. Tối ưu hóa hiệu năng và triển khai

Để cải thiện hiệu năng truy xuất tệp, hệ thống tích hợp cơ chế bộ đệm đa tầng:

  • Tầng 1: Bộ đệm Redis cho metadata (danh sách thư mục, thuộc tính tệp)
  • Tầng 2: Bộ đệm HTTP ở proxy ngược (Nginx) cho các tệp tĩnh đã được mã hóa
  • Tầng 3: Cache trên client thông qua header ETagCache-Control

Toàn bộ hệ thống được đóng gói bằng Docker với file docker-compose.yml riêng biệt cho từng môi trường (dev/staging/prod), bao gồm các service: ứng dụng Spring Boot, MySQL, Redis và Nginx làm reverse proxy. Quy trình CI/CD được tự động hóa bằng GitHub Actions, thực hiện build, test unit/integration và quét lỗ hổng bảo mật bằng Trivy trước mỗi lần triển khai.

Thẻ: spring-boot Redis mysql JWT docker

Đăng vào ngày 29 tháng 5 lúc 09:10