中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Node.js中處理Accept時出現Emfile的解決方法

發布時間:2021-06-16 09:56:28 來源:億速云 閱讀:188 作者:chen 欄目:web開發

這篇文章主要講解了“Node.js中處理Accept時出現Emfile的解決方法”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Node.js中處理Accept時出現Emfile的解決方法”吧!

EMFILE表示進程打開的文件描述符達到了上限,比如建立了一個TCP連接后,調用accept函數的時候就可能觸發這個錯誤。那么這個會導致什么問題呢?首先我們看看Node.js是如何處理連接的。

void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {

uv_stream_t* stream;

int err;

stream = container_of(w, uv_stream_t, io_watcher);

while (uv__stream_fd(stream) != -1) {

// 摘取一個TCP連接

err = uv__accept(uv__stream_fd(stream));

// 記錄下來

stream->accepted_fd = err;

// 執行上層回調,回調里消費accepted_fd

stream->connection_cb(stream, 0);

// 下一個循環

}

}

當監聽socket上可讀事件觸發的時候,Node.js就會執行uv__server_io進行處理。在uv__server_io中Node.js就會不斷地調用accept摘取連接,然后執行回調處理該連接。這是正常的流程,那么如果accept出錯了,那會怎么樣?比如返回了EMFILE錯誤。

因為Node.js中,epoll的工作模式是水平觸發,所以每輪事件循環中,uv__server_io都會被觸發,然后執行accept,接著觸發錯誤(如果還沒有可用的文件描述符的話)。然而底層已完成三次握手的TCP連接無法得到處理,客戶端也只能默默地在等待。Node.js選擇的處理策略是關閉連接來通知客戶端,服務器已經過載。我們看看Node.js具體是怎么做的。在初始化第一個Libuv  stream的時候會首先預留一個文件描述符。

if (loop->emfile_fd == -1) {

err = uv__open_cloexec("/dev/null", O_RDONLY);

if (err < 0)

/* In the rare case that "/dev/null" isn't mounted open "/"

* instead.

*/

err = uv__open_cloexec("/", O_RDONLY);

if (err >= 0)

loop->emfile_fd = err;

}

我們看到Node.js打開了一個資源,然后拿到了一個文件描述符保存到emfile_fd。當Node.js處理TCP連接的時候,這個emfile_fd可能就會被用上。

// 摘取TCP連接

err = uv__accept(uv__stream_fd(stream));

if (err < 0) {

// 文件描述符過載

if (err == UV_EMFILE || err == UV_ENFILE) {

err = uv__emfile_trick(loop, uv__stream_fd(stream));

if (err == UV_EAGAIN || err == UV__ERR(EWOULDBLOCK))

break;

}

stream->connection_cb(stream, err);

continue;

}

我們看到當uv_accept返回UV_EMFILE錯誤的時候,會執行uv__emfile_trick。

static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) {

int err;

int emfile_fd;

if (loop->emfile_fd == -1)

return UV_EMFILE;

// 關閉預留的文件描述符,下面的uv_accept才能執行成果

uv__close(loop->emfile_fd);

loop->emfile_fd = -1;

// 循環關閉無法處理的TCP連接

do {

// 摘取TCP連接

err = uv__accept(accept_fd);

if (err >= 0)

// 關閉TCP連接,通知客戶端服務器過載

uv__close(err);

} while (err >= 0 || err == UV_EINTR);

// 重新獲取一個預留的文件描述符

emfile_fd = uv__open_cloexec("/", O_RDONLY);

if (emfile_fd >= 0)

loop->emfile_fd = emfile_fd;

return err;

}

我們看到uv__emfile_trick中關閉了所有無法處理的TCP連接,然后重新補充預留的文件描述符。正常來說uv_accept最后會返回UV_EAGAIN表示沒有連接需要處理了,從而結束處理連接的整個邏輯。

感謝各位的閱讀,以上就是“Node.js中處理Accept時出現Emfile的解決方法”的內容了,經過本文的學習后,相信大家對Node.js中處理Accept時出現Emfile的解決方法這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

凤庆县| 颍上县| 五莲县| 祁连县| 樟树市| 越西县| 峨边| 尚义县| 廊坊市| 金寨县| 景泰县| 永吉县| 台南市| 安阳市| 临江市| 金川县| 贵港市| 隆德县| 凉山| 平遥县| 开原市| 保靖县| 延安市| 海淀区| 崇文区| 连南| 清河县| 应用必备| 长海县| 临猗县| 库车县| 鹿邑县| 扶余县| 家居| 子洲县| 卢氏县| 讷河市| 苏尼特左旗| 曲阳县| 梅州市| 宾川县|