8 phút

Khôi phục tự động cho tác động phụ của tác nhân

Khôi phục tự động cho tác động phụ của tác nhân không thể hoàn tác mọi hành động bên ngoài. Tìm hiểu khi nào ảnh chụp nhanh dừng lại và phê duyệt hoặc bù trừ cần bắt đầu.

Khôi phục tự động cho tác động phụ của tác nhân

Khôi phục tác nhân có thể đưa mã, cấu hình hoặc một phần dữ liệu ứng dụng về lại trạng thái cũ. Nó không thể khiến một tổ chức khác quên yêu cầu, lấy lại email đã được gửi khỏi hộp thư hay giả vờ rằng khoản thu thẻ chưa từng đến bộ xử lý thanh toán. Những đội gọi tất cả các thao tác đó là «khôi phục» đang xây dựng một cơ chế kiểm soát dễ tạo cảm giác an tâm nhưng lại thất bại đúng lúc hậu quả trở nên quan trọng.

Thiết kế an toàn tách bốn cơ chế: ảnh chụp nhanh ứng dụng, Git revert, khôi phục cơ sở dữ liệu và hành động bù trừ. Mỗi cơ chế chịu trách nhiệm cho một ranh giới khác nhau. Mọi hành động vượt ra ngoài ranh giới ứng dụng cần có phê duyệt, bằng chứng, quy tắc thử lại và đường khôi phục riêng trước khi tác nhân thực hiện. Nếu không ai có thể nói đường đó trong một câu, hành động chưa sẵn sàng để chạy không giám sát.

Khôi phục có bốn nghĩa riêng biệt

Khôi phục chỉ hữu ích khi đội ngũ nêu rõ trạng thái nào sẽ được đưa về và trạng thái nào không thể chạm tới. Từ này thường che giấu bốn cơ chế có mức đảm bảo rất khác nhau.

Ảnh chụp nhanh khôi phục một phiên bản đã được lưu của ứng dụng hoặc không gian làm việc. Tùy sản phẩm, ảnh đó có thể gồm mã được tạo, cấu hình và một phần trạng thái được quản lý. Nó không nói gì về dịch vụ bên ngoài trừ khi hợp đồng ảnh chụp nhanh ghi rõ có bao gồm chúng.

Git revert ghi một commit mới, trong đó các thay đổi đảo ngược commit trước. Nó sửa lịch sử mã nguồn mà không xóa lịch sử đó. Nó không liên hệ với những dịch vụ mà mã cũ đã gọi trong lúc chạy.

Khôi phục cơ sở dữ liệu thay đổi các bản ghi do cơ sở dữ liệu lưu giữ. Rollback giao dịch loại bỏ các lượt ghi chưa commit trong một giao dịch. Phục hồi bản sao lưu hoặc dùng khôi phục theo thời điểm là thao tác lớn hơn nhiều, đưa cụm cơ sở dữ liệu về gần trạng thái cũ hơn. Cả hai đều không tự động đối soát những hệ thống bên ngoài cơ sở dữ liệu đó.

Hành động bù trừ tạo một tác động mới nhằm bù đắp tác động cũ. Hoàn tiền bù cho khoản thanh toán đã thu. Yêu cầu hủy bù cho đơn hàng. Email đính chính có thể giảm tác hại của email gửi nhầm, nhưng không thể xóa thư đầu tiên. Bù trừ giữ lại sự thật khó chịu rằng hành động gốc đã xảy ra.

Tôi dùng bảng phân định quyền sở hữu tác động trong các buổi đánh giá thiết kế vì nó buộc mọi người trả lời chính xác:

Thay đổiBên chịu trách nhiệm khôi phụcCơ chế thường dùngCó thể xóa tác động gốc không?
Mã nguồn được tạoỨng dụng hoặc kho mãKhôi phục ảnh chụp nhanh hoặc Git revertThường có, với các lần chạy sau này
Hàng đã commitNgười vận hành cơ sở dữ liệuSửa logic hoặc khôi phụcĐôi khi, ở cục bộ
Email đã gửiNhà cung cấp thư và người nhậnGửi tiếp hoặc chặn thư đang chờKhông
Khoản thanh toán đã thuBộ xử lý thanh toánHủy hoặc hoàn tiềnKhông
Yêu cầu API bên ngoàiDịch vụ nhậnHủy hoặc bù trừ riêng theo nhà cung cấpThường không

