+3

Giải quyết bài toán giao dịch phân tán trong Microservices với Saga Pattern

Microservices đã mang đến một cuộc cách mạng trong việc xây dựng hệ thống linh hoạt và có khả năng mở rộng. Tuy nhiên, kiến trúc này cũng đặt ra những thách thức trong việc quản lý các giao dịch phân tán giữa các dịch vụ, và Saga Pattern chính là giải pháp hữu hiệu.

Bạn có thể xem thêm: Microservices with kubernetes là gì và mối liên kết giữa chúng

Mô hình Saga là gì?

Saga Pattern hoạt động bằng cách chia nhỏ một giao dịch lớn, phân tán thành một chuỗi các bước nhỏ hơn. Mỗi bước được xử lý bởi một microservice cụ thể và được thực hiện theo trình tự. Điểm đặc biệt của Saga Pattern là việc xác định các hành động bù trừ cho mỗi bước, cho phép khôi phục hệ thống về trạng thái trước đó nếu xảy ra lỗi.

Hai phương pháp chính để triển khai Saga Pattern bao gồm Choreography, nơi mỗi dịch vụ lắng nghe và phản ứng với các sự kiện, và Orchestration, sử dụng một dịch vụ điều phối trung tâm để quản lý luồng giao dịch.

Trường hợp nào nên sử dụng mô hình Saga?

Saga Pattern đặc biệt hữu ích trong các kiến trúc microservices, nơi giao dịch trải dài trên nhiều dịch vụ, khả năng mở rộng và tính tách rời là rất quan trọng. Việc xử lý các lỗi cục bộ một cách trơn tru cũng là một yếu tố then chốt. Ví dụ về quy trình onboarding nhân viên mới trong hệ thống nhân sự minh họa rõ nét lợi ích của Saga Pattern.

Quá trình này thường liên quan đến nhiều microservices như Dịch vụ Người dùng (tạo tài khoản nhân viên), Dịch vụ Lương (thiết lập chi tiết lương) và Dịch vụ Phúc lợi (đăng ký phúc lợi cho nhân viên). Nếu Dịch vụ Lương gặp sự cố, hệ thống cần phải hoàn tác việc tạo tài khoản và đăng ký phúc lợi.

Triển khai mẫu Saga trong C#

Để triển khai Saga Pattern với phương pháp Orchestration trong C# cho quy trình onboarding, chúng ta cần một Saga Coordinator. Đây là thành phần quản lý luồng giao dịch. Tiếp theo, mỗi dịch vụ (User Service, Payroll Service, Benefits Service) cần được triển khai với logic riêng và các hành động bù trừ tương ứng. Cuối cùng, Saga Coordinator sẽ được sử dụng để thực thi toàn bộ quy trình onboarding.

Bước 1: Xác định Saga Coordinator

Saga Coordinator quản lý luồng giao dịch. Sau đây là một triển khai cơ bản trong C#:

public class SagaCoordinator
{
    private readonly IUserService _userService;
    private readonly IPayrollService _payrollService;
    private readonly IBenefitsService _benefitsService;

    public SagaCoordinator(IUserService userService, IPayrollService payrollService, IBenefitsService benefitsService)
    {
        _userService = userService;
        _payrollService = payrollService;
        _benefitsService = benefitsService;
    }

    public async Task ExecuteOnboardingSagaAsync(Employee employee)
    {
        try
        {
            Console.WriteLine("Starting onboarding saga...");

            // Step 1: Create user account
            await _userService.CreateUserAsync(employee);

            // Step 2: Set up payroll
            await _payrollService.SetupPayrollAsync(employee);

            // Step 3: Register benefits
            await _benefitsService.RegisterBenefitsAsync(employee);

            Console.WriteLine("Onboarding completed successfully!");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error during onboarding: {ex.Message}");
            await CompensateAsync(employee);
        }
    }

    private async Task CompensateAsync(Employee employee)
    {
        Console.WriteLine("Compensating...");
        await _benefitsService.RollbackBenefitsAsync(employee);
        await _payrollService.RollbackPayrollAsync(employee);
        await _userService.DeleteUserAsync(employee);
        Console.WriteLine("Compensation complete.");
    }
}

Bước 2: Xác định dịch vụ

Mỗi dịch vụ đều triển khai logic và hành động bù trừ cụ thể của nó.

public interface IUserService
{
    Task CreateUserAsync(Employee employee);
    Task DeleteUserAsync(Employee employee);
}

public interface IPayrollService
{
    Task SetupPayrollAsync(Employee employee);
    Task RollbackPayrollAsync(Employee employee);
}

public interface IBenefitsService
{
    Task RegisterBenefitsAsync(Employee employee);
    Task RollbackBenefitsAsync(Employee employee);
}

Bước 3: Thực hiện Saga

Sau đây là cách bạn có thể sử dụng Saga Coordinator:

var sagaCoordinator = new SagaCoordinator(userService, payrollService, benefitsService);
await sagaCoordinator.ExecuteOnboardingSagaAsync(new Employee { Name = "John Doe" });

Ưu điểm của Saga Pattern nằm ở khả năng phục hồi từ các lỗi trong quy trình dài, khả năng mở rộng bằng cách tách rời các dịch vụ trong khi vẫn duy trì tính toàn vẹn giao dịch và tính linh hoạt trong việc hỗ trợ các quy trình làm việc đa dạng.

Tóm lại, Saga Pattern là một mô hình thiết kế quan trọng để duy trì tính nhất quán dữ liệu trong các hệ thống phân tán như microservices. Nó đảm bảo toàn bộ quy trình onboarding hoặc hoàn thành thành công hoặc được khôi phục một cách an toàn, giữ vững tính toàn vẹn của hệ thống.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí