Đây là một câu hỏi kinh điển tôi đã được hỏi trong một cuộc phỏng vấn gần đây Làm thế nào để gọi nhiều dịch vụ web và vẫn bảo tồn một số loại xử lý lỗi ở giữa nhiệm vụ. Ngày nay, trong điện toán hiệu năng cao, chúng tôi tránh hai lần cam kết. Tôi đã đọc một bài báo cách đây nhiều năm về cái được gọi là "mô hình Starbuck" cho các giao dịch: Nghĩ về quá trình đặt hàng, thanh toán, chuẩn bị và nhận cà phê bạn đặt hàng tại Starbuck ... Tôi mô tả quá mức mọi thứ nhưng mô hình cam kết hai giai đoạn sẽ đề nghị rằng toàn bộ quá trình sẽ là một giao dịch gói duy nhất cho tất cả các bước liên quan cho đến khi bạn nhận được cà phê của mình. Tuy nhiên, với mô hình này, tất cả nhân viên sẽ chờ đợi và ngừng làm việc cho đến khi bạn nhận được cà phê của mình. Bạn thấy bức tranh?
Thay vào đó, "mô hình Starbuck" có năng suất cao hơn bằng cách làm theo mô hình "nỗ lực tốt nhất" và bù đắp cho các lỗi trong quy trình. Đầu tiên, họ chắc chắn rằng bạn trả tiền! Sau đó, có hàng đợi tin nhắn với đơn đặt hàng của bạn được gắn vào cốc. Nếu có sự cố xảy ra trong quy trình, như bạn không nhận được cà phê của mình, đó không phải là những gì bạn đã đặt hàng, v.v., chúng tôi tham gia vào quy trình bồi thường và chúng tôi đảm bảo bạn có được những gì bạn muốn hoặc hoàn lại tiền cho bạn, Đây là mô hình hiệu quả nhất để tăng năng suất.
Đôi khi, starbuck đang lãng phí một ly cà phê nhưng quá trình tổng thể là hiệu quả. Có những thủ thuật khác để suy nghĩ khi bạn xây dựng các dịch vụ web của mình như thiết kế chúng theo cách mà chúng có thể được gọi bất kỳ số lần nào và vẫn cung cấp kết quả cuối cùng. Vì vậy, đề nghị của tôi là:
Đừng quá ổn khi xác định các dịch vụ web của bạn (Tôi không tin về sự cường điệu của dịch vụ vi mô xảy ra trong những ngày này: quá nhiều rủi ro khi đi quá xa);
Async tăng hiệu suất vì vậy thích không đồng bộ, gửi thông báo qua email bất cứ khi nào có thể.
Xây dựng các dịch vụ thông minh hơn để làm cho chúng "có thể nhớ lại" bất kỳ số lần nào, xử lý bằng uid hoặc taskid sẽ theo thứ tự từ dưới lên trên cho đến khi kết thúc, xác thực các quy tắc kinh doanh trong mỗi bước;
Sử dụng hàng đợi tin nhắn (JMS hoặc các loại khác) và chuyển hướng đến bộ xử lý xử lý lỗi sẽ áp dụng các hoạt động cho "rollback" bằng cách áp dụng các hoạt động ngược lại, bằng cách đó, làm việc với thứ tự async sẽ yêu cầu một số loại hàng đợi để xác thực trạng thái hiện tại của quy trình, vì vậy hãy xem xét điều đó;
Trong phương sách cuối cùng, (vì nó có thể không xảy ra thường xuyên), hãy đặt nó vào hàng đợi để xử lý lỗi thủ công.
Hãy quay trở lại với vấn đề ban đầu đã được đăng. Tạo một tài khoản và tạo ví và đảm bảo mọi thứ đã được thực hiện.
Giả sử một dịch vụ web được gọi để điều phối toàn bộ hoạt động.
Mã giả của dịch vụ web sẽ như thế này:
Gọi microservice tạo tài khoản, truyền cho nó một số thông tin và một số tác vụ duy nhất 1.1 Dịch vụ micros micros tạo tài khoản trước tiên sẽ kiểm tra xem tài khoản đó đã được tạo chưa. Một id nhiệm vụ được liên kết với hồ sơ của tài khoản. Microservice phát hiện ra rằng tài khoản không tồn tại nên nó tạo ra nó và lưu trữ id nhiệm vụ. LƯU Ý: dịch vụ này có thể được gọi 2000 lần, nó sẽ luôn thực hiện cùng một kết quả. Dịch vụ trả lời với "biên nhận chứa thông tin tối thiểu để thực hiện thao tác hoàn tác nếu được yêu cầu".
Tạo Ví gọi, cung cấp cho nó ID tài khoản và id tác vụ. Giả sử một điều kiện không hợp lệ và việc tạo ví không thể được thực hiện. Cuộc gọi trở lại với một lỗi nhưng không có gì được tạo ra.
Dàn nhạc được thông báo về lỗi. Nó biết rằng nó cần phải hủy bỏ việc tạo Tài khoản nhưng nó sẽ không tự làm được. Nó sẽ yêu cầu dịch vụ ví thực hiện bằng cách chuyển "biên nhận hoàn tác tối thiểu" nhận được ở cuối bước 1.
Dịch vụ Tài khoản đọc biên lai hoàn tác và biết cách hoàn tác thao tác; biên lai hoàn tác thậm chí có thể bao gồm thông tin về một dịch vụ siêu nhỏ khác mà nó có thể tự gọi mình để thực hiện một phần công việc. Trong tình huống này, biên lai hoàn tác có thể chứa ID tài khoản và có thể một số thông tin bổ sung cần thiết để thực hiện thao tác ngược lại. Trong trường hợp của chúng tôi, để đơn giản hóa mọi thứ, giả sử chỉ cần xóa tài khoản bằng id tài khoản.
Bây giờ, giả sử dịch vụ web không bao giờ nhận được thành công hay thất bại (trong trường hợp này) rằng việc hoàn tác tạo tài khoản đã được thực hiện. Nó chỉ đơn giản sẽ gọi lại dịch vụ hoàn tác của Tài khoản. Và dịch vụ này nên không bao giờ thất bại vì mục tiêu của nó là tài khoản không còn tồn tại. Vì vậy, nó kiểm tra nếu nó tồn tại và thấy không có gì có thể được thực hiện để hoàn tác nó. Vì vậy, nó trả về rằng hoạt động là một thành công.
Dịch vụ web trả về cho người dùng rằng tài khoản không thể được tạo.
Đây là một ví dụ đồng bộ. Chúng tôi có thể quản lý nó theo một cách khác và đưa vụ việc vào hàng đợi tin nhắn được nhắm mục tiêu đến bàn trợ giúp nếu chúng tôi không muốn hệ thống khắc phục hoàn toàn lỗi ". Tôi đã thấy điều này được thực hiện trong một công ty không đủ móc có thể được cung cấp cho hệ thống đầu cuối để khắc phục tình huống. Bàn trợ giúp nhận được tin nhắn có chứa những gì được thực hiện thành công và có đủ thông tin để sửa những thứ giống như nhận được hoàn tác của chúng tôi theo cách hoàn toàn tự động.
Tôi đã thực hiện tìm kiếm và trang web microsoft có mô tả mẫu cho phương pháp này. Nó được gọi là mẫu giao dịch bù:
Bồi thường mô hình giao dịch