Topik temu duga representatif

Temu Duga Backend: Bagaimanakah Anda Menyebarkan Deadline dan Pembatalan gRPC?

BackendSukar
Pasukan Editorial Offer.ccDiterbitkan Dikemas kini

Soalan

Satu permintaan API memanggil tiga perkhidmatan gRPC secara berurutan, dan pengguna mungkin keluar di pertengahan jalan. Reka bentuk tingkah laku deadline, pembatalan, percubaan semula dan pembersihan pelayan. Terangkan cara panggilan anak kekal dalam belanjawan induk, cara RPC penstriman tamat, dan cara operasi tulis mengesahkan keputusannya selepas pembatalan.

Gesaan dan konteks

Satu permintaan API memanggil perkhidmatan gRPC pengguna, katalog dan cadangan secara berurutan. Pengguna mungkin menavigasi keluar semasa panggilan cadangan sedang perlahan. Sistem mesti mengehadkan kependaman hujung ke hujung, melepaskan sumber pelayan, mengelakkan amplifikasi percubaan semula dan memastikan operasi tulis boleh ditanya apabila pembatalan berlaku selepas kesan sampingan luaran.

Panduan gRPC mentakrifkan deadline sebagai batas atas masa menunggu pelanggan dan menerangkan DEADLINE_EXCEEDED; pembatalan menamatkan RPC yang tidak diperlukan lagi. Jawapan yang mantap memisahkan penyebaran belanjawan, had percubaan semula, pembersihan strim dan hasil yang tidak diketahui daripada menetapkan tamat masa (timeout) lima saat yang bebas pada setiap lapisan.

Perkara yang dinilai oleh penemu duga

Cari deadline mutlak atau baki belanjawan, penyebaran ke dalam RPC anak dan pangkalan data, percubaan semula yang menggunakan jumlah belanjawan yang sama, dan keengganan untuk membuat kesimpulan bahawa "tiada respons" bermaksud "operasi tulis tidak berlaku." Calon juga harus menamakan medan yang boleh diperhatikan dan pelan ujian suntikan kegagalan.

Soalan penjelasan

  • Apakah SLO peringkat teratas, deadline pelanggan dan dasar hasil separa?
  • Adakah ketiga-tiga panggilan tersebut baca sahaja, atau adakah ia termasuk pembayaran dan kesan sampingan yang lain?
  • Status manakah yang boleh dicuba semula, dan adakah terdapat kunci keidempotennan?
  • Bolehkah mesej strim dimainkan semula, dan adakah terdapat kursor atau nombor jujukan?
  • Adakah pangkalan data dan API luaran menerima pembatalan?
  • Selepas pembatalan, adakah kontrak tersebut merupakan carian status, pampasan atau penyesuaian?

Jawapan 30 saat

"Cipta satu deadline mutlak di pinggir (edge); anak hanya mewarisi baki belanjawan. Sebarkan pembatalan kepada setiap RPC, pangkalan data dan pekerja yang boleh dibatalkan. Cuba semula hanya kegagalan sementara yang selamat dengan had percubaan, backoff, jitter dan jumlah deadline yang sama. Operasi tulis menggunakan ID operasi atau carian status, bukan percubaan semula buta yang baharu. Panggilan penstriman menutup lelaran dan sambungan, serta log merekodkan baki belanjawan, sebab pembatalan, percubaan dan status akhir."

Penyelesaian langkah demi langkah

Langkah 1: Tentukan belanjawan masa hujung ke hujung

Anggap deadline pelanggan sebagai batas atas. Setiap perkhidmatan mengira remaining = deadline - now, menetapkan deadline anak tidak lewat daripada titik tersebut, dan memperuntukkan masa untuk giliran, penyirikan dan pengendalian respons.

text
parent_deadline = 2.0s from request start
child_deadline = min(parent_deadline, now + remaining_budget)

Jangan berikan setiap lapisan tambahan dua saat: rantaian tiga lompatan boleh melebihi enam saat. Gunakan jam monotonik secara setempat untuk ukuran giliran dan kerja sementara rangka kerja RPC membawa deadline.

Langkah 2: Sebarkan pembatalan dan hentikan kerja

Navigasi keluar, pembatalan eksplisit dan tamat tempoh deadline mesti sampai ke pengendali pelayan. Salurkan token pembatalan pengendali kepada pangkalan data, pelanggan HTTP, penantian giliran dan lelaran strim. Mengembalikan ralat semasa kerja latar belakang diteruskan adalah kebocoran sumber.

Pembatalan harus melepaskan sambungan, fail sementara dan kunci (locks); berhenti menghasilkan mesej baharu; dan merekodkan peringkat yang telah selesai. Ia tidak boleh membatalkan transaksi yang telah dikomit, jadi carian status atau pampasan kemudian diperlukan.

Langkah 3: Cuba semula dalam baki belanjawan

Cuba semula hanya ralat sementara yang eksplisit seperti UNAVAILABLE, dengan percubaan maksimum, backoff eksponen dan jitter. Setiap percubaan menggunakan deadline yang sama; tamat tempoh akan melangkau baki percubaan semula.

text
for attempt in 1..maxAttempts:
  if remaining(deadline) <= backoff: stop
  result = call(child, deadline, cancellation)
  if result is success or permanent_error: return result
  sleep(jittered_backoff, cancellation)
return DEADLINE_EXCEEDED

Pilih satu pemilik percubaan semula di seluruh rantaian panggilan. Jejaki amplifikasi percubaan semula dan percubaan setiap lapisan supaya proksi dan pelanggan tidak menggandakan kerja.

Langkah 4: Asingkan operasi baca daripada operasi tulis

