Od kilku dni szukałem działającego rozwiązania błędu
Error: EMFILE, too many open files
Wydaje się, że wiele osób ma ten sam problem. Zwykła odpowiedź polega na zwiększeniu liczby deskryptorów plików. Więc spróbowałem tego:
sysctl -w kern.maxfiles=20480
,
Wartość domyślna to 10240. Moim zdaniem jest to trochę dziwne, ponieważ liczba plików, które obsługuję w katalogu, jest poniżej 10240. Co dziwniejsze, nadal otrzymuję ten sam błąd po zwiększeniu liczby deskryptorów plików .
Drugie Pytanie:
Po kilku wyszukiwaniach znalazłem obejście problemu „zbyt wielu otwartych plików”:
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);
Niestety nadal otrzymuję ten sam błąd. Co jest nie tak z tym kodem?
Ostatnie pytanie (jestem nowy w javascript i node): jestem w trakcie tworzenia aplikacji internetowej z dużą ilością zapytań dla około 5000 użytkowników dziennie. Mam wieloletnie doświadczenie w programowaniu w innych językach, takich jak Python i Java. więc początkowo myślałem, że stworzę tę aplikację za pomocą django lub frameworka play. Potem odkryłem node'a i muszę powiedzieć, że pomysł nieblokującego modelu I / O jest naprawdę fajny, uwodzicielski i przede wszystkim bardzo szybki!
Ale jakich problemów należy się spodziewać w przypadku węzła? Czy jest to sprawdzony serwer WWW? Jakie masz doświadczenia?
źródło
lsof -i -n -P | grep "12843" | wc -l
== 4085 aleulimit -a | grep "open files"
== (-n) 1024 jakaś wskazówka, jak mogę mieć więcej otwartych plików niż maksymalny limit?Użycie
graceful-fs
modułu autorstwa Isaaca Schluetera (opiekuna node.js) jest prawdopodobnie najbardziej odpowiednim rozwiązaniem. Wykonuje przyrostowe wycofywanie, jeśli napotkany zostanie EMFILE. Może być używany jako zamiennik wbudowanegofs
modułu.źródło
Nie jestem pewien, czy to komuś pomoże, zacząłem pracę nad dużym projektem z wieloma zależnościami, które wyrzuciły mi ten sam błąd. Mój kolega zasugerował mi instalację
watchman
za pomocą brew i to rozwiązało ten problem.Edycja 26 czerwca 2019 r .: łącze Github do watchman
źródło
Dzisiaj napotkałem ten problem i nie znajdując dla niego dobrych rozwiązań, stworzyłem moduł, aby go rozwiązać. Zainspirował mnie fragment @ fbartho, ale chciałem uniknąć nadpisywania modułu fs.
Moduł, który napisałem, to Filequeue i używasz go tak jak fs:
źródło
Czytasz za dużo plików. Węzeł czyta pliki asynchronicznie, będzie czytać wszystkie pliki naraz. Więc prawdopodobnie czytasz limit 10240.
Sprawdź, czy to działa:
źródło
Podobnie jak my wszyscy, jesteś kolejną ofiarą asynchronicznych operacji we / wy. W przypadku wywołań asynchronicznych, jeśli zapętlisz wiele plików, Node.js zacznie otwierać deskryptor pliku dla każdego pliku do odczytania, a następnie będzie czekał na akcję, aż go zamkniesz.
Deskryptor pliku pozostaje otwarty, dopóki na serwerze nie będzie dostępny zasób umożliwiający jego odczytanie. Nawet jeśli twoje pliki są małe, a odczyt lub aktualizacja jest szybka, zajmuje to trochę czasu, ale w tym samym czasie twoja pętla nie zatrzymuje się, aby otworzyć nowy deskryptor plików. Więc jeśli masz zbyt wiele plików, wkrótce limit zostanie osiągnięty i otrzymasz piękny EMFILE .
Jest jedno rozwiązanie, tworząc kolejkę, aby uniknąć tego efektu.
Dzięki ludziom, którzy napisali Async , jest do tego bardzo przydatna funkcja. Istnieje metoda o nazwie Async.queue , tworzysz nową kolejkę z limitem, a następnie dodajesz nazwy plików do kolejki.
Uwaga: jeśli musisz otworzyć wiele plików, dobrym pomysłem byłoby zapisanie, które pliki są aktualnie otwarte i nie otwieraj ich ponownie w nieskończoność.
Możesz zobaczyć, że każdy plik jest dodawany do kolejki (nazwa pliku console.log), ale tylko wtedy, gdy bieżąca kolejka jest poniżej limitu, który ustawiłeś wcześniej.
async.queue uzyskuje informacje o dostępności kolejki poprzez wywołanie zwrotne, to wywołanie zwrotne jest wywoływane tylko wtedy, gdy plik danych jest odczytywany i wykonywana jest każda czynność, którą musisz wykonać. (patrz metoda fileRead)
Nie możesz więc być przytłoczony deskryptorem plików.
źródło
Właśnie skończyłem pisać mały fragment kodu, aby samodzielnie rozwiązać ten problem, wszystkie inne rozwiązania wydają się zbyt ciężkie i wymagają zmiany struktury programu.
To rozwiązanie po prostu blokuje wszystkie wywołania fs.readFile lub fs.writeFile, tak że w locie w danym momencie nie ma więcej niż ustalona liczba.
źródło
Zrobiłem wszystkie powyższe rzeczy dla tego samego problemu, ale nic nie działało. Próbowałem poniżej to działało w 100%. Proste zmiany konfiguracji.
Opcja 1 ustaw limit (nie będzie działać przez większość czasu)
sprawdź dostępny limit
Opcja 2 Zwiększenie dostępnego limitu do 65535
dodaj do niego następujący wiersz
uruchom to, aby odświeżyć nową konfigurację
edytuj następujący plik
dodaj do niego następujące wiersze
edytuj następujący plik
dodaj do niego tę linię
wyloguj się, zaloguj się i wypróbuj następujące polecenie
Opcja 3 Po prostu dodaj poniższą linię
do /etc/systemd/system.conf i /etc/systemd/user.conf
źródło
Z dudami potrzebujesz tylko zmiany
=>
Dudy pomagają ograniczyć podobieństwo. więcej szczegółów: https://github.com/JacksonTian/bagpipe
źródło
Miałem ten sam problem podczas uruchamiania polecenia nodemon, więc zredukowałem nazwy plików otwieranych wysublimowanym tekstem i błąd zniknął.
źródło
EMFILE
błędy i metodą prób i błędów zauważyłem, że zamknięcie niektórych okien Sublime rozwiązało problem. Nadal nie wiem dlaczego. Próbowałem dodaćulimit -n 2560
do mojego .bash_profile, ale to nie rozwiązało problemu. Czy to wskazuje na potrzebę przejścia na Atom zamiast tego?Opierając się na odpowiedzi @ blak3r, oto trochę skrótu, którego używam na wypadek, gdyby pomóc innym zdiagnozować:
Jeśli próbujesz debugować skrypt Node.js, w którym brakuje deskryptorów plików, oto wiersz zawierający dane wyjściowe
lsof
używane przez dany proces węzła:Będzie to działać synchronicznie,
lsof
przefiltrowane przez aktualnie działający proces Node.js i zwróci wyniki przez bufor.Następnie użyj,
console.log(openFiles.toString())
aby przekonwertować bufor na ciąg i zarejestrować wyniki.źródło
cwait to ogólne rozwiązanie ograniczające jednoczesne wykonywanie wszelkich funkcji, które zwracają obietnice.
W twoim przypadku kod może wyglądać następująco:
źródło
Dla użytkowników nodemon : po prostu użyj flagi --ignore, aby rozwiązać problem.
Przykład:
źródło
Użyj najnowszego
fs-extra
.Miałem ten problem na
Ubuntu
(16 i 18) z dużą ilością miejsca na deskryptory plików / gniazd (licząc zlsof |wc -l
).fs-extra
Wersja używana8.1.0
. Po aktualizacji9.0.0
komunikatu „Błąd: EMFILE, zbyt wiele otwartych plików” zniknął.Doświadczyłem różnych problemów w różnych systemach operacyjnych z systemami plików obsługującymi węzły. Systemy plików nie są oczywiście trywialne.
źródło
Miałem ten problem i rozwiązałem go, uruchamiając
npm update
i zadziałało.W niektórych przypadkach może być konieczne usunięcie modułów node_modules
rm -rf node_modules/
źródło
Zainstalowałem stróża, zmieniłem limit itp. I nie zadziałało to w Gulp.
Ponowne uruchomienie iterm2 faktycznie pomogło.
źródło