成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Node.js中關于Accept時Emfile的處理

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

[[403078]]

本文轉載自微信公眾號「編程雜技」,作者theanarkh。轉載本文請聯系編程雜技公眾號。

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表示沒有連接需要處理了,從而結束處理連接的整個邏輯。

 

責任編輯:武曉燕 來源: 編程雜技
相關推薦

2021-04-19 07:41:37

AcceptEmfile問題

2021-03-04 23:12:57

Node.js異步迭代器開發

2011-11-02 09:04:15

Node.js

2021-12-25 22:29:57

Node.js 微任務處理事件循環

2020-10-26 08:34:13

Node.jsCORS前端

2021-12-28 20:04:23

Node.js開發JavaScript

2023-10-04 07:35:03

2015-03-10 10:59:18

Node.js開發指南基礎介紹

2024-01-05 08:49:15

Node.js異步編程

2021-05-21 09:36:42

開發技能代碼

2016-08-11 14:02:02

NodeJS前端

2020-04-15 15:48:03

Node.jsstream前端

2013-11-01 09:34:56

Node.js技術

2017-03-19 16:40:28

漏洞Node.js內存泄漏

2017-03-20 13:43:51

Node.js內存泄漏

2012-02-03 09:25:39

Node.js

2020-05-29 15:33:28

Node.js框架JavaScript

2021-12-01 00:05:03

Js應用Ebpf

2011-09-08 13:53:31

Node.js

2011-09-08 14:16:12

Node.js
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 午夜免费影视 | 欧美日韩国产高清 | 婷婷久久综合 | 羞羞免费网站 | 成人亚洲| 天天躁日日躁狠狠躁2018小说 | 午夜在线观看免费 | 亚洲精品福利视频 | 91免费版在线 | av一区在线观看 | 伦理午夜电影免费观看 | 国产欧美视频一区 | 免费在线视频一区二区 | 国产精品久久久久久久久久免费看 | 国产乱码精品一区二区三区忘忧草 | 视频一区中文字幕 | 一区二区在线看 | 久久亚洲一区二区 | 午夜久久| 日韩二 | www.精品国产 | 最新中文字幕在线播放 | 国产精品久久久久久婷婷天堂 | 欧美性tv| 国产精品高潮呻吟久久 | 欧美性区 | 九九国产在线观看 | 夜夜骑综合 | 久久久国产精品一区 | 免费成人高清在线视频 | 午夜精品久久久久久久 | 黄网在线观看 | 国产高清在线观看 | 欧洲av在线| 欧美a v在线 | 精品久久久一区二区 | 欧美最猛黑人xxxⅹ 粉嫩一区二区三区四区公司1 | 男女在线网站 | 中文字幕二区 | 视频一区在线观看 | 国产目拍亚洲精品99久久精品 |