Selama beberapa hari saya telah mencari solusi yang berfungsi untuk kesalahan
Error: EMFILE, too many open files
Tampaknya banyak orang memiliki masalah yang sama. Jawaban yang biasa melibatkan peningkatan jumlah deskriptor file. Jadi, saya sudah mencoba ini:
sysctl -w kern.maxfiles=20480
,
Nilai defaultnya adalah 10240. Ini agak aneh di mata saya, karena jumlah file yang saya tangani di direktori di bawah 10240. Bahkan lebih aneh, saya masih menerima kesalahan yang sama setelah saya meningkatkan jumlah deskriptor file .
Pertanyaan kedua:
Setelah beberapa pencarian, saya menemukan solusi untuk masalah "terlalu banyak file terbuka":
var requestBatches = {};
function batchingReadFile(filename, callback) {
// First check to see if there is already a batch
if (requestBatches.hasOwnProperty(filename)) {
requestBatches[filename].push(callback);
return;
}
// Otherwise start a new one and make a real request
var batch = requestBatches[filename] = [callback];
FS.readFile(filename, onRealRead);
// Flush out the batch on complete
function onRealRead() {
delete requestBatches[filename];
for (var i = 0, l = batch.length; i < l; i++) {
batch[i].apply(null, arguments);
}
}
}
function printFile(file){
console.log(file);
}
dir = "/Users/xaver/Downloads/xaver/xxx/xxx/"
var files = fs.readdirSync(dir);
for (i in files){
filename = dir + files[i];
console.log(filename);
batchingReadFile(filename, printFile);
Sayangnya saya masih menerima kesalahan yang sama. Apa yang salah dengan kode ini?
Satu pertanyaan terakhir (saya baru javascript dan node), saya sedang dalam proses mengembangkan aplikasi web dengan banyak permintaan untuk sekitar 5000 pengguna setiap hari. Saya sudah bertahun-tahun pengalaman dalam pemrograman dengan bahasa lain seperti python dan java. jadi awalnya saya pikir untuk mengembangkan aplikasi ini dengan Django atau kerangka bermain. Kemudian saya menemukan simpul dan saya harus mengatakan bahwa ide model I / O non-blocking sangat bagus, menggoda, dan yang paling utama sangat cepat!
Tapi masalah apa yang harus saya harapkan dengan node? Apakah ini server web yang terbukti produksi? Apa pengalaman anda
sumber
lsof -i -n -P | grep "12843" | wc -l
== 4085 tetapiulimit -a | grep "open files"
== (-n) 1024 ada petunjuk bagaimana saya bisa memiliki lebih banyak file yang dibuka daripada batas maksimum?Menggunakan
graceful-fs
modul oleh Isaac Schlueter (pengelola node.js) mungkin merupakan solusi yang paling tepat. Itu akan menambah mundur jika EMFILE ditemukan. Ini dapat digunakan sebagai pengganti drop-in untukfs
modul bawaan.sumber
Saya tidak yakin apakah ini akan membantu siapa pun, saya mulai mengerjakan proyek besar dengan banyak dependensi yang membuat saya mengalami kesalahan yang sama. Rekan saya menyarankan saya untuk menginstal
watchman
menggunakan minuman dan itu memperbaiki masalah ini untuk saya.Sunting pada 26 Juni 2019: Tautan Github ke penjaga
sumber
Saya mengalami masalah ini hari ini, dan tidak menemukan solusi yang baik untuk itu, saya membuat modul untuk mengatasinya. Saya terinspirasi oleh cuplikan @ fbartho, tetapi ingin menghindari menimpa modul fs.
Modul yang saya tulis adalah Filequeue , dan Anda menggunakannya seperti fs:
sumber
Anda membaca terlalu banyak file. Node membaca file secara tidak sinkron, itu akan membaca semua file sekaligus. Jadi, Anda mungkin membaca batas 10240.
Lihat apakah ini berfungsi:
sumber
Seperti kita semua, Anda adalah korban I / O yang tidak sinkron. Dengan panggilan asinkron, jika Anda memutar banyak file, Node.js akan mulai membuka deskriptor file untuk setiap file untuk dibaca dan kemudian akan menunggu tindakan sampai Anda menutupnya.
Deskriptor file tetap terbuka sampai sumber daya tersedia di server Anda untuk membacanya. Meskipun file Anda kecil dan membaca atau memperbarui cepat, dibutuhkan beberapa saat, tetapi pada saat yang sama loop Anda tidak berhenti untuk membuka deskriptor file baru. Jadi jika Anda memiliki terlalu banyak file, batasnya akan segera tercapai dan Anda mendapatkan EMFILE yang indah .
Ada satu solusi, membuat antrian untuk menghindari efek ini.
Terima kasih kepada orang-orang yang menulis Async , ada fungsi yang sangat berguna untuk itu. Ada metode yang disebut Async.queue , Anda membuat antrian baru dengan batas dan kemudian menambahkan nama file ke antrian.
Catatan: Jika Anda harus membuka banyak file, sebaiknya simpan file mana yang saat ini terbuka dan jangan buka kembali secara tak terbatas.
Anda dapat melihat bahwa setiap file ditambahkan ke antrian (nama file console.log), tetapi hanya ketika antrian saat ini di bawah batas yang Anda tetapkan sebelumnya.
async.queue mendapatkan informasi tentang ketersediaan antrian melalui panggilan balik, panggilan balik ini dipanggil hanya ketika file data dibaca dan tindakan apa pun yang harus Anda lakukan tercapai. (lihat metode fileRead)
Jadi Anda tidak bisa kewalahan oleh deskriptor file.
sumber
Saya baru saja selesai menulis sedikit cuplikan kode untuk menyelesaikan masalah ini sendiri, semua solusi lain tampak terlalu berat dan mengharuskan Anda untuk mengubah struktur program Anda.
Solusi ini hanya menghentikan panggilan fs.readFile atau fs.writeFile sehingga tidak ada lebih dari satu nomor yang ditetapkan dalam penerbangan pada waktu tertentu.
sumber
Saya melakukan semua hal yang disebutkan di atas untuk masalah yang sama tetapi tidak ada yang berhasil. Saya mencoba di bawah ini bekerja 100%. Perubahan konfigurasi sederhana.
Opsi 1 set batas (Ini tidak akan bekerja sebagian besar waktu)
periksa batas yang tersedia
Opsi 2 Untuk meningkatkan batas yang tersedia untuk mengatakan 65535
tambahkan baris berikut ke sana
jalankan ini untuk menyegarkan dengan konfigurasi baru
edit file berikut
tambahkan baris berikut ke sana
edit file berikut
tambahkan baris ini ke sana
logout dan login dan coba perintah berikut
Opsi 3 Cukup tambahkan baris di bawah ini
ke /etc/systemd/system.conf dan /etc/systemd/user.conf
sumber
Dengan bagpipe, Anda hanya perlu kembalian
=>
Bagpipe membantu Anda membatasi paralelnya. lebih detail: https://github.com/JacksonTian/bagpipe
sumber
Punya masalah yang sama ketika menjalankan perintah nodemon jadi saya mengurangi nama file yang terbuka di teks luhur dan kesalahan menghilang.
sumber
EMFILE
kesalahan dan melalui percobaan dan kesalahan melihat bahwa menutup beberapa jendela Sublime menyelesaikan masalah. Saya masih tidak tahu mengapa. Saya mencoba menambahkanulimit -n 2560
.bash_profile saya, tetapi itu tidak menyelesaikan masalah. Apakah ini mengindikasikan perlunya mengubah ke Atom ?Membangun jawaban @ blak3r, inilah sedikit singkatan yang saya gunakan untuk berjaga-jaga jika ini membantu diagnosa lain:
Jika Anda mencoba men-debug skrip Node.js yang kehabisan deskriptor file, inilah baris untuk memberi Anda output yang
lsof
digunakan oleh proses simpul yang dimaksud:Ini akan berjalan secara sinkron
lsof
difilter oleh proses Node.js yang sedang berjalan dan mengembalikan hasilnya melalui buffer.Kemudian gunakan
console.log(openFiles.toString())
untuk mengonversi buffer ke string dan mencatat hasilnya.sumber
cwait adalah solusi umum untuk membatasi eksekusi bersamaan dari setiap fungsi yang mengembalikan janji.
Dalam kasus Anda, kodenya bisa berupa:
sumber
Untuk pengguna nodemon : Cukup gunakan bendera --ignore untuk menyelesaikan masalah.
Contoh:
sumber
Gunakan yang terbaru
fs-extra
.Saya punya masalah itu pada
Ubuntu
(16 dan 18) dengan banyak ruang file / socket-deskriptor (hitung denganlsof |wc -l
).fs-extra
Versi yang digunakan8.1.0
. Setelah pembaruan ke9.0.0
"Kesalahan: EMFILE, terlalu banyak file yang terbuka" menghilang.Saya telah mengalami beragam masalah pada beragam OS 'dengan node yang menangani sistem file. Sistem file jelas tidak sepele.
sumber
Saya memiliki masalah ini, dan saya menyelesaikannya dengan menjalankan
npm update
dan berhasil.Dalam beberapa kasus, Anda mungkin perlu menghapus node_modules
rm -rf node_modules/
sumber
Saya menginstal penjaga, mengubah batas dll dan tidak bekerja di Gulp.
Restart iterm2 sebenarnya membantu.
sumber