Thử lại các hàm không đồng bộ

Tài liệu này mô tả cách bạn có thể yêu cầu các chức năng nền không đồng bộ (không phải HTTPS) thử lại khi không thành công.

Ngữ nghĩa của lệnh thử lại

Cloud Functions cung cấp ít nhất một lần thực thi hàm do sự kiện điều khiển cho mỗi sự kiện do nguồn sự kiện phát ra. Theo mặc định, nếu một lệnh gọi hàm kết thúc bằng lỗi, thì hàm đó sẽ không được gọi lại và sự kiện sẽ bị loại bỏ. Khi bạn bật tính năng thử lại trên một hàm do sự kiện điều khiển, Cloud Functions sẽ thử lại lệnh gọi hàm không thành công cho đến khi hoàn tất hoặc cửa sổ thử lại hết hạn.

Đối với các hàm thế hệ 2, khoảng thời gian thử lại này sẽ hết hạn sau 24 giờ. Đối với các hàm thế hệ 1, hàm sẽ hết hạn sau 7 ngày. Cloud Functions thử lại các hàm do sự kiện tạo mới bằng cách sử dụng chiến lược thời gian đợi luỹ thừa, với thời gian đợi tăng dần từ 10 đến 600 giây. Chính sách này được áp dụng cho các hàm mới trong lần đầu tiên bạn triển khai các hàm đó. Chính sách này không áp dụng cho các hàm hiện có được triển khai lần đầu trước khi những thay đổi được mô tả trong ghi chú phát hành này có hiệu lực, ngay cả khi bạn triển khai lại các hàm đó.

Khi không bật tính năng thử lại cho một hàm (mặc định), hàm đó luôn báo cáo rằng hàm đã thực thi thành công và mã phản hồi 200 OK có thể xuất hiện trong nhật ký của hàm. Điều này xảy ra ngay cả khi hàm gặp lỗi. Để làm rõ thời điểm hàm của bạn gặp lỗi, hãy nhớ báo cáo lỗi một cách thích hợp.

Lý do khiến các hàm do sự kiện điều khiển không hoàn tất

Trong một số ít trường hợp, một hàm có thể thoát sớm do lỗi nội bộ, và theo mặc định, hàm có thể được tự động thử lại hoặc không.

Thông thường, một hàm do sự kiện điều khiển có thể không hoàn tất thành công do lỗi được gửi trong chính mã hàm. Sau đây là một số lý do có thể dẫn đến việc này:

  • Hàm này chứa lỗi và thời gian chạy sẽ gửi một ngoại lệ.
  • Hàm không thể truy cập vào điểm cuối của dịch vụ hoặc hết thời gian chờ trong khi cố gắng truy cập.
  • Hàm này cố ý gửi một ngoại lệ (ví dụ: khi một tham số không xác thực được).
  • Hàm Node.js trả về một lời hứa bị từ chối hoặc truyền một giá trị không phải null đến một lệnh gọi lại.

Trong mọi trường hợp này, hàm sẽ ngừng thực thi theo mặc định và sự kiện sẽ bị loại bỏ. Để thử lại hàm khi xảy ra lỗi, bạn có thể thay đổi chính sách thử lại mặc định bằng cách đặt thuộc tính "thử lại khi không thành công". Điều này khiến sự kiện được thử lại nhiều lần cho đến khi hàm hoàn tất thành công hoặc hết thời gian chờ thử lại.

Bật hoặc tắt tính năng thử lại

Định cấu hình các lần thử lại từ bảng điều khiển

Nếu bạn đang tạo một hàm mới:

  1. Trên màn hình Create Function (Tạo hàm), trong mục Trigger (Trình kích hoạt), hãy chọn loại sự kiện để làm trình kích hoạt cho hàm của bạn.
  2. Chọn hộp đánh dấu Thử lại khi không thành công để cho phép thử lại.

Nếu bạn đang cập nhật một hàm hiện có:

  1. Trên trang Tổng quan về Cloud Functions, hãy nhấp vào tên của hàm mà bạn đang cập nhật để mở màn hình Thông tin chi tiết về hàm, sau đó chọn Chỉnh sửa trên thanh trình đơn để hiện ngăn Trình kích hoạt.
  2. Chọn hoặc bỏ chọn hộp đánh dấu Thử lại khi không thành công để bật hoặc tắt tính năng thử lại.

Định cấu hình các lần thử lại trong mã hàm

Với Cloud Functions for Firebase, bạn có thể bật tính năng thử lại trong mã cho một hàm. Để thực hiện việc này cho hàm nền như functions.foo.onBar(myHandler);, hãy sử dụng runWith và định cấu hình chính sách lỗi:

functions.runWith({failurePolicy: true}).foo.onBar(myHandler);

Việc đặt true như minh hoạ sẽ định cấu hình một hàm để thử lại khi không thành công.

Các phương pháp hay nhất

Phần này mô tả các phương pháp hay nhất để sử dụng tính năng thử lại.

Sử dụng tính năng thử lại để xử lý các lỗi tạm thời

