Tài liệu này mô tả cách bạn có thể yêu cầu các hàm không đồng bộ (không phải HTTPS) ở chế độ nền thử lại khi gặp lỗi.
Lý do khiến các hàm dựa trên sự kiệ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ể tự động thử lại hoặc không.
Thông thường hơn, một hàm dựa trên sự kiện có thể không hoàn tất thành công do các lỗi phát sinh trong chính mã hàm. Điều này có thể xảy ra do một số lý do sau:
- Hàm này có một lỗi và thời gian chạy sẽ trả về một ngoại lệ.
- Hàm không thể truy cập vào một điểm cuối dịch vụ hoặc hết thời gian chờ trong khi cố gắng thực hiện việc này.
- Hàm này cố ý tạo ra một ngoại lệ (ví dụ: khi một tham số không xác thực được).
- Một 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 bất kỳ trường hợp nào nêu trên, hàm sẽ ngừng thực thi và trả về lỗi. Các trình kích hoạt sự kiện tạo ra thông báo có chính sách thử lại mà bạn có thể tuỳ chỉnh để đáp ứng nhu cầu của hàm.
Ngữ nghĩa của thao tác thử lại
Cloud Functions cung cấp hoạt động thực thi ít nhất một lần của một hàm dựa trên sự kiện cho mỗi sự kiện do một nguồn sự kiện phát ra. Cách bạn định cấu hình các lần thử lại phụ thuộc vào cách bạn tạo hàm:
- Các hàm được tạo trong Google Cloud Console hoặc bằng Cloud Run Admin API yêu cầu bạn tạo và quản lý riêng các trình kích hoạt sự kiện. Trình kích hoạt có hành vi thử lại mặc định mà bạn có thể tuỳ chỉnh cho phù hợp với nhu cầu của hàm.
- Các hàm được tạo bằng Cloud Functions API phiên bản 2 sẽ ngầm tạo các trình kích hoạt sự kiện cần thiết, chẳng hạn như các chủ đề Pub/Sub hoặc trình kích hoạt Eventarc. Theo mặc định, tính năng thử lại sẽ bị tắt đối với các sự kiện kích hoạt này và bạn có thể bật lại bằng Cloud Functions API phiên bản 2.
Các hàm dựa trên sự kiện được tạo bằng Cloud Run
Các hàm được tạo trong Google Cloud Console hoặc bằng Cloud Run Admin API yêu cầu bạn tạo và quản lý riêng các trình kích hoạt sự kiện. Bạn nên xem xét hành vi mặc định của từng loại điều kiện kích hoạt:
- Eventarc chính sách thử lại có thời gian giữ lại thông báo mặc định là 24 giờ với độ trễ thời gian đợi luỹ thừa. Tham khảo tài liệu về Eventarc để biết thông tin về sự kiện thử lại.
- Pub/Sub mặc định sử dụng chính sách gửi lại ngay lập tức cho tất cả các gói thuê bao. Tham khảo tài liệu Pub/Sub về xử lý lỗi tin nhắn và yêu cầu thử lại.
Các hàm dựa trên sự kiện được tạo bằng Cloud Functions API phiên bản 2
Các hàm được tạo bằng API Cloud Functions phiên bản 2; ví dụ: khi bạn sử dụng Cloud Functions gcloud CLI, REST API hoặc Terraform, hệ thống sẽ tạo và quản lý các trình kích hoạt sự kiện thay cho bạn. 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 cho một hàm dựa trên sự kiện, Cloud Functions sẽ thử lại một lệnh gọi hàm không thành công cho đến khi lệnh gọi đó hoàn tất thành công hoặc hết khoảng thời gian thử lại.
Khi bạn không bật tính năng thử lại cho một hàm (đây là chế độ mặc định), hàm đó sẽ luôn báo cáo rằng đã 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. Để cho biết 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.
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ừ 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 một hàm nền như functions.foo.onBar(myHandler);
, hãy dùng runWith
và định cấu hình chính sách thất bại:
functions.runWith({failurePolicy: true}).foo.onBar(myHandler);
Việc thiết lập true
như trong cấu hình sẽ thiết lập một hàm để thử lại khi thất bại.
Khoảng thời gian thử lại
Đối với các hàm thế hệ thứ 2, cửa sổ thử lại này sẽ hết hạn sau 24 giờ. Đối với các chức năng thế hệ đầu tiên, mã này sẽ hết hạn sau 7 ngày. Cloud Functions thử lại các hàm dựa trên sự kiện mới tạo bằng chiến lược thời gian đợi luỹ thừa, với thời gian đợi tăng từ 10 đến 600 giây. Chính sách này được áp dụng cho các hàm mới vào lần đầu tiên bạn triển khai chúng. Thay đổi này không được áp dụng ngược thời gian cho các hàm hiện có được triển khai lần đầu trước khi các 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.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 của bạn được thử lại liên tục cho đến khi thực thi thành công, nên bạn phải loại bỏ các lỗi vĩnh viễn như lỗi trong mã thông qua kiểm thử trước khi bật tính năng thử lại. Bạn nên dùng cơ chế thử lại để xử lý các lỗi không liên tục hoặc tạm thời có khả năng cao sẽ đượ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 tình trạng lặp lại liên tục khi sử dụng các lần thử lại. Bạn có thể làm việc này bằng cách thêm một điều kiện kết thúc được xác định rõ trước khi hàm bắt đầu xử lý. Xin lưu ý rằng kỹ thuật này chỉ hoạt động nếu hàm của bạn khởi động 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 thời gian nhất định. Điều này giúp tránh tình trạng 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ả cá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 Promises
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. Đảm bảo rằng mã của bạn ghi lại mọi lỗi không được dẫn đến việc thử lại.
Sau đâ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 dựa trên sự kiện có thể thử lại theo cách thức bất biến
Các hàm dựa trên sự kiện có thể thử lại phải là hàm đẳng nhất. Sau đây là một số nguyên tắc chung để tạo một hàm như vậy có tính chất luỹ đẳng:
- Nhiều API bên ngoài (chẳng hạn như Stripe) cho phép bạn cung cấp khoá bất biến dưới dạng một tham số. Nếu đang sử dụng một API như vậy, bạn nên dùng mã sự kiện làm khoá chỉ thực hiện một lần.
- Tính chất bất biến hoạt động hiệu quả với phương thức phân phối ít nhất một lần, vì tính chất này giúp bạn có thể thử lại một cách an toàn. Vì vậy, một phương pháp hay nhất chung để viết mã đáng tin cậy là kết hợp tính chất bất biến với các lần thử lại.
- Đảm bảo mã của bạn có tính chất đẳng nhất 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 tác dụng phụ đều là tác dụng phụ bất biến.
- Áp dụng một quy trình kiểm tra giao dịch bên ngoài hàm, độc lập với mã. Ví dụ: duy trì trạng thái ở một nơi nào đó ghi lại 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 tần. 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 định cấu hình trực tiếp chính sách thử lại. Nhờ đó, bạn có thể 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 còn ít nhất 10 phút.
- Thay đổi thời gian tạm ngưng tối thiểu và tối đa cho chiến lược thử lại tạm ngưng luỹ thừa.
- Thay đổi chiến lược thử lại thành thử lại ngay lập tức.
- Định cấu hình chủ đề thư không gửi được.
- Đặt số lần thử 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:
- Viết một hàm HTTP.
- Sử dụng API Pub/Sub để tạo một 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 về cách 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.