Cloud Scheduler menyertakan identifikasi tugas dan header HTTP waktu jadwal pada permintaan HTTP dan App Engine yang memungkinkan Anda menghapus duplikat eksekusi yang dicoba ulang dan membuat pengendali target Anda idempoten. Karena Cloud Scheduler menyediakan pengiriman setidaknya sekali, penghapusan duplikat permintaan akan mencegah pengendali atau API Google Cloud downstream Anda memproses eksekusi terjadwal yang sama lebih dari sekali saat waktu tunggu habis atau terjadi gangguan jaringan sementara.
Cara kerja penghapusan duplikat permintaan
Permintaan tugas duplikat untuk operasi terjadwal yang sama dapat terjadi dalam situasi berikut:
- Target yang berjalan lama: Layanan target memerlukan waktu lebih lama untuk merespons daripada
batas waktu percobaan (
attemptDeadline) tugas, sehingga Cloud Scheduler kehabisan waktu dan mencoba ulang tugas saat percobaan pertama masih berjalan. Untuk target HTTP,attemptDeadlineditetapkan secara default ke 3 menit dan dapat dikonfigurasi hingga 30 menit. SelaraskanattemptDeadlinedengan waktu tunggu target Anda, atau proses pekerjaan yang berjalan lama secara asinkron jika eksekusi dapat melebihi 30 menit. - Konfirmasi jaringan yang hilang atau percobaan ulang proxy sementara: Target
menerima dan memproses permintaan, tetapi gangguan jaringan sementara atau
pemutusan koneksi proxy mencegah Cloud Scheduler menerima respons
2xxHTTP. Meskipun Anda menetapkanretryCountke0, pengiriman minimal satu kali berarti target masih dapat menerima permintaan duplikat selama kegagalan transportasi sementara.
Agar pengendali tugas Anda idempoten dan menghapus duplikat permintaan yang dicoba ulang, gunakan header HTTP yang otomatis disertakan Cloud Scheduler pada permintaan ke target HTTP dan App Engine:
| Header | Deskripsi |
|---|---|
X-CloudScheduler-JobName |
ID tugas singkat (JOB_ID) dari
projects/PROJECT_ID/locations/LOCATION_ID/jobs/JOB_ID. |
X-CloudScheduler-ScheduleTime |
Untuk tugas yang ditentukan dalam
format Header ini tidak dijamin untuk tugas yang menggunakan
format jadwal |
Mewajibkan autentikasi di endpoint target Anda
Header X-CloudScheduler-* tidak diautentikasi dan dapat ditetapkan oleh pemanggil mana pun. Jangan gunakan header ini untuk autentikasi. Sebagai gantinya, amankan endpoint Anda berdasarkan jenis target:
- Target HTTP: Konfigurasikan tugas untuk mengirim token OIDC atau OAuth dan mewajibkan autentikasi di endpoint Anda. Untuk mengetahui informasi selengkapnya, lihat Menggunakan autentikasi dengan target HTTP.
- Target App Engine: Batasi akses ke pengendali dengan menetapkan
login: admindi fileapp.yamldan mengonfigurasi aturan firewall App Engine.
Menggunakan pencarian header yang tidak peka huruf besar/kecil
Kapitalisasi header dapat bervariasi di berbagai versi HTTP dan infrastruktur (misalnya, X-Cloudscheduler-Jobname di HTTP/1.1 atau huruf kecil x-cloudscheduler-jobname dan x-cloudscheduler-scheduletime di lingkungan HTTP/2 seperti Cloud Run). Selalu gunakan pencarian header yang tidak peka huruf besar/kecil di pengendali Anda.
Menghilangkan ambiguitas ID pekerjaan di seluruh project atau region
Cloud Scheduler tidak otomatis mengirim header project ID atau region. Satu endpoint pengendali mungkin menerima permintaan dari beberapa project atau region yang menggunakan JOB_ID yang sama. Dalam hal ini,
teruskan project ID atau region di
HttpTarget.headers,
AppEngineHttpTarget.headers,
atau jalur URL target atau parameter kueri, dan sertakan nilai tersebut dalam
kunci penghapusan duplikat Anda.
Menghapus duplikat permintaan di pengendali HTTP
Sebelum menerapkan penghapusan duplikat permintaan di pengendali, selesaikan prasyarat penyiapan berikut:
- Konfigurasikan jadwal tugas Anda dalam format
unix-cron(misalnya,*/5 * * * *, bukanevery 5 minutes) agar Cloud Scheduler mengirim headerX-CloudScheduler-ScheduleTime. - Siapkan datastore persisten yang mendukung transaksi atau penulisan kondisional atomik, seperti Firestore, Spanner, atau Memorystore.
Konfigurasikan kebijakan time-to-live (TTL) pada koleksi atau tabel (misalnya, pada kolom
expire_at) untuk menghapus data penghapusan duplikat lama setelah periode percobaan ulang tugas (maxRetryDuration). TTL Firestore menghapus data yang sudah tidak berlaku secara asinkron, biasanya dalam waktu 24-72 jam. Agar percobaan ulang dapat mengklaim kembali operasi dari instance yang error sebelum pembersihan TTL, simpan juga stempel waktu habis masa berlaku sewa (sepertilease_expires, yang ditetapkan setidaknya ke waktu tunggu permintaan target danattemptDeadline) dan evaluasi dalam transaksi.
Untuk memproses setiap operasi terjadwal hanya sekali di pengendali HTTP, selesaikan langkah-langkah berikut:
- Baca
X-CloudScheduler-JobNamedanX-CloudScheduler-ScheduleTimedari header permintaan masuk dan hash ke dalam kunci penghapusan duplikat dengan panjang tetap (run_id). - Jalankan transaksi di datastore Anda untuk memeriksa dan mengklaim data untuk kunci penghapusan duplikat:
- Jika data ada dan
statusadalahcompleted, segera tampilkan kode status HTTP200 OK(atau204 No Content) tanpa menjalankan logika tugas sehingga Cloud Scheduler berhenti mencoba ulang. - Jika data ada,
statusadalahin_progress, dan sewa (lease_expires) belum berakhir, tampilkan kode status error yang dapat dicoba lagi seperti409 Conflictagar Cloud Scheduler tetap mengaktifkan kebijakan percobaan ulangnya jika upaya yang sedang berlangsung gagal. Hindari menampilkan503 Service Unavailabledari target App Engine, karena App Engine memperlakukan503sebagai error sistem dan mencoba ulang permintaan tanpa memperhitungkannya terhadapretryCount. - Jika data tidak ada atau lease-nya telah berakhir, tulis data dengan
statusditetapkan kein_progress, ID upaya unik (attempt_id), stempel waktu habis masa berlaku lease (lease_expires), dan stempel waktu habis masa berlaku TTL (expire_at).
- Jika data ada dan
Setelah mengklaim data, jalankan logika tugas Anda. Dalam transaksi, pastikan bahwa
attempt_iddata masih cocok dengan upaya saat ini sebelum mengubah data:- Jika logika tugas berhasil, perbarui
statuskecompleteddan tampilkan kode status HTTP200 OK. - Jika logika tugas gagal dengan error yang dapat Anda coba lagi, hapus
data penghapusan duplikat sebelum menampilkan kode status
5xxagar Cloud Scheduler dapat mencoba lagi operasi tanpa menunggu masa berlaku sewa berakhir.
- Jika logika tugas berhasil, perbarui
Contoh pengendali HTTP
Contoh Python berikut (untuk Cloud Run atau Cloud Run Functions) menggunakan transaksi Firestore dengan sewa untuk mengklaim operasi dan menghapus duplikat permintaan tugas yang dicoba ulang.
Contoh ini belum siap produksi. Tinjau dan sesuaikan dengan kebutuhan Anda sebelum men-deploy:
Mencegah permintaan duplikat ke target API Google Cloud
Saat Cloud Scheduler memanggil endpoint API Google Cloud
(*.googleapis.com) secara langsung melalui HTTP, API target akan mengabaikan
header X-CloudScheduler-JobName dan X-CloudScheduler-ScheduleTime. Misalnya, memanggil workflowexecutions.googleapis.com untuk memulai
eksekusi Workflows,
run.googleapis.com untuk menjalankan
tugas Cloud Run, atau
cloudbuild.googleapis.com untuk menjalankan
pemicu Cloud Build akan memulai operasi baru pada
setiap upaya percobaan ulang.
Untuk keandalan produksi, terapkan idempotensi di layanan paling downstream yang mengubah status. Menghapus duplikat permintaan hanya di lapisan upstream akan mempersempit jendela percobaan ulang, tetapi jika permintaan downstream berhasil dan respons HTTP hilang melalui jaringan, pemanggil upstream tidak dapat menentukan apakah operasi telah selesai dan mungkin masih mencoba ulang permintaan.
Untuk mencegah eksekusi duplikat saat menjadwalkan target Google Cloud API, gunakan pendekatan berikut bersama-sama untuk idempotensi menyeluruh:
Rutekan permintaan melalui proxy idempoten: Alih-alih memanggil endpoint
*.googleapis.comlangsung dari Cloud Scheduler, deploy layanan Cloud Run atau proxy Cloud Run Functions Anda sendiri dan konfigurasikan Cloud Scheduler untuk memanggil proxy tersebut. Di proxy, terapkan pola klaim transaksional atomik Python dan Firestore yang dijelaskan dalam dokumen ini, di bagian Menghapus duplikat permintaan di pengendali HTTP.Proxy membaca
X-CloudScheduler-JobNamedanX-CloudScheduler-ScheduleTime, menghapus duplikat permintaan yang dicoba lagi, dan meneruskan kunci penghapusan duplikat sebagai token idempotensi dalam payload permintaan (misalnya, di kolomargumentsaat memulai eksekusi Workflows).Wajibkan autentikasi pada proxy (misalnya, deploy dengan
--no-allow-unauthenticated) dan konfigurasikan tugas Cloud Scheduler untuk melakukan autentikasi dengan token OIDC. Jalankan proxy di akun layanan khusus dengan peran Identity and Access Management (IAM) minimum yang diperlukan (sepertiroles/workflows.invokerpada alur kerja target danroles/datastore.useruntuk data penghapusan duplikat).Terapkan idempotensi di layanan downstream: Gunakan token idempotensi untuk melakukan pemeriksaan atomik atau transaksional di datastore seperti Firestore sebelum menjalankan langkah-langkah yang mengubah status. Teruskan token ke endpoint HTTP downstream atau fungsi Cloud Run yang dipanggil oleh layanan Anda, sehingga target tersebut juga dapat menghapus duplikat percobaan ulang. Untuk contoh end-to-end yang menggunakan Workflows, transaksi Firestore, dan Cloud Run Functions, lihat postingan blog Google Cloud, Melakukan panggilan API tepat satu kali saat menggunakan Workflows.