Gesaan dan skop
Titik akhir Node melakukan beberapa panggilan luaran dan biasanya mengambil masa 5–35 saat. Node membenarkan 60 saat, manakala NGINX mengekalkan proxy_read_timeout lalainya. Pengguna pengeluaran kadangkala melihat 502; log aplikasi kemudiannya menyatakan penulisan perniagaan telah selesai. Di bawah bebanan, sambungan yang berjangka hayat panjang juga menggunakan kolam sambungan.
Lukis garis masa untuk klien, NGINX, Node, kebergantungan hiliran dan storan tugas. Terangkan punca 502, sebab kerja boleh selesai selepas klien melihat kegagalan, dan bila masa untuk menggunakan respons segerak, penstriman atau barisan gilir tak segerak. Nombor-nombor ini adalah andaian temu duga; kemahiran teras ialah semantik tamat masa rentas lapisan, pembatalan, sempadan kesan sampingan, pengasingan dan bukti pembetulan, jadi ini adalah soalan backend.
Perkara yang dinilai oleh penemu duga
Calon yang mantap memisahkan penutupan sambungan, tarikh akhir aplikasi dan penyelesaian perniagaan dan bukannya mencuba semula setiap ralat 502. Mereka tahu tamat masa baca NGINX mengukur masa melahu antara bacaan huluan, bukan semestinya keseluruhan respons, dan AbortSignal.timeout() hanya memberitahu operasi yang benar-benar mendengar isyarat tersebut.
Mereka juga menyenaraikan nilai lalai dalam proksi, get laluan, pengimbang beban, SDK dan klien; mengasingkan permintaan HTTP daripada tugas yang panjang apabila sesuai; dan membuktikan bahawa pembaikan tidak mewujudkan penulisan pendua, kebocoran sambungan atau amplifikasi percubaan semula.
Soalan untuk dijelaskan terlebih dahulu
- Adakah 502 dijana oleh NGINX atau dikembalikan oleh Node dan ditulis semula? Bandingkan pengepala, log ralat proksi dan log akses huluan.
- Adakah kesan sampingan perniagaan telah dikomit semasa tamat masa berlaku? Hasil yang tidak diketahui tidak boleh dimainkan semula secara membuta tuli.
- Adakah keputusan mesti dikembalikan dalam permintaan ini? Jika hanya keputusan akhir yang penting, sambungan segerak 35 saat adalah tidak perlu.
- Adakah huluan menghantar bait secara berterusan? Tamat masa melahu baca dan jumlah tarikh akhir permintaan mempunyai maksud yang berbeza dalam situasi tersebut.
- Adakah pembatalan sampai ke pangkalan data, klien HTTP dan SDK luaran? Menutup sambungan pelayar tidak menghentikan setiap operasi.
- Bagaimanakah keserentakan, penggunaan kolam sambungan, kelewatan gelung peristiwa dan kedalaman barisan gilir berubah? Sahkan kekangan utama sebelum menukar nombor.
Jawapan 30 saat
“Saya akan mengaitkan satu ID surih merentasi klien, NGINX, Node, panggilan hiliran dan storan untuk mengenal pasti lapisan mana yang mengeluarkan 502 dan bila. proxy_read_timeout NGINX mengehadkan masa melahu antara bacaan; tetapan permintaan 60 saat Node tidak menjamin bahawa tugas akan berhenti selepas klien terputus sambungan. Untuk keputusan segerak, saya akan menetapkan satu tarikh akhir hujung-ke-hujung dan meninggalkan margin pembersihan merentasi proksi, aplikasi dan hiliran. Jika tugas melebihi bajet interaksi, simpankannya, kembalikan ID dan biarkan pekerja melaksanakannya. Saya akan menyuntik kegagalan untuk mengesahkan tiada kesan sampingan pendua, kehabisan sambungan atau amplifikasi percubaan semula.”
Penyelesaian langkah demi langkah
Mulakan dengan garis masa. Klien menghantar permintaan, NGINX memajukannya dan Node memulakan kerja. Jika Node tidak menghantar bait respons untuk masa yang cukup lama, pemasa baca NGINX boleh tamat dan menutup sambungan huluan, menghasilkan 502 atau 504. Node mungkin tidak menerima pembatalan pada masa yang sama; ia mungkin telah mengomit penulisan dan kemudian menyelesaikan pengiraan. Oleh itu, kegagalan yang dilihat pengguna dan operasi perniagaan yang selesai boleh wujud bersama.
Kaitkan log akses/ralat NGINX, peristiwa mula/tamat/batal permintaan Node, panggilan hiliran dan komit pangkalan data dengan ID surih, permintaan dan tugas. Bandingkan upstream_response_time, tempoh pengendali, masa penerimaan klien dan masa komit kesan sampingan. Ini membezakan tamat masa melahu proksi, tarikh akhir aplikasi, tamat masa hiliran dan pemutusan sambungan klien. Log "kejayaan" aplikasi sahaja tidak mencukupi.
proxy_read_timeout NGINX secara lalai ialah 60 saat dan mengukur selang melahu paling lama antara dua bacaan; penerimaan bait memulakan semula selang tersebut. Meningkatkannya mengubah toleransi proksi, bukan tarikh akhir klien atau kos sambungan. Jika anda mengubahnya, catatkan had proksi, aplikasi dan klien dalam satu jadual dan simpan masa untuk penghantaran respons, pembersihan dan kegelisahan rangkaian (jitter).
Node boleh mencipta tarikh akhir dengan AbortSignal.timeout() dan menghantar isyarat kepada fetch, pangkalan data atau panggilan SDK yang menyokong pembatalan. Pembatalan adalah secara bekerjasama: perpustakaan yang mengabaikan isyarat boleh terus berjalan. Transaksi yang telah dikomit tidak boleh dihapuskan dengan membatalkannya. Oleh itu, setiap kesan sampingan memerlukan kunci ketakberubahan (idempotency key), mesin keadaan atau laluan pampasan dengan keadaan eksplisit seperti accepted, running, succeeded, failed dan unknown.
Jika p99 tugas jauh melebihi bajet interaksi, wujudkan sempadan tak segerak. API mengesahkan input, menulis rekod tugas atau mesej barisan gilir dan mengembalikan 202 bersama ID tugas. Pekerja memajak tugas tersebut, melaksanakan percubaan semula dan mengekalkan hasilnya; klien meninjau atau melanggan status. Penciptaan dan penyiapan tugas mestilah idempoten, permulaan semula pekerja mesti boleh dipulihkan dan penghantaran pendua tidak boleh menduplikasi pembayaran atau penciptaan sumber. Barisan gilir menambah storan, pekerja dan operasi surat mati (dead-letter) yang memerlukan kapasiti dan amaran.
Penstriman hanya sesuai apabila hasil boleh dihasilkan dengan selamat dalam bentuk pecahan (chunks), setiap perantara menyokong respons jangka hayat panjang dan jumlah tempoh dihadkan. Denyutan jantung (heartbeats) tidak menggantikan jumlah tarikh akhir, had output atau laluan pembatalan. Jangan gunakan penstriman untuk menyembunyikan kerja yang tidak terikat.
Sahkan pembaikan dengan menetapkan tamat masa melahu proksi yang diketahui dan menyuntik kesenyapan hiliran melebihi masa tersebut; putuskan sambungan klien pada fasa yang berbeza; mulakan semula pekerja; dan jalankan ujian keserentakan. Pastikan paling banyak satu kesan sampingan yang berjaya bagi setiap tugas logik, tiada percubaan semula melebihi tarikh akhir, penggunaan sambungan dan barisan gilir yang terhad, serta surihan yang membina semula cap masa setiap lapisan.
Jawapan model
“Saya tidak akan bermula dengan menukar 30 saat kepada lima minit. Mula-mula saya akan mengaitkan cap masa NGINX, Node, hiliran dan pangkalan data untuk menentukan sama ada proksi yang menjana 502 atau Node yang mengembalikannya. proxy_read_timeout ialah selang melahu antara bacaan, manakala tarikh akhir permintaan Node dan penyiapan perniagaan adalah peristiwa yang berasingan; proksi boleh menutup sambungan sementara Node terus berjalan dan mengomit kesan sampingan.
Untuk keputusan segerak, saya akan menentukan satu tarikh akhir hujung-ke-hujung, menyebarkan baki bajet ke hiliran, menggunakan AbortSignal.timeout() dan mengesahkan bahawa setiap SDK mematuhi pembatalan. Hasil penulisan yang tidak diketahui memerlukan kunci idempoten dan carian status. Jika p99 tugas melebihi bajet interaksi, API harus mengekalkan tugas dan mengembalikan 202 dengan ID; pekerja melaksanakan, mencuba semula dan mengekalkan status. Saya akan menyuntik tamat masa melahu proksi, pemutusan sambungan klien, permulaan semula pekerja dan penghantaran pendua, kemudian memeriksa ketiadaan kesan sampingan pendua, penggunaan sambungan yang terhad dan surihan yang lengkap.”
Kesilapan lazim
- Hanya meningkatkan tamat masa NGINX → sambungan panjang dan tekanan keserentakan kekal → tentukan tarikh akhir perniagaan dan sempadan tak segerak.
- Mencuba semula setiap 502 → tugas asal mungkin telah dikomit → tanya status dan guna semula kunci idempoten.
- Menganggap
proxy_read_timeoutsebagai jumlah masa respons → pecahan kecil yang berterusan boleh memastikan permintaan terus hidup selama-lamanya → tambah jumlah tarikh akhir dan had output. - Andaian bahawa penutupan klien menghentikan Node → banyak perpustakaan mengabaikan pembatalan → sahkan tingkah laku henti paksa (abort), sambungan dan transaksi bagi setiap lapisan.
- Menggunakan denyutan jantung untuk menyembunyikan tugas yang tidak terhad → sumber masih bocor → hadkan jumlah masa, bait dan keserentakan.
- Menjalankan tugas 35 saat dalam pengendali segerak → sambungan HTTP menanggung semua kerja → simpan tugas dan gunakan pekerja.
- Hanya melihat log Node → ralat dan pemasaan proksi hilang → kumpulkan akses/ralat proksi dan pemasaan huluan.
- Menambah barisan gilir tanpa keadaan idempoten → penghantaran pendua menyebabkan caj pendua → gunakan kunci tugas yang unik dan kemas kini keadaan bersyarat.
Soalan susulan dan jawapan
Soalan susulan 1: Adakah menukar proxy_read_timeout kepada 60 saat mencukupi?
Tidak. Ia hanya mengawal masa melahu antara bacaan; lapisan lain mungkin mempunyai tarikh akhir yang lebih pendek dan sambungan masih menggunakan sumber. Tentukan bajet interaksi terlebih dahulu, kemudian selaraskan setiap lapisan.
Soalan susulan 2: Bagaimanakah Node berhenti selepas klien terputus sambungan?
Perhatikan peristiwa penutupan permintaan, batalkan pengawal dan hantar isyaratnya kepada operasi yang boleh dibatalkan. Untuk panggilan yang tidak boleh dibatalkan, asingkan kapasiti dan buang hasil yang lewat dengan selamat. Kesan sampingan yang telah dikomit masih memerlukan sifat idempoten dan penyelarasan.
Soalan susulan 3: Bilakah penstriman sesuai?
Apabila hasil boleh dipecahkan dengan selamat, semua perantara menyokong respons jangka hayat panjang dan jumlah tempoh dihadkan. Kekalkan selang denyutan jantung, jumlah tarikh akhir, had output dan laluan pembatalan.
Soalan susulan 4: Bagaimanakah barisan gilir mengelakkan pelaksanaan pendua?
Hasilkan satu kunci tugas daripada permintaan perniagaan dan kuat kuasakan keunikan dalam storan. Pekerja menggunakan pajakan, penyiapan menggunakan kemas kini bersyarat dan kesan sampingan luaran menggunakan semula kunci idempoten yang sama.
Soalan susulan 5: Bagaimanakah anda membuktikan pembaikan itu berkesan?
Suntik tamat masa melahu proksi, respons hiliran yang perlahan, pemutusan sambungan klien, penetapan semula rangkaian dan permulaan semula pekerja dalam persekitaran pementasan (staging). Bandingkan cap masa lapisan dan periksa sumber ralat, penggunaan sambungan, kesan pendua dan kelewatan barisan gilir.
Soalan susulan 6: Mengapa log aplikasi boleh menyatakan kejayaan sedangkan pengguna mendapat 502?
Proksi mungkin telah menutup sambungan terlebih dahulu, atau respons mungkin hilang kemudian. Log penyiapan membuktikan kod telah selesai, bukan respons telah dihantar. Kaitkan status proksi, hasil penulisan Node dan pemerhatian klien.
Soalan susulan 7: Apakah kos pelaksanaan tak segerak?
Ia menambah storan keadaan, pekerja, percubaan semula, surat mati dan ketekalan akhirnya (eventual consistency). Sebagai ganti, jangka hayat HTTP diasingkan daripada tempoh tugas manakala keserentakan dan main semula boleh dikawal secara bebas.