Cột cuối cùng quan trọng nhất. Thao tác ngược không chứng minh rằng thao tác gốc đã biến mất. Bản ghi kiểm toán, bản sao của người nhận, mục quyết toán, webhook và công việc thực tế vẫn có thể tồn tại.

Hoàn tác mã thay đổi chương trình, không thay đổi quá khứ

Hoàn tác mã ngăn hoặc thay đổi hành vi về sau, nó không đảo ngược hành vi mà phiên bản cũ đã gây ra. Điều này vẫn đúng dù đội dùng Git, ảnh chụp nhanh của nền tảng hay rollback triển khai.

Tài liệu Git mô tả git revert là ghi các commit đảo ngược thay đổi do những commit trước tạo ra. Cách diễn đạt đó rất chính xác: Git áp dụng bản vá ngược vào nội dung kho mã. Git không biết gì về email, thanh toán, tài nguyên đám mây, phiếu hỗ trợ hay API của đối tác được tạo ra khi commit bị hoàn tác còn chạy.

Giả sử một tác nhân sửa hàm lập hóa đơn, triển khai nó và gọi hàm hai lần trước khi giám sát phát hiện lỗi. Hoàn tác commit có thể ngăn hàm lỗi chạy thêm. Hai lần thử thanh toán vẫn còn tại bộ xử lý. Nếu cơ sở dữ liệu cục bộ chỉ ghi một lần thử, việc hoàn tác còn có thể khiến điều tra khó hơn vì nó xóa đường mã hiểu phản hồi thứ hai.

Rollback triển khai có cùng ranh giới. Chuyển lưu lượng trở về bản dựng trước sẽ khôi phục hành vi có thể chạy. Những yêu cầu mà bản dựng bị thay thế đã nhận vẫn giữ hậu quả của chúng. Tác vụ trong hàng đợi cũng có thể sống sót qua lần triển khai và chạy các giả định cũ trên phiên bản đã khôi phục.

Trước khi hoàn tác, hãy giữ lại bằng chứng vận hành do bản dựng cũ tạo ra:

  • Mã định danh triển khai và commit nguồn
  • Mã định danh lần chạy và ý định của tác nhân
  • Mã định danh thông điệp hàng đợi và trạng thái lease
  • Mã định danh yêu cầu bên ngoài
  • Phản hồi và dấu thời gian của nhà cung cấp

Sau đó dừng thực thi mới, đối soát thao tác chưa hoàn tất rồi mới khôi phục mã. Hoàn tác trước rồi mới đặt câu hỏi thường phá hủy cách dễ nhất để hiểu tác động nào đã thoát ra ngoài.

Ảnh chụp nhanh có thể rộng hơn một commit Git, nhưng quy tắc vẫn vậy. Hợp đồng ảnh chụp nhanh phải nói chính xác tài nguyên nào nó chứa. Nếu nó chứa mã và cấu hình, hãy gọi đó là cơ chế khôi phục mã và cấu hình. Đừng biến nó thành hoàn tác vạn năng bằng câu chữ đầy hy vọng trên giao diện.

Khôi phục cơ sở dữ liệu hẹp hơn mọi người thường nghĩ

Khôi phục cơ sở dữ liệu đưa trạng thái cơ sở dữ liệu trở lại, không khôi phục thực tế kinh doanh trên mọi bên tham gia giao dịch. Một giao dịch có thể nguyên tử trong một cơ sở dữ liệu, trong khi thao tác xung quanh vẫn bị chia tách giữa nhiều hệ thống.

Hãy xét chuỗi sau:

  1. Tác nhân chèn một hàng hóa đơn.
  2. Nó gọi API thanh toán.
  3. Bộ xử lý chấp nhận khoản thu.
  4. Commit cơ sở dữ liệu thất bại.

Rollback cục bộ xóa hàng hóa đơn. Khoản thu vẫn tồn tại. Thử lại toàn bộ thao tác mà không đối soát có thể thu tiền khách hàng lần nữa. Đây là lỗi ghi kép kinh điển: ứng dụng cố biến một hành động kinh doanh thành nguyên tử trên các hệ thống không dùng chung điều phối viên giao dịch.

Đảo thứ tự cũng không giải quyết được. Nếu ứng dụng commit hóa đơn trước rồi lệnh gọi thanh toán thất bại, cơ sở dữ liệu sẽ có hóa đơn chưa thanh toán. Trạng thái đó dễ kiểm tra hơn, nhưng ứng dụng vẫn cần máy trạng thái phân biệt payment_pending, payment_confirmed, payment_failedpayment_unknown.

