Prompt dan Peranan yang Berkenaan
Satu perkhidmatan API Linux berjalan di bawah trafik yang stabil selama beberapa jam, kemudian mula menolak sambungan baharu. Panggilan ke perkhidmatan huluan dan percubaan untuk membuka fail log juga mula gagal. Anda mengetahui bahawa:
- proses perkhidmatan mempunyai
RLIMIT_NOFILElembut sebanyak 8,192 dan had keras sebanyak 65,536; - ia bermula dengan kira-kira 400 file descriptor yang terbuka, kemudian meningkat kira-kira 25 setiap minit;
- sejurus sebelum insiden tersebut,
/proc/<pid>/fdmengandungi hampir 8,192 entri dan log mengandungiEMFILE: Too many open files; - memulakan semula proses memulihkan perkhidmatan serta-merta, tetapi peningkatan itu berulang;
/proc/sys/fs/file-nrhos kekal jauh di bawah/proc/sys/fs/file-max.
Terangkan hubungan antara file descriptor, jadual file descriptor proses, dan perihalan fail terbuka (open file description). Terangkan sebab fail biasa, soket, paip, dan epoll semuanya menggunakan deskriptor, serta bezakan EMFILE daripada ENFILE. Kemudian berikan urutan diagnostik yang selamat untuk produksi, putuskan sama ada ini adalah kebocoran FD atau keserentakan sah yang melebihi kapasiti, cadangkan mitigasi dan pembaikan yang tahan lama, serta terangkan cara anda membuktikan bahawa insiden itu telah diselesaikan.
Soalan ini sesuai untuk temu duga bahagian belakang (backend), SRE, infrastruktur, sistem, dan kejuruteraan perisian am. Nilai 8,192, 65,536, 400, dan 25 setiap minit adalah input temu duga hipotesis, bukan cadangan sejagat. Jawapan sebenar juga mesti mengambil kira pengurus perkhidmatan, masa jalanan kontena (container runtime), kebenaran proses, dan model keserentakan aplikasi.
Perkara yang Diuji oleh Penemu Duga
Pertama, bolehkah calon menerangkan bahawa file descriptor ialah indeks integer kecil di dalam sesuatu proses, bukan nama laluan (pathname), inode, atau objek kernel itu sendiri? Jawapan yang kukuh melakar rantaian “jadual FD proses → perihalan fail terbuka → fail, soket, paip, atau objek lain” dan mengetahui bahawa deskriptor yang dicipta oleh dup atau diwarisi melalui fork boleh merujuk kepada perihalan fail terbuka yang sama.
Kedua, bolehkah calon membezakan skop had? EMFILE bermaksud proses semasa telah mencapai RLIMIT_NOFILE; ENFILE bermaksud had fail terbuka di seluruh sistem telah dicapai. fs.file-max secara bersendirian mahupun ulimit -n dalam shell yang tidak berkaitan tidak membuktikan had berkesan bagi proses yang gagal tersebut.
Ketiga, adakah diagnosis merangkumi bilangan, komposisi, dan trend? Satu snapshot lsof hanya menunjukkan satu ketika. Untuk membuktikan kebocoran, persampelan jumlah dan jenis objek di bawah trafik yang stabil diperlukan, kemudian mengaitkan peningkatan tersebut dengan kolam sambungan (connection pools), kitaran hayat permintaan, penggiliran log, proses anak, dan laluan kegagalan.
Keempat, bolehkah calon memisahkan kapasiti sementara daripada pembetulan punca utama? Menaikkan had mungkin mewujudkan ruang masa untuk tindak balas insiden atau menjadi sebahagian daripada perancangan kapasiti yang sah, tetapi ia tidak menutup sumber yang pemilikannya telah hilang. Kecerunan positif yang tetap akhirnya akan menggunakan had yang lebih besar itu juga.
Akhir sekali, adakah terdapat gelung pengesahan? “Ralat telah berhenti” adalah tidak mencukupi. Jawapan yang kukuh mengesahkan penggunaan dan kecerunan FD, jenis objek, ralat permintaan, kependaman ekor (tail latency), keadaan kolam (pool state), dan peristiwa kitaran hayat yang berulang di bawah trafik puncak sasaran dan kegagalan yang disuntik.
Soalan untuk Dijelaskan Sebelum Menjawab
- Apakah errno yang tepat? Sahkan
EMFILEatauENFILEdaripada ralat aplikasi atau panggilan sistem dan bukannya membuat kesimpulan skop daripada mesej yang boleh dibaca manusia. - PID manakah yang gagal? Penyelia (supervisor), pekerja (worker), sidecar, dan anak yang berhayat pendek boleh mewarisi had yang berbeza dan memegang sumber yang berbeza.
- Apakah yang melancarkan perkhidmatan tersebut? Shell interaktif, systemd, masa jalanan kontena, dan pengurus proses mungkin menetapkan had lembut dan had keras yang berbeza. Perintah shell tidak boleh mengubah perkhidmatan yang sedang berjalan secara retroaktif.
- Apakah yang bergerak seiring dengan peningkatan FD? Selaraskannya dengan sambungan serentak, permintaan huluan, kedalaman giliran, penggiliran log, muat semula, bilangan anak, dan kadar ralat.
- Jenis objek manakah yang meningkat? Soket, fail biasa, paip,
anon_inode:[eventpoll], objek inotify, dan fail yang dipadamkan merujuk kepada laluan pemilikan yang berbeza. - Apakah model kapasiti yang sah? Proksi keserentakan tinggi mungkin secara sah memerlukan banyak soket. Bilangan yang besar tidak secara automatik bermaksud kebocoran; ia mesti sepadan dengan keserentakan yang dikonfigurasikan dan mendatar apabila beban berkurang.
- Bolehkah
/procdiperiksa dengan selamat? Membaca deskriptor pengguna lain mungkin dihadkan oleh kebenaran dan peraturan ptrace. Siasatan produksi harus menggunakan keistimewaan minimum yang diperlukan dan mengelakkan pengesanan (tracing) jangka panjang dengan overhed yang tinggi.
Jawapan 30 Saat
“File descriptor ialah indeks integer bukan negatif dalam jadual FD sesuatu proses. Entri jadual merujuk kepada perihalan fail terbuka (open file description) di seluruh sistem, yang menyimpan ofset fail dan bendera status, kemudian menunjuk ke fail biasa, soket, paip, atau objek I/O kernel yang lain. EMFILE bermaksud proses ini mencapai RLIMIT_NOFILE; ENFILE bermaksud hos mencapai had fail terbuka di seluruh sistemnya.
Saya akan mengesahkan PID dan errno yang gagal, membaca /proc/<pid>/limits, mengira dan mengklasifikasikan /proc/<pid>/fd, mengambil sampel kategori mengikut masa, dan menyemak /proc/sys/fs/file-nr. Kecerunan positif yang tetap di bawah trafik yang stabil, yang diset semula melalui pemulaan semula dan tertumpu pada satu jenis objek, menunjukkan kebocoran. Bilangan yang menjejaki keserentakan, mencapai paras mendatar yang ditetapkan, dan menurun selepas itu menunjukkan tekanan kapasiti. Saya boleh mengehadkan kadar (rate-limit), melancarkan semula instans secara berperingkat (roll instances), dan menaikkan had perkhidmatan sebenar selepas pengesahan kapasiti, tetapi pembaikan yang tahan lama ialah pemilikan sumber, pembersihan laluan kegagalan, kolam yang terikat (bounded pools), dan pewarisan yang betul. Saya membuktikannya dengan penggunaan dan kecerunan FD, pelepasan objek, dan sifar ralat berkaitan pada beban puncak.”
Selaman Mendalam Langkah demi Langkah
Langkah 1: Bina Model Rujukan Tiga Lapisan
Apabila berjaya, open() mengembalikan integer bukan negatif. Linux biasanya memilih nombor deskriptor terendah yang belum digunakan oleh proses tersebut. Secara konvensyen, 0, 1, dan 2 ialah input standard, output standard, dan ralat standard. Nombor seterusnya masih hanyalah indeks dalam proses tersebut.
Hubungan terasnya ialah:
process FD-table entry → open file description → underlying object
Lapisan tersebut memegang keadaan yang berbeza:
| Lapisan | Perkara yang dipegang | Sifat penting |
|---|---|---|
| Entri jadual FD proses | Nombor deskriptor dan bendera deskriptor seperti close-on-exec | Nombor tersebut hanya bermakna dalam konteks jadual FD proses itu |
| Perihalan fail terbuka (Open file description) | Ofset fail semasa dan bendera status fail terbuka | Objek seluruh sistem yang boleh dikongsi oleh beberapa deskriptor |
| Objek asas | Inode, soket, paip, peranti, atau objek kernel tanpa nama | Menentukan tingkah laku I/O sebenar |
Dua panggilan bebas ke open() pada laluan yang sama biasanya mencipta perihalan fail terbuka yang berasingan. Deskriptor yang dikembalikan oleh dup() merujuk kepada perihalan fail terbuka yang sama, jadi kedua-dua deskriptor berkongsi ofset dan bendera status fail. Selepas fork(), deskriptor induk dan anak yang sepadan juga merujuk kepada perihalan fail terbuka yang sama. Bendera khusus deskriptor seperti close-on-exec adalah berasingan daripada keadaan yang dikongsi itu.
Inilah sebabnya “FD 42” tidak mempunyai makna rentas proses yang stabil dan mengapa pengelompokan mengikut nama laluan sahaja boleh menyembunyikan masalah. Laluan yang sama boleh dibuka secara bebas berkali-kali, manakala nombor deskriptor yang berbeza boleh berkongsi satu keadaan terbuka.
Langkah 2: Fahami Sumber Mana yang Menggunakan Deskriptor
Antara muka gaya Unix mendedahkan banyak sumber I/O melalui deskriptor yang boleh dibaca, boleh ditulis, atau boleh ditunggu:
- fail dan direktori biasa;
- soket TCP, UDP, dan domain Unix;
- paip tanpa nama dan FIFO bernama;
- terminal, peranti, dan beberapa fail pseudo;
- objek kernel tanpa nama seperti
epoll,eventfd,timerfd,signalfd, dan inotify.
/proc/<pid>/fd mengandungi satu pautan simbolik bagi setiap deskriptor yang dibuka dalam proses. Fail biasa biasanya menunjukkan laluan. Soket dan paip biasanya muncul sebagai socket:[inode] dan pipe:[inode]. Objek tanpa inode yang sepadan mungkin muncul sebagai anon_inode:[eventpoll] atau jenis anon_inode yang lain.
Mencipta satu deskriptor epoll untuk gelung peristiwa tidak bermakna ribuan sambungan yang dipantau berhenti menggunakan deskriptor. Setiap soket yang dipantau masih mempunyai FD tersendiri. Sebaliknya, beberapa entri anon_inode:[eventpoll] tidak membuktikan kebocoran gelung peristiwa dengan sendirinya; kenal pasti kategori yang bilangannya benar-benar meningkat.
Langkah 3: Asingkan EMFILE, ENFILE, dan Siling Had
RLIMIT_NOFILE mempunyai had lembut dan had keras. Kernel menguatkuasakan had lembut. Had keras ialah siling yang membolehkan proses tanpa keistimewaan menaikkan had lembut. Linux mentakrifkan nilai tersebut sebagai satu lebih besar daripada nombor deskriptor terbesar yang boleh dibuka oleh proses tersebut.
Sempadan utamanya ialah:
| Isyarat | Maksud | Bukti pertama untuk diperiksa |
|---|---|---|
EMFILE | Proses ini mencapai RLIMIT_NOFILE | /proc/<pid>/limits dan /proc/<pid>/fd |
ENFILE | Hos mencapai had fail terbuka di seluruh sistem | /proc/sys/fs/file-nr, file-max, dan log kernel |
/proc/sys/fs/nr_open | Siling kernel untuk menaikkan RLIMIT_NOFILE | Periksa apabila peningkatan had keras gagal |
Medan pertama dalam /proc/sys/fs/file-nr ialah bilangan pemegang fail yang diperuntukkan; medan ketiga sepadan dengan file-max. Ini ialah kiraan perihalan fail terbuka di seluruh sistem, jadi ia tidak semestinya sama dengan jumlah kiraan FD setiap proses: beberapa deskriptor boleh berkongsi perihalan fail terbuka.
Prompt secara jelas melaporkan EMFILE, manakala penggunaan seluruh sistem kekal jauh di bawah file-max. Oleh itu, laluan utamanya ialah had bagi setiap proses. Mengubah fs.file-max tidak menangani kegagalan ini.
Langkah 4: Kumpulkan Bukti Berisiko Rendah dan Boleh Dibandingkan Terlebih Dahulu
Selepas mengesahkan PID dan kebenaran, mulakan dengan snapshot /proc beroverhed rendah:
pid=12345
grep 'Max open files' /proc/"$pid"/limits
find /proc/"$pid"/fd -maxdepth 1 -type l 2>/dev/null | wc -l
find /proc/"$pid"/fd -maxdepth 1 -type l -exec readlink {} \; 2>/dev/null |
sed -E 's/socket:\[[0-9]+\]/socket:[id]/; s/pipe:\[[0-9]+\]/pipe:[id]/' |
sort | uniq -c | sort -nr | head -20
cat /proc/sys/fs/file-nr
cat /proc/sys/fs/file-max/proc ialah paparan langsung. Proses tersebut mungkin membuka atau menutup deskriptor semasa penjelajahan, dan entri berhayat pendek mungkin hilang. Anggap perintah ini sebagai diagnostik trend, bukan audit atomik. Ambil sampel jumlah dan kategori pada selang masa tetap dengan cap masa, kemudian selaraskannya dengan metrik aplikasi.
Jika soket mendominasi peningkatan tersebut, periksa arah sambungan, destinasi, dan keadaan TCP. Jika fail biasa meningkat, kelompokkan laluan mengikut log, fail sementara, atau muat semula konfigurasi. Jika paip meningkat, periksa proses anak dan kitaran hayat IPC. Jika objek anon_inode meningkat, cari pendaftaran dan pelupusan gelung peristiwa, pemantau (watcher), atau pemasa.
Alat seperti lsof -p <pid>, ss -tanp, atau pengesanan panggilan sistem yang terhad boleh menambah butiran selepas /proc dan metrik aplikasi mengecilkan skop carian. Pengesanan jangka panjang boleh menambah overhed produksi dan mungkin masih tidak lengkap tanpa kebenaran yang mencukupi.
Langkah 5: Gunakan Bilangan, Komposisi, Kecerunan, dan Pemulihan untuk Mengklasifikasikan Masalah
Bilangan semasa yang tinggi sahaja tidak membuktikan kebocoran. Tanya empat soalan:
- Adakah bilangannya sepadan dengan keserentakan yang dijangkakan? Belanjawan merangkumi soket mendengar (listening sockets), sambungan yang diterima, kolam keluar, fail, paip, objek peristiwa, dan ruang keselamatan.
- Adakah komposisinya sepadan dengan seni bina? Jika kolam huluan dihadkan kepada 500 tetapi deskriptor untuk destinasi tersebut mencecah 5,000, siasat laluan pengembalian dan penutupan.
- Adakah kecerunan kekal positif di bawah beban yang stabil? Jika kadar permintaan dan keserentakan adalah mendatar tetapi FD masih meningkat sebanyak 25 setiap minit, bukti kebocoran adalah kukuh.
- Adakah penggunaan kembali ke paras mendatar apabila beban berkurang? Fail berskop permintaan, sambungan pendek, dan paip sementara sepatutnya dilepaskan. Sambungan kolam yang berhayat panjang mungkin kekal, tetapi pada had yang jelas.
Dalam prompt, perkhidmatan bermula sekitar 400, meningkat pada kadar yang tetap, diset semula semasa pemulaan semula, dan berulang. Corak itu sangat menyokong kebocoran. Klasifikasi objek masih diperlukan supaya pemanasan kolam sambungan yang semula jadi tidak disalah anggap sebagai fail yang tidak ditutup.
Kapasiti yang tidak mencukupi biasanya kelihatan berbeza: penggunaan mengikut keserentakan, mencapai paras mendatar berhampiran had kolam dan sambungan yang dikonfigurasikan, dan menurun selepas beban atau tamat masa reda. Gabungan objek sepadan dengan reka bentuk, dan kegagalan muncul hanya apabila permintaan puncak yang sah melebihi belanjawan asal. Menaikkan had, menambah proses, atau mengurangkan kos setiap sambungan kemudiannya boleh menjadi perubahan kapasiti yang tahan lama.
Langkah 6: Jejak Pemilikan Sumber Melalui Laluan Kebocoran Biasa
Jawapan yang kukuh bertanyakan “siapa yang menciptanya, siapa yang memilikinya, dan siapa yang menutupnya selepas kegagalan?” dan bukannya terhenti pada arahan semata-mata. Punca biasa termasuk:
- klien HTTP tidak menutup badan respons, jadi sambungan tidak boleh diguna semula mahupun dilepaskan dengan segera;
- pangkalan data, cache, atau sambungan huluan diambil (checked out) tetapi tidak dikembalikan selepas tamat masa atau pengecualian;
- penggiliran log atau muat semula konfigurasi berulang kali membuka fail baharu tanpa menutup pemegang lama;
- setiap permintaan mencipta pemasa, pemantau, paip, atau objek peristiwa tetapi pembatalan melangkau pembersihan;
- proses induk dan anak membiarkan hujung strim standard atau paip IPC yang tidak digunakan terbuka;
- deskriptor terselamat daripada
execdi luar jangkaan, jadi proses lain mengekalkan sumber tersebut hidup; - logik percubaan semula mencipta sambungan baharu semasa percubaan terdahulu masih tergantung.
Jadikan pemilikan seumur hidup kelihatan dalam struktur kod. Gunakan defer, finally, RAII, atau pengurusan sumber berskop rangka kerja. Wujudkan pembersihan serta-merta selepas pemerolehan. Hadkan kolam, keserentakan, giliran, dan percubaan semula. Salurkan laluan pembatalan, tamat masa, dan pemulangan awal melalui logik pembersihan yang sama.
Dalam program berbilang benang (multithreaded), memanggil open() dan menetapkan FD_CLOEXEC dalam operasi kemudian mewujudkan ruang di mana benang lain boleh fork dan exec. Jika disokong, tetapkan O_CLOEXEC secara atomik semasa penciptaan. Ini menghalang perlumbaan pewarisan (inheritance race); ia tidak menggantikan pemilikan close() biasa.
Langkah 7: Pisahkan Mitigasi Insiden daripada Pembaikan Tahan Lama
Bergantung pada risiko, mitigasi insiden boleh merangkumi:
- mengehadkan kadar kerja baharu atau mengurangkan keserentakan setiap instans sebelum proses kehilangan keupayaan untuk membuka log, sambungan kawalan, dan fail konfigurasi;
- melancarkan semula instans yang bocor secara berperingkat sambil mengekalkan sekurang-kurangnya satu sampel diagnostik dan mengelakkan pemulaan semula serentak;
- menaikkan had lembut dan keras proses perkhidmatan sebenar selepas menyemak memori, overhed kernel, dan kapasiti hiliran;
- menambah instans supaya keserentakan yang sah diagihkan merentasi lebih banyak proses.
Mengubah ulimit -n dalam terminal semasa tidak menjejaskan perkhidmatan yang sedia berjalan. Ubah suai pengurus perkhidmatan, kontena, atau masa jalanan yang sebenarnya mencipta proses tersebut, mulakan semula, dan sahkan /proc/<new-pid>/limits. Penyuntingan fail konfigurasi sahaja bukan bukti bahawa had baharu telah aktif.
Pembaikan yang tahan lama mesti menyasarkan objek yang disahkan meningkat: lengkapkan laluan penutupan, hadkan kolam dan keserentakan, baiki penggiliran atau kitaran hayat pemantau, tetapkan tamat masa yang berguna, cegah pewarisan yang tidak diingini, serta dedahkan kiraan semasa ditambah pembilang cipta/lepas untuk kategori sumber utama.
Langkah 8: Buktikan Pembaikan dengan Belanjawan Kapasiti dan Kecerunan
Cipta belanjawan FD bagi setiap instans:
baseline FDs + peak inbound connections + peak outbound connections + pools and files + IPC/event objects + safety headroom
Belanjawan mesti diperoleh daripada seni bina sebenar dan ujian beban. Tiada peratusan penggunaan sejagat untuk setiap perkhidmatan. Had tersebut juga mesti menyediakan ruang untuk diagnostik, pemeriksaan kesihatan, pengelogan, dan sambungan kawalan semasa insiden.
Pengesahan harus merangkumi sekurang-kurangnya:
- di bawah trafik puncak sasaran dan kegagalan yang disuntik, jumlah penggunaan FD meningkat ke paras mendatar yang stabil;
- selepas beban berkurang dan tamat masa tamat, deskriptor berhayat pendek kembali ke garis dasar yang dijangkakan;
- jenis objek yang sebelum ini meningkat tidak lagi mempunyai kecerunan positif yang berterusan;
EMFILE,ENFILE, kegagalan sambungan, dan kegagalan pembukaan fail kekal pada sifar;- p95/p99 permintaan, masa menunggu kolam, dan jumlah percubaan semula tidak merosot disebabkan oleh had yang terlalu agresif;
- penggunaan (deploy) berulang, penggiliran log, muat semula konfigurasi, dan pelancaran proses anak tidak mewujudkan pertumbuhan bertingkat;
- pemantauan merangkumi
process_open_fds,process_max_fds, penggunaan, kadar pertumbuhan, dan kolam objek utama.
“Ujian beban sepuluh minit telah lulus” mungkin terlepas pandang kebocoran yang perlahan. Jalankan cukup lama untuk merangkumi jumlah pertumbuhan yang menyebabkan insiden asal, atau gandakan laluan yang disyaki dan buktikan bahawa pembilang cipta dan lepas adalah seimbang.
Sampel Jawapan yang Kukuh
“Mula-mula saya akan mengesahkan bahawa errno ialah EMFILE dan bahawa pekerja API itu sendiri yang gagal. File descriptor ialah indeks bukan negatif dalam jadual FD proses. Entri jadual merujuk kepada perihalan fail terbuka di seluruh sistem, yang menyimpan ofset dan bendera status fail, kemudian merujuk kepada fail biasa, soket, paip, atau objek kernel tanpa nama. dup dan fork boleh membuatkan beberapa deskriptor berkongsi satu perihalan fail terbuka, jadi kiraan FD proses dan kiraan pemegang fail di seluruh sistem ialah metrik yang berbeza.
EMFILE bermaksud proses ini mencapai RLIMIT_NOFILE; ENFILE bermaksud hos mencapai file-max. Di sini, had lembut ialah 8,192, kiraan pra-insiden adalah hampir dengan nilai tersebut, dan file-nr adalah jauh di bawah file-max, jadi menukar had seluruh sistem adalah tidak bersasar.
Saya akan membaca /proc/<pid>/limits, kemudian mengambil sampel bilangan dan sasaran pautan simbolik dalam /proc/<pid>/fd, yang dikelompokkan kepada soket, paip, fail biasa, dan objek anon_inode. Saya akan menyelaraskan kecerunan setiap kategori dengan sambungan masuk, kolam huluan, penggiliran fail, proses anak, dan ralat. Bermula hampir 400 dan meningkat sebanyak 25 setiap minit di bawah trafik yang stabil, kemudian diset semula semasa mula semula, sangat mencadangkan kebocoran. Jika soket satu perkhidmatan huluan mendominasi, saya akan memeriksa penutupan badan respons, pembatalan tamat masa, dan laluan pengembalian kolam dan bukannya menganggap setiap sambungan mencerminkan trafik yang sah.
Untuk mitigasi, saya akan mengehadkan kadar dan melancarkan semula instans secara berperingkat sambil mengekalkan sampel diagnostik. Jika analisis kapasiti membenarkan, saya boleh menaikkan had buat sementara waktu dalam pengurus perkhidmatan sebenar atau konfigurasi kontena, tetapi saya mesti mengesahkan /proc/<pid>/limits proses baharu tersebut. Pembaikan yang tahan lama menjadikan pemilikan sumber dan pembersihan bersifat struktur, mengehadkan kolam, percubaan semula, pemasa, dan pemantau, serta menghalang pewarisan yang tidak diingini dengan close-on-exec.
Saya akan mengesahkan di bawah beban puncak sasaran dan laluan kegagalan. Penggunaan FD harus mencapai paras mendatar yang dirancang dan kembali ke arah garis dasar apabila beban berkurang. Kategori yang sebelum ini meningkat mesti berhenti terkumpul, EMFILE mesti kekal pada sifar, serta kependaman ekor dan penantian kolam tidak boleh merosot. Hasil tersebut membuktikan pembaikan; pemulaan semula atau had yang lebih besar hanya membuktikan bahawa kehabisan sumber telah ditangguhkan.”
Kesilapan Biasa
- Menganggap FD sebagai laluan atau inode → ia adalah indeks dalam jadual proses → terangkan jadual FD, perihalan fail terbuka, dan objek asas.
- Menganggap hanya fail cakera yang menggunakan FD → soket, paip,
epoll, pemasa, dan pemantau juga menggunakannya → klasifikasikan sasaran/proc/<pid>/fd. - Mengubah
fs.file-maxuntuk setiap ralat Too many open files →EMFILEdanENFILEmempunyai skop yang berbeza → sahkan errno dan PID yang gagal terlebih dahulu. - Menggunakan
ulimit -nshell semasa sebagai had perkhidmatan → perkhidmatan yang sedang berjalan mungkin telah dilancarkan di tempat lain → baca/proc/<pid>/limits. - Mengisytiharkan kebocoran semata-mata kerana bilangannya tinggi → keserentakan tinggi yang sah boleh mencipta paras mendatar yang tinggi → bandingkan model kapasiti, campuran jenis, kecerunan, dan pemulihan selepas beban.
- Hanya menaikkan 8,192 kepada 65,536 → kecerunan kebocoran yang tetap akan menggunakan had baharu itu juga → anggap peningkatan tersebut sebagai kapasiti yang disahkan atau ruang sementara.
- Hanya menyemak laluan pemulangan biasa → tamat masa, pembatalan, percubaan semula, dan pemulangan awal biasanya melangkau pembersihan → takrifkan pencipta, pemilik, dan pembersihan laluan kegagalan untuk setiap sumber.
- Menggunakan satu snapshot
lsof→ satu snapshot tidak boleh membuktikan pengumpulan → ambil sampel pada selang masa tetap dan kaitkan dengan beban kerja serta kolam. - Menerima kehilangan ralat sementara → pemulaan semula dan had yang lebih tinggi boleh melambatkan perulangan → sahkan jenis objek, kecerunan, pemulihan, dan peristiwa kitaran hayat yang berulang.
Soalan Susulan
Susulan 1: Mengapa ulimit -n menunjukkan 65,536 manakala perkhidmatan masih gagal pada 8,192?
ulimit biasanya melaporkan shell semasa dan menjejaskan keturunan yang dicipta selepas itu. Perkhidmatan yang telah dilancarkan oleh systemd, masa jalanan kontena, atau pengurus proses lain tidak diubah secara retroaktif. Penyelia dan pekerjanya juga mungkin mempunyai tetapan yang berbeza. Baca /proc/<pid>/limits bagi PID yang gagal, kemas kini sempadan pelancaran sebenar, dan sahkan PID baharu.
Susulan 2: Mengapa dua deskriptor untuk fail yang sama boleh menjejaskan kedudukan bacaan antara satu sama lain?
Jika ia berasal daripada dup, atau daripada deskriptor yang sama sebelum fork, ia merujuk kepada perihalan fail terbuka yang sama dan oleh itu berkongsi ofset dan bendera status fail. Jika program memanggil open() dua kali, laluan yang sama biasanya menghasilkan dua perihalan fail terbuka yang bebas dengan ofset yang bebas. Nama laluan yang dikongsi tidak membuktikan keadaan terbuka yang dikongsi.
Susulan 3: Mengapakah sesuatu proses masih boleh menggunakan fail melalui FD selepas fail tersebut dipadamkan?
Deskriptor tersebut merujuk kepada perihalan fail terbuka; I/O tidak menyelesaikan nama laluan sekali lagi setiap kali. Membuang entri direktori tidak membatalkan rujukan sedia ada. Objek asas boleh kekal sehingga rujukan terakhir ditutup. Penggiliran log yang memutuskan pautan (unlink) fail lama tanpa memastikan proses menutupnya boleh menggunakan kedua-dua deskriptor dan ruang cakera.
Susulan 4: Mengapakah usaha menaikkan RLIMIT_NOFILE kepada nombor yang sangat besar mungkin gagal?
Proses tanpa keistimewaan tidak boleh menaikkan had lembut melebihi had keras atau menaikkan had kerasnya secara bebas. Linux juga mengehadkan RLIMIT_NOFILE dengan /proc/sys/fs/nr_open. Pengurus perkhidmatan, kontena, atau sempadan kebenaran mungkin menambah kekangan. Semak ralat permulaan dan had berkesan bagi proses baharu selepas setiap perubahan.
Susulan 5: Jika satu instans epoll memantau banyak sambungan, mengapakah proses masih boleh kehabisan FD?
Instans epoll itu sendiri menggunakan satu FD dan muncul sebagai anon_inode:[eventpoll]. Setiap soket yang dipantau kekal sebagai FD yang berasingan. epoll menjadikan penungguan pada banyak sambungan cekap; ia tidak menggabungkan ribuan soket menjadi satu deskriptor atau menutupnya untuk aplikasi tersebut.
Susulan 6: Bagaimanakah anda akan menetapkan amaran mengenai penggunaan FD?
Pantau deskriptor terbuka semasa, maksimum proses, penggunaan, dan kadar pertumbuhan bagi setiap instans. Penggunaan mengesan kedekatan dengan kehabisan sumber; kecerunan mengesan kebocoran perlahan lebih awal. Kolam sambungan, fail, dan pemantau harus mendedahkan bilangan semasa masing-masing juga. Tetapkan ambang daripada belanjawan puncak, masa penskalaan, dan masa petunjuk tindak balas insiden dan bukannya menyalin peratusan sejagat.