Vì hàm này được thử lại liên tục cho đến khi thực thi thành công, nên các lỗi vĩnh viễn như lỗi sẽ bị loại bỏ khỏi mã của bạn trong quá trình kiểm thử trước khi cho phép thử lại. Tốt nhất bạn nên sử dụng tính năng thử lại để xử lý các lỗi gián đoạn hoặc tạm thời có nhiều khả năng được giải quyết khi thử lại, chẳng hạn như điểm cuối dịch vụ không ổn định hoặc hết thời gian chờ.

Đặt điều kiện kết thúc để tránh vòng lặp thử lại vô hạn

Bạn nên bảo vệ hàm của mình khỏi việc lặp lại liên tục khi sử dụng tính năng thử lại. Bạn có thể làm việc này bằng cách đưa vào một điều kiện kết thúc được xác định rõ ràng, trước khi hàm bắt đầu xử lý. Lưu ý rằng kỹ thuật này chỉ hoạt động nếu hàm của bạn bắt đầu thành công và có thể đánh giá điều kiện kết thúc.

Một phương pháp đơn giản nhưng hiệu quả là loại bỏ các sự kiện có dấu thời gian cũ hơn một khoảng thời gian nhất định. Điều này giúp tránh các lần thực thi quá mức khi lỗi xảy ra liên tục hoặc kéo dài hơn dự kiến.

Ví dụ: đoạn mã này loại bỏ tất cả sự kiện cũ hơn 10 giây:

const eventAgeMs = Date.now() - Date.parse(event.timestamp);
const eventMaxAgeMs = 10000;
if (eventAgeMs > eventMaxAgeMs) {
  console.log(`Dropping event ${event} with age[ms]: ${eventAgeMs}`);
  callback();
  return;
}

Sử dụng catch với Lời hứa

Nếu hàm của bạn đã bật tính năng thử lại, thì mọi lỗi chưa được xử lý sẽ kích hoạt một lần thử lại. Hãy đảm bảo rằng mã của bạn ghi lại mọi lỗi không nên dẫn đến việc thử lại.

Dưới đây là ví dụ về những việc bạn nên làm:

return doFooAsync().catch((err) => {
    if (isFatal(err)) {
        console.error(`Fatal error ${err}`);
    }
    return Promise.reject(err);
});

Tạo các hàm do sự kiện điều khiển có thể thử lại và idempotent

Các hàm hướng sự kiện có thể được thử lại phải không thay đổi. Dưới đây là một số nguyên tắc chung để tạo một hàm idempotent như vậy:

  • Nhiều API bên ngoài (chẳng hạn như Stripe) cho phép bạn cung cấp khoá giá trị nhận dạng dưới dạng tham số. Nếu đang sử dụng một API như vậy, bạn nên sử dụng mã sự kiện làm khoá tính chất không thể thay đổi.
  • Tính năng bình thường hoạt động tốt với chế độ phân phối ít nhất một lần, vì tính năng này giúp bạn an toàn thử lại. Vì vậy, phương pháp hay nhất chung để viết mã đáng tin cậy là kết hợp tính chất không thể thay đổi với tính năng thử lại.
  • Đảm bảo rằng mã của bạn không thay đổi giá trị nội bộ. Ví dụ:
    • Đảm bảo rằng các đột biến có thể xảy ra nhiều lần mà không làm thay đổi kết quả.
    • Truy vấn trạng thái cơ sở dữ liệu trong một giao dịch trước khi thay đổi trạng thái.
    • Đảm bảo rằng tất cả các hiệu ứng phụ đều giống nhau.
  • Áp dụng quy trình kiểm tra giao dịch bên ngoài hàm, độc lập với mã. Ví dụ: hãy duy trì trạng thái ở đâu đó bản ghi rằng một mã sự kiện nhất định đã được xử lý.
  • Xử lý các lệnh gọi hàm trùng lặp ngoài băng thông. Ví dụ: có một quy trình dọn dẹp riêng để dọn dẹp sau các lệnh gọi hàm trùng lặp.

Định cấu hình chính sách thử lại

Tuỳ thuộc vào nhu cầu của hàm, bạn có thể muốn trực tiếp định cấu hình chính sách thử lại. Điều này cho phép bạn thiết lập bất kỳ tổ hợp nào sau đây:

  • Rút ngắn khoảng thời gian thử lại từ 7 ngày xuống chỉ còn 10 phút.
  • Thay đổi thời gian đợi tối thiểu và tối đa cho chiến lược thử lại thời gian đợi luỹ thừa.
  • Thay đổi chiến lược thử lại để thử lại ngay lập tức.
  • Định cấu hình chủ đề thư chết.
  • Đặt số lần phân phối tối đa và tối thiểu.

Cách định cấu hình chính sách thử lại:

  1. Viết một hàm HTTP.
  2. Sử dụng API Pub/Sub để tạo gói thuê bao Pub/Sub, chỉ định URL của hàm làm mục tiêu.

Hãy xem tài liệu về Pub/Sub để xử lý lỗi để biết thêm thông tin về cách định cấu hình trực tiếp Pub/Sub.