Tài liệu PostgreSQL giải thích khôi phục theo thời điểm là phục hồi bản sao lưu gốc và phát lại các bản ghi write ahead log đến mục tiêu khôi phục đã chọn. Đây là thủ tục của người vận hành để khôi phục một cụm cơ sở dữ liệu. Nó không phải hoàn tác có chọn lọc cho một lần chạy tác nhân và không thể yêu cầu bộ xử lý thanh toán hoặc dịch vụ thư quay về cùng thời điểm.

Đưa cơ sở dữ liệu lùi lại có thể tạo ra một sai lệch thứ hai. Hãy tưởng tượng khôi phục về 10:00 sau sự cố. Nhà cung cấp đã nhận yêu cầu đến 10:07, nhưng cơ sở dữ liệu được khôi phục không còn bản ghi của chúng. Các tác nhân thấy hàng «thiếu» có thể tạo lại toàn bộ bảy phút công việc. Vì thế, khôi phục cần một giai đoạn đối soát bên ngoài trước khi worker chạy lại.

Mẫu outbox giảm một khoảng trống nguy hiểm. Ứng dụng commit thay đổi nghiệp vụ và ý định tạo tác động trong cùng giao dịch cục bộ:

BEGIN;

INSERT INTO invoices (invoice_id, customer_id, status)
VALUES ('inv_2048', 'cust_91', 'payment_pending');

INSERT INTO effect_intents
  (intent_id, operation, subject_id, status)
VALUES
  ('eff_7f31', 'capture_payment', 'inv_2048', 'pending');

COMMIT;

Worker sau đó nhận eff_7f31, gọi nhà cung cấp với giá trị idempotency ổn định và ghi kết quả. Outbox không làm lệnh gọi bên ngoài trở thành nguyên tử. Nó cung cấp bằng chứng bền vững rằng công việc đã được dự định, nhờ đó có thể thử lại và đối soát.

Hành động bên ngoài cần bù trừ, và đôi khi không có cách nào

Một tác động bên ngoài cần có phương án bù trừ riêng theo nhà cung cấp hoặc tuyên bố rõ rằng không có bù trừ nào thực sự có ý nghĩa. Xem mọi hành động là có thể đảo ngược còn tệ hơn thừa nhận rằng một số hành động cần phê duyệt.

Email là ví dụ đơn giản nhất. Trước khi nhà cung cấp nhận thư, ứng dụng có thể hủy tác vụ trong hàng đợi. Sau khi nhận, nhà cung cấp có thể cho phép hủy trong một giai đoạn nội bộ ngắn, nhưng không có bảo đảm thu hồi chung giữa các người nhận và hệ thống thư. Khi đã gửi, thư thứ hai có thể đính chính hồ sơ chứ không xóa thư đầu. Dữ liệu nhạy cảm, thông báo pháp lý và tổn hại danh tiếng vẫn bị lộ.

Thanh toán có nhiều trạng thái mà các đội thường gộp thành «đã thu tiền». Ủy quyền giữ lại khả năng chi tiêu. Thu tiền yêu cầu chuyển tiền dựa trên ủy quyền đó. Hủy có thể giải phóng ủy quyền chưa quyết toán. Hoàn tiền tạo một mục tài chính sau đó để trả lại tiền sau khi đã thu. Những thao tác này khác nhau về thời gian, phí, quyền hạn và tác động tới khách hàng. Công cụ undo_payment chung chung che giấu thông tin tác nhân cần để hành động an toàn.

Các API khác còn ít hỗ trợ hơn. Một yêu cầu có thể đặt hàng tồn kho, cấp hạ tầng, xuất bản nội dung, cấp quyền truy cập, gửi kiện hàng hoặc khiến một người bắt đầu công việc. Điểm cuối DELETE không chứng minh tính đảo ngược. Xóa tài nguyên có thể vẫn để lại nhật ký kiểm toán, dữ liệu sao chép, thông báo, tài nguyên phụ thuộc hoặc hậu quả thực tế.

Hãy phân loại bù trừ theo điều nó thực sự đạt được:

  • Thao tác ngược chính xác ở cục bộ đưa trạng thái được kiểm soát về giá trị trước đó.
  • Hủy từ nhà cung cấp dừng công việc chưa hoàn thành.
  • Bù trừ tài chính tạo hoàn tiền hoặc khoản tín dụng.
  • Thông điệp đính chính thừa nhận thư đầu tiên vẫn còn hiển thị.
  • Khắc phục thủ công xử lý các tác động có bối cảnh không thể đặt trong quy tắc tự động an toàn.

