2011-06-26 28 views
7

Tôi mới sử dụng Node.JS và bị kẹt với lỗi EMFILE. Tôi là sau khi một cách để bắt ngoại lệ EMFILE, và xử lý nó trong mã.Làm thế nào để xử lý các ngoại lệ EMJILE nodejs mà không sửa đổi ulimit?

Dường như có nhiều câu hỏi về lỗi "Lỗi: EMFILE, Quá nhiều tệp đang mở", nhưng hầu hết các câu trả lời dường như nằm dọc theo dòng "Tăng ulimit của bạn".

Câu hỏi đầu tiên của tôi là, làm cách nào để bắt ngoại lệ này? Khi tôi chạy mã dưới đây với nhiều kết nối, nó làm tăng các lỗi EMFILE:

stream = net.createConnection(port, host); 

    stream.addListener('connect', function() { 
    return stream.write(request); 
    }); 
    stream.addListener('data', function(data) { 
    return console.log(data); 
    }); 
    stream.addListener('end', function() { 
    stream.end(); 
    return callback(); 
    }); 
    stream.addListener('timeout', function() { 
    stream.destroy(); 
    console.log("timeout"); 
    return callback(); 
    }); 
    stream.addListener('error', function(e) { 
    console.log("this never gets called"); 
    return 
    }); 

Trường hợp ngoại lệ là không được đánh bắt trong 'lỗi' người nghe. Tôi đã cố gắng để bọc ở trên trong một try{} catch (e) {} và không có gì xảy ra. Tôi đã sử dụng một phương thức gọi lại cho createConnection, và nó không trả về bất kỳ lỗi nào.

Cách duy nhất tôi đã có thể nắm bắt những ngoại lệ với:

process.on('uncaughtException', function(err) { 
    console.log(err); 
}); 

mà dường như không an toàn cho nó bắt tất cả mọi thứ.

Và vì vậy câu hỏi thứ hai của tôi là: Cách "thực hành tốt nhất" để bắt lỗi và thử lại cuộc gọi là gì?

tôi đã xem xét: https://github.com/isaacs/npm/blob/master/lib/utils/graceful-fs.jsSimple nodejs http proxy fails with "too many open files" như tài liệu tham khảo, nhưng tôi không chắc chắn làm thế nào để áp dụng các duyên dáng phương pháp từ NPM để gọi createConnection.

Cảm ơn nhiều!

Trả lời

3

Thậm chí nếu bạn có thể bắt ngoại lệ này, bạn có thể làm gì hữu ích cho điều này không? Nếu bạn bị rò rỉ ở đâu đó, bạn cần phải sửa chữa rò rỉ, và nếu bạn có tải trọng bình thường nhưng rất cao, thì bạn sẽ cần phải xử lý bằng cách nào đó. Dù bằng cách nào, khi bạn nhấn điều kiện này, mọi thứ đều khá tệ trong quá trình nút của bạn.

Thật không may, khi bạn xử lý một sự kiện uncaughtException, điều an toàn duy nhất cần làm là ghi lại thông báo lỗi và sau đó thoát khỏi quá trình. Các ngăn xếp mà trên đó các ngoại lệ đã được ném bây giờ đã biến mất, và sự nhầm lẫn sâu sắc nội bộ sẽ sớm có kết quả.

Giải pháp tốt nhất là tăng số lượng bộ mô tả tệp khả dụng cho quy trình. Tin tốt là các bộ mô tả tập tin thực sự rẻ.

+0

Tôi thực sự chỉ muốn bắt ngoại lệ như một phương tiện học cách tốt nhất để xử lý loại ngoại lệ ứng dụng này. Đối với ứng dụng cụ thể, tôi đã kết thúc việc tạo một mảng với kết nối tiếp theo - khi một kết nối kết thúc, nó sẽ lấy một kết nối tiếp theo từ mảng đó. – Moolio

+2

để tăng số lượng bộ mô tả tệp khả dụng cho quy trình, chạy 'ulimit -S -n 5000' trên OSX – DTrejo

+1

Tôi muốn nói cách tốt nhất để xử lý loại ngoại lệ này là gỡ lỗi nguyên nhân. EMFILE (về cơ bản là một bộ mô tả tập tin bị rò rỉ trong trường hợp của bạn) không phải là một ngoại lệ sẽ xuất hiện trong mã chức năng đúng (trừ khi mã của bạn thực sự đang mở một số lượng lớn các tệp). Tôi muốn đề nghị sử dụng 'lsof' để gỡ lỗi ở đâu, như thế nào và tại sao rò rỉ xảy ra trước khi thử các chiến lược' try'/'catch'. –

Các vấn đề liên quan