Operasi baca boleh dicuba semula apabila kontrak membenarkannya. Operasi tulis memerlukan ID operasi, kekangan unik dan carian status. Jika pembatalan berlaku selepas penulisan luaran, pemanggil mempunyai hasil UNKNOWN dan tidak boleh mencipta ID baharu dengan serta-merta.

text
PENDING -> CONFIRMED
       \-> FAILED
       \-> UNKNOWN (reconcile before retry)

Titik akhir status mengembalikan hasil daripada pihak berkuasa (authority). Deadline mengawal masa menunggu; ia tidak mencipta pengembalian semula (rollback) atomik merentas sistem.

Langkah 5: Kendalikan kitaran hayat RPC penstriman

Tetapkan jumlah deadline dan, jika sesuai, tamat masa melahu (idle timeout). Semak pembatalan pada setiap bacaan. Apabila pelanggan keluar, hentikan penjanaan dan tutup kursor pangkalan data atau langganan. Sambung semula dengan kursor atau nombor jujukan dan bukannya memainkan semula kesan sampingan dari awal.

Rekodkan masa mesej terakhir, sebab pembatalan, penyambungan semula dan tunggakan. Semasa penutupan secara tertib (graceful shutdown), biarkan strim aktif selesai dalam baki deadline mereka atau kembalikan status pembatalan yang boleh dikenal pasti.

Langkah 6: Sahkan penyebaran dan had sumber

Uji pembatalan induk, tamat masa setiap anak, kerja pangkalan data yang perlahan, UNAVAILABLE sementara, ralat kekal, gangguan strim, kehilangan respons selepas operasi tulis, percubaan semula pelbagai lapisan dan penutupan pelayan secara tertib. Pastikan anak berhenti sebelum deadline induk, pembatalan tidak meninggalkan kerja latar belakang, dan percubaan kekal dalam belanjawan.

Rekodkan kaedah RPC, ID jejak, baki deadline, percubaan, status, punca pembatalan dan ID operasi tanpa muatan sensitif. Ujian beban mesti memerhatikan sambungan, giliran, amplifikasi percubaan semula, CPU dan kependaman ekor (tail latency) dan bukannya purata kejayaan semata-mata.

Jawapan model

"Saya mencipta deadline mutlak di pinggir dan menyebarkan baki belanjawan kepada ketiga-tiga perkhidmatan. Setiap pengendali menyalurkan pembatalan kepada pangkalan data, panggilan HTTP dan lelaran strimnya serta melepaskan sumber sebelum kembali. Panggilan baca mencuba semula hanya ralat sementara yang selamat, dengan satu jumlah deadline dan jitter terhad."

"Operasi tulis membawa ID operasi; selepas pembatalan saya menandakan hasilnya sebagai UNKNOWN dan menyoal status. Strim menggunakan jumlah deadline, kursor dan dasar penyambungan semula. Saya menyuntik pembatalan induk, tamat masa anak, respons yang hilang dan penutupan tertib, kemudian mengesahkan tiada kebocoran atau amplifikasi percubaan semula."

Kesilapan lazim

  • Menetapkan semula tamat masa penuh pada setiap lapisan → rantaian melebihi SLO pinggir → sebarkan satu deadline mutlak.
  • Kembali daripada pengendali dan menganggapnya dibatalkan → kerja hiliran masih berjalan → sebarkan pembatalan dan lakukan pembersihan.
  • Mencuba semula setiap ralat → beban teramplifikasi → cuba semula mengikut semantik, belanjawan dan had percubaan.
  • Mencipta ID tulis baharu selepas tamat masa → penulisan pertama mungkin telah berjaya → tanya pihak berkuasa atau pampas.
  • Menyambung semula strim dari awal → mesej dan kesan berganda → gunakan kursor, jujukan dan pengguna idempoten.
  • Hanya merekod log ralat akhir → tiada lapisan yang menerangkan kehabisan belanjawan → rekod log baki deadline dan percubaan bagi setiap lompatan.

Soalan susulan dan respons

Soalan susulan 1: Bolehkah perkhidmatan anak melanjutkan deadline induk?

Tidak. Jika operasi memerlukan masa yang lebih lama, jadikannya tak segerak (asynchronous) dan kembalikan ID operasi. Melanjutkan permintaan segerak secara senyap-senyap akan menggagalkan SLO pinggir.

Soalan susulan 2: Bolehkah pembatalan membatalkan transaksi pangkalan data yang telah dikomit?

Tidak secara boleh dipercayai. Ia menghentikan kerja yang belum dimulakan atau diselesaikan; kerja yang dikomit memerlukan carian status, pampasan atau penyesuaian. API mesti mendedahkan keadaan yang boleh diperhatikan.

Soalan susulan 3: Bagaimanakah anda menghalang percubaan semula berganda?

Tetapkan satu pemilik percubaan semula dan biarkan lapisan lain menyebarkan ralat. Kongsi medan percubaan dan jumlah belanjawan, hadkan percubaan, dan pantau amplifikasi pada setiap lapisan.

Soalan susulan 4: Patutkah strim yang melahu sentiasa dibatalkan?

Bezakan strim jangka panjang yang disengajakan daripada strim yang ditinggalkan. Gunakan jumlah deadline, tamat masa melahu atau denyutan jantung (heartbeat) dan kembalikan keadaan yang boleh disambung semula dan bukannya memegang sumber selama-lamanya.

Soalan susulan 5: Bagaimana jika pelayan terus mengira selepas deadline tamat?

Jadikan pengendali dan kerja hiliran sedar akan pembatalan (cancellation-aware). Pindahkan kerja yang tidak boleh dibatalkan ke dalam giliran latar belakang terhad dengan ID operasi dan had sumber, dan bukannya membiarkan bebenang (thread) permintaan terus digunakan.

Sumber awam

Soalan berkaitan