Bù trừ cũng có thể thất bại. Điểm cuối hoàn tiền có thể hết thời gian chờ. Cửa sổ hủy có thể đóng. Địa chỉ người nhận có thể từ chối thư đính chính. Tài khoản tác nhân dùng có thể thiếu quyền. Vì vậy, hệ thống phải theo dõi bù trừ như một thao tác khác, với mã định danh ý định, trạng thái, số lần thử, bằng chứng và chính sách phê duyệt riêng.

Đừng xây dựng tính năng «khôi phục việc khôi phục» theo kiểu đệ quy. Hãy mô hình hóa lịch sử như sổ cái hành động. Nếu bù trừ gây lỗi mới, hãy đưa ra hành động rõ ràng khác sau khi xem lại trạng thái hiện tại. Lịch sử sẽ dài hơn, nhưng vẫn dễ hiểu trong sự cố.

Idempotency ngăn lặp lại nhưng không đảo ngược thành công

Lên kế hoạch thay đổi rủi ro sớm hơn
Lập kế hoạch thay đổi trong Koder.ai trước khi tạo nó, để ranh giới ứng dụng rõ ràng trước lúc triển khai.

Idempotency bảo vệ các lần thử lại khỏi tạo tác động dự định trùng lặp, nó không hoàn tác tác động thành công đầu tiên. Các đội thường nhầm lẫn hai điều này rồi phát hiện khác biệt sau một lần hết thời gian chờ.

RFC 9110 định nghĩa phương thức yêu cầu idempotent dựa trên việc tác động dự định của nhiều yêu cầu giống hệt nhau giống với một yêu cầu như vậy. RFC xác định PUT, DELETE và các phương thức an toàn là idempotent ở cấp ngữ nghĩa giao thức. POST nhìn chung không idempotent, dù API có thể bổ sung hành vi idempotency bằng hợp đồng riêng.

Điều kiện này rất quan trọng. DELETE idempotent vẫn có thể tạo mục nhật ký, chỉ số hoặc phản hồi mới mỗi lần. Cách nhà cung cấp triển khai idempotency cũng có thể hết hạn bản ghi, giới hạn mã định danh trong một tài khoản, từ chối tham số đã thay đổi hoặc chỉ lưu một số kết quả. Hãy đọc hợp đồng của nhà cung cấp thay vì suy ra mức đảm bảo từ động từ HTTP.

Mỗi ý định tạo tác động cần nhận một giá trị idempotency ổn định trước lần thử đầu tiên. Các lần thử lại cho cùng ý định dùng lại giá trị đó. Ý định nghiệp vụ mới nhận giá trị mới. Đừng tạo nó chỉ từ các tham số có thể thay đổi như khách hàng, số tiền và ngày tháng, vì hai lần mua hợp lệ có thể trùng các giá trị này.

Hết thời gian chờ tạo kết quả chưa rõ, không phải thất bại. Hãy theo trình tự này:

  1. Đánh dấu lần thử là outcome_unknown, đừng tạo ý định thay thế.
  2. Truy vấn nhà cung cấp bằng giá trị idempotency hoặc mã tham chiếu thao tác.
  3. Nếu nhà cung cấp xác nhận thành công, ghi nhận thành công đó tại cục bộ.
  4. Nếu họ xác nhận không có thao tác, thử lại với cùng giá trị.
  5. Nếu họ không thể trả lời, giữ thao tác để đối soát hoặc con người xem xét.

Dạng phản hồi này cho tác nhân đủ thông tin để phân biệt được chấp nhận với sự không chắc chắn khi truyền tải:

{
  "intent_id": "eff_7f31",
  "attempt": 2,
  "idempotency_key": "eff_7f31",
  "transport_status": "timeout",
  "provider_status": "unknown",
  "provider_reference": null,
  "next_action": "reconcile"
}

Giá trị idempotency nên đi qua nhật ký, thông điệp hàng đợi, tiêu đề API và siêu dữ liệu của nhà cung cấp khi được hỗ trợ. Nếu người vận hành không thể tìm kiếm theo nó ở cả hai phía ranh giới, họ sẽ phải đoán trong quá trình khôi phục.

Phê duyệt phải ở ranh giới tác động

