Topik wawancara representatif

Wawancara Backend: Mengapa ketidakcocokan batas waktu Node dan NGINX dapat mengembalikan kesalahan saat pekerjaan selesai?

BackendSedang
Tim Redaksi Offer.ccDipublikasikan Diperbarui

Pertanyaan

Layanan Node berada di belakang proksi terbalik NGINX. Titik akhir terkadang mengembalikan 502, tetapi log aplikasi menunjukkan pekerjaan selesai beberapa detik kemudian. Bagaimana Anda menemukan lapisan batas waktu dan memilih antara mengubah batas waktu, melakukan streaming respons, atau memindahkan pekerjaan ke antrean?

Perintah dan cakupan

Sebuah titik akhir Node melakukan beberapa panggilan eksternal dan biasanya membutuhkan waktu 5–35 detik. Node mengizinkan 60 detik, sementara NGINX mempertahankan proxy_read_timeout default-nya. Pengguna produksi terkadang melihat 502; log aplikasi kemudian menyatakan penulisan bisnis telah selesai. Di bawah beban kerja, koneksi yang berumur panjang juga menghabiskan pool.

Gambarkan garis waktu untuk klien, NGINX, Node, dependensi hilir, dan penyimpanan pekerjaan. Jelaskan sumber dari 502, mengapa pekerjaan dapat selesai setelah klien melihat kegagalan, dan kapan harus menggunakan respons sinkron, streaming, atau antrean asinkron. Angka-angka ini adalah asumsi wawancara; keterampilan intinya adalah semantik batas waktu lintas lapisan, pembatalan, batas efek samping, isolasi, dan bukti perbaikan, jadi ini adalah pertanyaan backend.

Yang dievaluasi pewawancara

Kandidat yang kuat memisahkan penutupan koneksi, tenggat waktu aplikasi, dan penyelesaian bisnis alih-alih mencoba kembali setiap 502. Mereka tahu batas waktu baca NGINX mengukur waktu idle antara pembacaan hulu, belum tentu keseluruhan respons, dan bahwa AbortSignal.timeout() hanya memberi tahu operasi yang benar-benar mendengarkan sinyal tersebut.

Mereka juga mendata nilai default di proksi, gateway, penyeimbang beban, SDK, dan klien; memisahkan permintaan HTTP dari pekerjaan panjang jika sesuai; dan membuktikan bahwa perbaikan tidak menciptakan penulisan ganda, kebocoran koneksi, atau amplifikasi percobaan ulang.

Pertanyaan untuk diklarifikasi terlebih dahulu

  • Apakah 502 dihasilkan oleh NGINX atau dikembalikan oleh Node dan ditulis ulang? Bandingkan header, log kesalahan proksi, dan log akses hulu.
  • Apakah efek samping bisnis sudah di-commit saat batas waktu terjadi? Hasil yang tidak diketahui tidak dapat diulang secara membabi buta.
  • Haruskah hasilnya dikembalikan dalam permintaan ini? Jika hanya hasil akhir yang penting, koneksi sinkron 35 detik tidak diperlukan.
  • Apakah hulu mengirimkan byte secara terus-menerus? Batas waktu idle baca dan total tenggat waktu permintaan memiliki arti yang berbeda dalam kasus tersebut.
  • Apakah pembatalan mencapai basis data, klien HTTP, dan SDK eksternal? Menutup koneksi peramban tidak menghentikan setiap operasi.
  • Bagaimana perubahan konkurensi, penggunaan pool koneksi, penundaan event-loop, dan kedalaman antrean? Konfirmasikan hambatan utama sebelum mengubah angka.

Jawaban 30 detik

“Saya akan mengorelasikan satu ID jejak di seluruh klien, NGINX, Node, panggilan hilir, dan penyimpanan untuk mengidentifikasi lapisan mana yang mengeluarkan 502 dan kapan. proxy_read_timeout NGINX membatasi waktu idle antar pembacaan; pengaturan permintaan 60 detik Node tidak menjamin bahwa pekerjaan berhenti setelah klien terputus. Untuk hasil sinkron, saya akan menentukan satu batas waktu menyeluruh dan menyisakan margin pembersihan di seluruh proksi, aplikasi, dan hilir. Jika pekerjaan melebihi anggaran interaksi, simpan pekerjaan tersebut, kembalikan sebuah ID, dan biarkan pekerja mengeksekusinya. Saya akan menyuntikkan kegagalan untuk memverifikasi tidak ada efek samping ganda, kehabisan koneksi, atau amplifikasi percobaan ulang.”

Solusi langkah demi langkah