Phê duyệt phải diễn ra sau khi tác nhân đã hình thành hành động bên ngoài chính xác và trước khi yêu cầu không thể đảo ngược đầu tiên rời hệ thống. Phê duyệt ở đầu một nhiệm vụ rộng cho tác nhân quá nhiều khoảng trống để sau đó đổi người nhận, số tiền, phạm vi hoặc công cụ.

«Xử lý tài khoản của khách hàng này» không phải phê duyệt đủ để thu tiền thẻ hoặc gửi email cho mọi người dùng. Phê duyệt hợp lệ mô tả thao tác cụ thể: người nhận, số tiền và tiền tệ, nội dung thư hoặc mã tóm tắt payload, tài khoản đích, công cụ, thời hạn và số lần thử được phép. Nếu bất kỳ trường nào đã phê duyệt thay đổi, phê duyệt không còn khớp.

Chính sách hữu ích sẽ sắp xếp tác động theo hậu quả thay vì theo tác nhân hoặc mô hình yêu cầu. Quyền đọc vẫn có thể lộ dữ liệu riêng tư, nhưng không tạo cùng vấn đề khôi phục như hành động đi ra ngoài. Soạn email là cục bộ và có thể đảo ngược. Gửi email vượt qua ranh giới. Tạo đề xuất thanh toán là cục bộ. Thu tiền vượt qua ranh giới.

Yêu cầu phê duyệt rõ ràng cho các hành động:

  • Chuyển tiền hoặc tạo nghĩa vụ tài chính
  • Gửi thông tin cho một người hoặc tổ chức bên ngoài
  • Xuất bản, xóa hoặc tiết lộ dữ liệu ngoài kho lưu trữ được kiểm soát
  • Thay đổi danh tính, quyền truy cập, quyền sở hữu hoặc cài đặt bảo mật
  • Bắt đầu công việc thực tế hoặc quy trình khác không thể thu hồi một cách đáng tin cậy

Hành động lặp lại, ít hậu quả có thể dùng phê duyệt thường trực có giới hạn. Giới hạn cần nêu số tiền tối đa, tập người nhận, công cụ được phép, thời điểm hết hạn, tần suất và tổng số thao tác. «Đã phê duyệt cho việc lập hóa đơn» không có ranh giới có thể thực thi.

Phê duyệt cũng cần chống phát lại. Hãy gắn nó với mã tóm tắt bất biến của thao tác và đánh dấu đã dùng khi chính sách chỉ cho phép thực hiện một lần. Nếu thực thi trả về kết quả chưa rõ, đừng yêu cầu phê duyệt mới rồi tạo ý định thứ hai. Hãy đối soát ý định đã được phê duyệt trước.

Màn hình phê duyệt cần nêu sự thật về khôi phục bằng ngôn ngữ thông thường. «Không thể thu hồi thư này sau khi gửi» là hữu ích. «Thao tác này có thể đảo ngược» gây hiểu lầm khi cách khôi phục thực tế là hoàn tiền có thể mất thời gian và vẫn hiện trên sao kê tài chính.

Hợp đồng công cụ phải thể hiện toàn bộ vòng đời tác động

Tách lưu trữ khỏi tác động
Dùng tên miền riêng và lưu trữ cho ứng dụng, đồng thời giữ phê duyệt các tác động bên ngoài trong hợp đồng công cụ.

Hợp đồng công cụ của tác nhân cần mô tả ý định, thực thi, quan sát và bù trừ như các thao tác riêng. Một hàm duy nhất tạo tác động rồi trả về success: true để lại quá ít bằng chứng cho thử lại, phê duyệt hoặc ứng phó sự cố.

Mảnh chính sách sau đủ nhỏ để thực thi và đủ cụ thể để đánh giá:

tools:
  send_email:
    effect: irreversible
    approval: required
    idempotency_field: intent_id
    evidence_field: provider_message_id
    compensation: null

  capture_payment:
    effect: compensatable
    approval: required
    idempotency_field: intent_id
    evidence_field: provider_payment_id
    compensation: refund_payment

  update_draft:
    effect: local_reversible
    approval: none
    compensation: restore_version

effect cho bộ lập kế hoạch biết lớp khôi phục nào áp dụng. approval chặn thực thi cho đến khi đối số chính xác được cho phép. Trường idempotency giúp lần thử lại dùng chung một danh tính. Trường bằng chứng cho người vận hành biết điều gì phải được giữ lại. Trường bù trừ trỏ đến công cụ riêng thay vì giả vờ lệnh gọi gốc có thể chạy ngược.

Thực thi cần nhận phong bì bất biến:

{
  "intent_id": "eff_7f31",
  "operation": "capture_payment",
  "arguments": {
    "invoice_id": "inv_2048",
    "amount_minor": 12900,
    "currency": "USD"
  },
  "approval": {
    "approval_id": "apr_662",
    "scope_hash": "sha256:8b4f...",
    "expires_at": "2026-07-27T18:00:00Z"
  }
}

Bộ thực thi tính mã tóm tắt thao tác, so sánh với scope_hash, kiểm tra hết hạn, giữ chỗ ý định rồi mới liên hệ nhà cung cấp. Nó lưu siêu dữ liệu yêu cầu trước khi gọi và phản hồi sau đó. Nếu bị lỗi giữa hai lượt ghi, ý định bền vững vẫn sẵn có để đối soát.

Bộ thực thi cần từ chối bốn điều kiện mà không tự suy diễn: đối số đã thay đổi, phê duyệt hết hạn, dùng lại ý định cho thao tác khác và cố bù trừ một tác động chưa xác nhận hoàn tất thành công. Tác nhân giỏi tìm ra những bước tiếp theo có vẻ hợp lý. Kiểm soát tài chính và giao tiếp phải ưu tiên việc dừng rõ ràng hơn một phỏng đoán có vẻ hợp lý.

Hãy dành riêng một công cụ cho quan sát, chẳng hạn get_payment_status(intent_id). Quan sát không được tạo tác động. Tách riêng nó giúp tác nhân giải quyết kết quả mơ hồ mà không được cấp phép thử lại hành động gốc.

Một lần chạy lỗi có thể vượt qua mọi ranh giới khôi phục

Khôi phục không phải bù trừ
Khôi phục ảnh chụp nhanh ứng dụng khi lỗi nằm cục bộ, sau đó đối soát riêng từng hành động bên ngoài.

Một lần chạy tác nhân có thể để mã, bản ghi cơ sở dữ liệu và hệ thống bên ngoài ở những thời điểm khác nhau. Đi qua tình huống lỗi đó trước khi ra mắt sẽ phơi bày khoảng trống mà nút khôi phục chung chung che giấu.

Giả sử một tác nhân xây ứng dụng thành viên, triển khai thay đổi, nhập danh sách khách hàng, thu phí hằng năm và gửi email chào mừng. Nhiệm vụ nghe có vẻ thống nhất, nhưng vượt qua ít nhất bốn ranh giới khôi phục.

Lúc 14:00, tác nhân triển khai mã tính phí hằng năm từ sai cột. Lúc 14:02, nó ghi 40 ý định thanh toán và bản nháp email vào cơ sở dữ liệu. Lúc 14:03, một worker thu một số khoản thanh toán. Lúc 14:04, nhà cung cấp thư nhận các email chào mừng có mức phí sai. Lúc 14:05, giám sát dừng worker. Một số lệnh gọi thanh toán hết thời gian chờ sau khi đã đến bộ xử lý, nên trạng thái cục bộ không cho biết chúng có thành công không.

Khôi phục ảnh chụp nhanh mã lúc 13:59 ngăn phép tính lỗi trong các lần chạy sau. Nó không thay đổi mức phí đã được sao chép vào các ý định hiện có. Hoàn tác commit Git ghi lại việc sửa nguồn nhưng cũng có giới hạn đó.

Khôi phục cơ sở dữ liệu về 13:59 sẽ xóa các bản ghi ý định cục bộ có mã tham chiếu nhà cung cấp và giá trị idempotency. Điều này khiến sai lệch bên ngoài tệ hơn. Hành động cơ sở dữ liệu tốt hơn là sửa logic: giữ lại các ý định, đánh dấu thao tác không chắc chắn để đối soát và chỉ sửa hàng sau khi khớp với trạng thái nhà cung cấp.

Đội ứng phó sau đó nên xử lý theo lớp tác động. Họ truy vấn từng khoản thanh toán không chắc chắn bằng danh tính thao tác ổn định. Các khoản đã thu được xác nhận chuyển sang xem xét hoàn tiền, lần thử thất bại đóng mà không thử lại và lần chưa rõ vẫn bị chặn. Email đã gửi nhận được nội dung đính chính được phê duyệt cẩn thận. Thư trong hàng đợi chưa đến nhà cung cấp sẽ bị hủy. Mỗi bù trừ nhận ý định mới liên kết với ý định gốc.

Ví dụ này cũng cho thấy vì sao bù trừ tự động có thể nguy hiểm. Nếu hệ thống hoàn tiền ngay mọi bản ghi payment_unknown cục bộ, nó có thể hoàn tiền cho khoản thu chưa từng tồn tại hoặc gọi điểm cuối hoàn tiền với mã tham chiếu sai. Nếu gửi lại mọi email thiếu sau khi khôi phục cơ sở dữ liệu, người nhận có thể nhận thư trùng. Đối soát phải diễn ra trước bù trừ bất cứ khi nào trạng thái cục bộ và nhà cung cấp không khớp.

Lần chạy chỉ hoàn tất khi mọi ý định đạt trạng thái cuối như succeeded, confirmed_failed, compensated hoặc manual_exception. «Ứng dụng đã được khôi phục» chỉ mô tả phần đầu của sự cố.

Khôi phục chỉ hiệu quả khi bằng chứng còn tồn tại

Cơ chế khôi phục thất bại khi rollback xóa các bản ghi cần để quyết định chuyện gì đã xảy ra. Hãy lưu sổ cái tác động chỉ ghi thêm, nằm ngoài trạng thái ứng dụng mà ảnh chụp nhanh hoặc phục hồi thường quy có thể thay thế, đồng thời giữ đủ bằng chứng từ nhà cung cấp để đối soát từng thao tác.

Sổ cái cần ghi việc tạo ý định, mã tóm tắt đối số, phê duyệt, lease thực thi, lần thử, kết quả truyền tải, mã tham chiếu nhà cung cấp, trạng thái nhà cung cấp đã quan sát và liên kết bù trừ. Hạn chế thay đổi vào các chuyển trạng thái thay vì cho phép tác nhân ghi đè mục cũ. Sửa đổi cần thêm sự kiện thay vì chỉnh sửa lịch sử.

Hãy giám sát trạng thái chưa giải quyết, không chỉ lỗi rõ ràng. outcome_unknown kéo dài mười phút có thể nguy hiểm hơn việc bị từ chối rõ ràng vì người vận hành có thể thử lại thủ công. Cũng cần cảnh báo khi phê duyệt hết hạn trong lúc thực thi, giá trị idempotency xuất hiện với mã tóm tắt đối số khác, hoặc bù trừ thất bại.

Hãy diễn tập khôi phục với các điểm lỗi khó xử có chủ ý. Dừng worker sau khi nhà cung cấp nhận yêu cầu nhưng trước khi ghi thành công ở cục bộ. Phục hồi dữ liệu ứng dụng từ ảnh chụp nhanh cũ trong khi vẫn giữ sổ cái tác động. Cho phê duyệt hết hạn giữa lập kế hoạch và thực thi. Làm API quan sát không sẵn sàng. Buổi diễn tập đạt yêu cầu khi hệ thống dừng, đối soát và hiển thị quyết định chưa giải quyết mà không nhân đôi tác động.

Khi dùng Koder.ai, hãy coi ảnh chụp nhanh và rollback của nó là lớp khôi phục ứng dụng, rồi thiết kế kiểm soát riêng cho lịch sử cơ sở dữ liệu và mọi hành động bên ngoài mà ứng dụng có thể kích hoạt. Xuất mã nguồn, kiểm soát triển khai và rollback giúp khôi phục phần mềm, trong khi hợp đồng công cụ của ứng dụng vẫn chịu trách nhiệm về phê duyệt và bù trừ.

Nút khôi phục nên ghi rõ ranh giới ngay bên cạnh nút: mã, cấu hình, dữ liệu được quản lý hoặc tác động bên ngoài. Nếu giao diện không thể nói chính xác câu đó, nó không nên hứa hẹn khôi phục. Cơ chế trung thực có thể kém kỳ diệu hơn, nhưng nó mang lại cho đội ứng phó điều họ cần lúc 2 giờ sáng: bản tường thuật đáng tin cậy về điều gì đã thay đổi, điều gì đã thoát ra ngoài và hành động nào an toàn để thực hiện tiếp.

Câu hỏi thường gặp

Khôi phục tác nhân AI có thể hủy gửi email không?

Không. Nó có thể khôi phục mã hoặc ảnh chụp nhanh ứng dụng có trước khi email được yêu cầu, nhưng không thể thu hồi thư mà nhà cung cấp email đã nhận. Hệ thống cần có phê duyệt trước khi gửi và lưu bền vững phản hồi của nhà cung cấp.

Khôi phục tự động có thể đảo ngược khoản thanh toán bằng thẻ tín dụng không?