Mulailah dengan garis waktu. Klien mengirimkan permintaan, NGINX meneruskannya, dan Node mulai bekerja. Jika Node tidak mengirimkan byte respons cukup lama, pengatur waktu baca NGINX dapat kedaluwarsa dan menutup koneksi hulu, menghasilkan 502 atau 504. Node mungkin tidak menerima pembatalan pada saat yang sama; Node mungkin telah melakukan penulisan commit lalu menyelesaikan komputasi. Oleh karena itu, kegagalan yang terlihat oleh pengguna dan operasi bisnis yang selesai dapat terjadi secara bersamaan.

Korelasikan log akses/kesalahan NGINX, peristiwa mulai/selesai/pembatalan permintaan Node, panggilan hilir, dan commit basis data dengan ID jejak, permintaan, dan pekerjaan. Bandingkan upstream_response_time, durasi pengendali, waktu penerimaan klien, dan waktu commit efek samping. Ini membedakan batas waktu idle proksi, batas waktu aplikasi, batas waktu hilir, dan pemutusan klien. Log "sukses" aplikasi saja tidak cukup.

proxy_read_timeout NGINX secara default adalah 60 detik dan mengukur interval idle terpanjang antara dua pembacaan; menerima byte akan memulai ulang interval tersebut. Meningkatkannya akan mengubah toleransi proksi, bukan tenggat waktu klien atau biaya koneksi. Jika Anda mengubahnya, catat batas proksi, aplikasi, dan klien dalam satu tabel dan pesan waktu untuk transmisi respons, pembersihan, dan jitter jaringan.

Node dapat membuat tenggat waktu dengan AbortSignal.timeout() dan meneruskan sinyal ke fetch, basis data, atau panggilan SDK yang mendukung pembatalan. Pembatalan bersifat kooperatif: pustaka yang mengabaikan sinyal tersebut dapat terus berjalan. Transaksi yang sudah di-commit tidak dapat ditiadakan dengan membatalkannya. Oleh karena itu, setiap efek samping memerlukan kunci idempoten, mesin status, atau jalur kompensasi dengan status eksplisit seperti accepted, running, succeeded, failed, dan unknown.

Jika p99 pekerjaan jauh melampaui anggaran interaksi, buat batas asinkron. API memvalidasi input, menulis catatan pekerjaan atau pesan antrean, dan mengembalikan 202 beserta ID pekerjaan. Seorang pekerja menyewa pekerjaan tersebut, mengeksekusi percobaan ulang, dan menyimpan hasilnya; klien melakukan polling atau berlangganan status. Pembuatan dan penyelesaian pekerjaan harus bersifat idempoten, mulai ulang pekerja harus dapat dipulihkan, dan pengiriman duplikat tidak boleh menduplikasi pembayaran atau pembuatan sumber daya. Antrean menambahkan penyimpanan, pekerja, dan operasi dead-letter yang memerlukan kapasitas dan peringatan.

Streaming hanya sesuai jika hasil dapat diproduksi secara aman dalam bentuk potongan (chunk), setiap perantara mendukung respons berumur panjang, dan total durasi dibatasi. Heartbeat tidak menggantikan tenggat waktu total, batas output, atau jalur pembatalan. Jangan gunakan streaming untuk menyembunyikan pekerjaan yang tidak terbatas.

Verifikasi perbaikan dengan menetapkan batas waktu idle proksi yang diketahui dan menyuntikkan keheningan hilir melampaui batas tersebut; putuskan koneksi klien pada fase yang berbeda; mulai ulang pekerja; dan jalankan pengujian konkurensi. Pastikan paling banyak satu efek samping yang berhasil per pekerjaan logis, tidak ada percobaan ulang di luar tenggat waktu, penggunaan koneksi dan antrean yang dibatasi, serta jejak yang merekonstruksi stempel waktu setiap lapisan.

Jawaban model

“Saya tidak akan memulai dengan mengubah 30 detik menjadi lima menit. Pertama, saya akan mengorelasikan stempel waktu NGINX, Node, hilir, dan basis data untuk menentukan apakah proksi yang menghasilkan 502 atau Node yang mengembalikannya. proxy_read_timeout adalah interval idle antar pembacaan, sedangkan tenggat waktu permintaan Node dan penyelesaian bisnis adalah peristiwa yang terpisah; proksi dapat menutup koneksi sementara Node terus berjalan dan melakukan commit efek samping.

Untuk hasil sinkron, saya akan menentukan satu tenggat waktu menyeluruh, menyebarkan sisa anggaran ke hilir, menggunakan AbortSignal.timeout(), dan memverifikasi bahwa setiap SDK mematuhi pembatalan. Hasil penulisan yang tidak diketahui memerlukan kunci idempoten dan pencarian status. Jika p99 pekerjaan melebihi anggaran interaksi, API harus menyimpan pekerjaan dan mengembalikan 202 dengan sebuah ID; pekerja mengeksekusi, mencoba kembali, dan menyimpan status. Saya akan menyuntikkan batas waktu idle proksi, pemutusan klien, mulai ulang pekerja, dan pengiriman duplikat, lalu memeriksa tidak adanya efek samping ganda, penggunaan koneksi yang dibatasi, dan jejak yang lengkap.”