Thường là không. Khôi phục không thể xóa khoản thanh toán đã quyết toán khỏi hồ sơ của bên xử lý, hệ thống phải tạo hoàn tiền như một giao dịch tài chính mới. Khoản ủy quyền chưa được thu có thể hủy được, nhưng đó vẫn là một thao tác thanh toán rõ ràng chứ không phải khôi phục mã.

Git revert thực sự hoàn tác điều gì?

Git revert tạo một commit mới áp dụng phần thay đổi ngược với một thay đổi mã trước đó. Nó không khôi phục các hàng cơ sở dữ liệu, hủy yêu cầu API, xóa thư đã được gửi, hoặc hoàn tiền. Hãy xem đây chỉ là cách sửa lịch sử mã nguồn.

Khôi phục cơ sở dữ liệu có hoàn tác các lệnh gọi API bên ngoài không?

Giao dịch cơ sở dữ liệu có thể hoàn tác các lượt ghi cục bộ chưa được commit. Sau khi commit, quy trình khôi phục có thể đưa cơ sở dữ liệu về trạng thái trước đó, nhưng cũng có thể xóa các lượt ghi hợp lệ không liên quan và không thể đảo ngược hành động trong hệ thống bên ngoài. Hãy dùng nó như một quy trình khôi phục, không phải nút hoàn tác cho mọi thứ.

Khóa idempotency có giống khôi phục không?

Không. Tính idempotency ngăn các lần thử lặp lại tạo ra tác động lặp lại nếu nhà cung cấp triển khai đúng. Nó không hủy yêu cầu thành công đầu tiên hoặc bảo đảm rằng một yêu cầu khác dùng cùng mã định danh sẽ an toàn.

Những hành động nào của tác nhân nên cần con người phê duyệt?

Hãy yêu cầu phê duyệt khi hành động có thể tạo hậu quả pháp lý, tài chính, quyền riêng tư, danh tiếng hoặc vận hành bên ngoài ứng dụng. Ví dụ gồm gửi tin nhắn, thu tiền, xuất bản dữ liệu, thay đổi quyền truy cập, đặt hàng và gọi API khởi động công việc thực tế. Thao tác đọc và bản nháp cục bộ thường không cần cùng mức kiểm soát.

Tác nhân cần ghi lại gì trước khi gọi API bên ngoài?

Ghi lại mã định danh ý định, đối số chính xác, quyền hạn, phạm vi phê duyệt, giá trị idempotency, số lần thử, mã tham chiếu của nhà cung cấp, trạng thái phản hồi và trạng thái bù trừ. Lưu bản ghi trước khi thực thi và cập nhật sau mỗi lần thử. Chỉ nhật ký ứng dụng rất dễ bị mất trong chính lần khôi phục bạn đang điều tra.

Tác nhân có thể thử lại yêu cầu hết thời gian chờ một cách an toàn như thế nào?

Chỉ an toàn khi thao tác thực sự có tính idempotent hoặc dịch vụ nhận nhận ra một giá trị idempotency ổn định. Hết thời gian chờ là kết quả mơ hồ vì yêu cầu đầu tiên có thể đã thành công dù bên gọi không nhận được phản hồi. Khi có thể, hãy truy vấn nhà cung cấp bằng cùng mã định danh thao tác trước khi gửi yêu cầu mới.

Khi nào hành động bù trừ nên chạy tự động?

Dùng hành động bù trừ khi hành động bên ngoài có thao tác ngược thật sự có ý nghĩa và chính sách cho phép. Hoàn tiền, yêu cầu hủy và thông điệp đính chính là các hành động bù trừ vì chúng thêm lịch sử mới thay vì xóa lịch sử cũ. Đừng tự động hóa mù quáng khi chúng có thể tạo thêm khoản thu, tin nhắn, thay đổi quyền hoặc cam kết pháp lý.

Kiểm tra độ an toàn khi khôi phục cho công cụ tác nhân như thế nào?

Hãy chạy thử trong môi trường staging, buộc hết thời gian chờ sau khi nhà cung cấp nhận yêu cầu nhưng trước khi tác nhân ghi nhận thành công. Xác nhận hệ thống đối soát bằng mã định danh thao tác, tránh tạo bản sao và ghi lại mọi bù trừ. Cũng cần kiểm tra phê duyệt hết hạn, đối số thay đổi, nhà cung cấp ngừng hoạt động một phần và khôi phục sau khi dữ liệu ứng dụng được phục hồi.

Related posts