Kesalahan umum

  • Hanya meningkatkan batas waktu NGINX → koneksi lama dan tekanan konkurensi tetap ada → tentukan tenggat waktu bisnis dan batas asinkron.
  • Mencoba kembali setiap 502 → pekerjaan asli mungkin telah di-commit → kueri status dan gunakan kembali kunci idempoten.
  • Memperlakukan proxy_read_timeout sebagai total waktu respons → potongan kecil yang terus menerus dapat membuat permintaan tetap hidup tanpa batas waktu → tambahkan total batas waktu dan batas output.
  • Mengasumsikan penutupan klien menghentikan Node → banyak pustaka mengabaikan pembatalan → verifikasi perilaku abort, koneksi, dan transaksi per lapisan.
  • Menggunakan heartbeat untuk menyembunyikan pekerjaan yang tidak terbatas → sumber daya masih bocor → batasi total waktu, byte, dan konkurensi.
  • Menjalankan pekerjaan 35 detik dalam pengendali sinkron → koneksi HTTP menanggung semua pekerjaan → simpan pekerjaan dan gunakan pekerja.
  • Hanya melihat log Node → kesalahan dan waktu proksi menghilang → kumpulkan log akses/kesalahan proksi dan waktu hulu.
  • Menambahkan antrean tanpa status idempoten → pengiriman duplikat menyebabkan tagihan ganda → gunakan kunci pekerjaan unik dan pembaruan status bersyarat.

Pertanyaan lanjutan dan tanggapan

Pertanyaan lanjutan 1: Apakah mengubah proxy_read_timeout menjadi 60 detik sudah cukup?

Tidak. Ini hanya mengontrol waktu idle antar pembacaan; lapisan lain mungkin memiliki batas waktu yang lebih pendek, dan koneksi masih menghabiskan sumber daya. Tentukan anggaran interaksi terlebih dahulu, lalu selaraskan setiap lapisan.

Pertanyaan lanjutan 2: Bagaimana Node berhenti setelah klien terputus?

Amati peristiwa penutupan permintaan, batalkan pengontrol, dan teruskan sinyalnya ke operasi yang dapat dibatalkan. Untuk panggilan yang tidak dapat dibatalkan, isolasi kapasitas dan buang hasil yang terlambat dengan aman. Efek samping yang telah di-commit masih memerlukan idempotensi dan rekonsiliasi.

Pertanyaan lanjutan 3: Kapan streaming tepat digunakan?

Ketika hasil dapat dipecah dengan aman, semua perantara mendukung respons berumur panjang, dan total durasi dibatasi. Pertahankan interval heartbeat, total tenggat waktu, batas output, dan jalur pembatalan.

Pertanyaan lanjutan 4: Bagaimana antrean menghindari eksekusi ganda?

Dapatkan satu kunci pekerjaan dari permintaan bisnis dan tegakkan keunikan di penyimpanan. Pekerja menggunakan sewa (lease), penyelesaian menggunakan pembaruan bersyarat, dan efek samping eksternal menggunakan kembali kunci idempoten yang sama.

Pertanyaan lanjutan 5: Bagaimana Anda membuktikan bahwa perbaikan tersebut berhasil?

Suntikkan batas waktu idle proksi, respons hilir yang lambat, pemutusan klien, reset jaringan, dan mulai ulang pekerja di lingkungan staging. Bandingkan stempel waktu lapisan dan periksa sumber kesalahan, penggunaan koneksi, efek duplikat, dan penundaan antrean.

Pertanyaan lanjutan 6: Mengapa log aplikasi dapat menyatakan sukses sementara pengguna mendapatkan 502?

Proksi mungkin telah menutup koneksi terlebih dahulu, atau responsnya hilang kemudian. Log penyelesaian membuktikan kode telah selesai, bukan bahwa respons telah terkirim. Korelasikan status proksi, hasil penulisan Node, dan pengamatan klien.

Pertanyaan lanjutan 7: Berapa biaya eksekusi asinkron?

Ini menambahkan penyimpanan status, pekerja, percobaan ulang, antrean pesan gagal (dead letter), dan konsistensi akhir. Sebagai imbalannya, masa pakai HTTP dipisahkan dari durasi pekerjaan serta konkurensi dan pemutaran ulang dapat dikontrol secara independen.

Sumber publik

Pertanyaan terkait