[英]nodejs http response.write: is it possible out-of-memory?
如果我有以下代碼每隔10ms反復向客戶端發送數據:
setInterval(function() {
res.write(somedata);
}, 10ms);
如果客戶端接收數據的速度非常慢,會發生什么?
服務器會出現內存不足錯誤嗎?
編輯:實際上連接保持活動狀態,服務器不斷發送jpeg數據(HTTP multipart / x-mixed-replace標頭+正文+標頭+正文.....)
由於node.js response.write是異步的,
因此,一些用戶猜測它可能會將數據存儲在內部緩沖區中,然后等到低層告知它可以發送,
這樣內部緩沖區會增加,對嗎?
如果我是對的,那么如何解決呢?
問題是在為單個寫調用發送數據時,node.js不會通知我。
換句話說,我不能告訴用戶這種方式在理論上沒有“內存不足”以及如何解決的風險。
更新:通過user568109給出的關鍵字“ drain”事件,我研究了node.js的來源,並得出了結論:
它確實會導致“內存不足”錯誤。 我應該檢查response.write(...)=== false的返回值,然后處理響應的“排水”事件。
http.js:
OutgoingMessage.prototype._buffer = function(data, encoding) {
this.output.push(data); //-------------No check here, will cause "out-of-memory"
this.outputEncodings.push(encoding);
return false;
};
OutgoingMessage.prototype._writeRaw = function(data, encoding) { //this will be called by resonse.write
if (data.length === 0) {
return true;
}
if (this.connection &&
this.connection._httpMessage === this &&
this.connection.writable &&
!this.connection.destroyed) {
// There might be pending data in the this.output buffer.
while (this.output.length) {
if (!this.connection.writable) { //when not ready to send
this._buffer(data, encoding); //----------> save data into internal buffer
return false;
}
var c = this.output.shift();
var e = this.outputEncodings.shift();
this.connection.write(c, e);
}
// Directly write to socket.
return this.connection.write(data, encoding);
} else if (this.connection && this.connection.destroyed) {
// The socket was destroyed. If we're still trying to write to it,
// then we haven't gotten the 'close' event yet.
return false;
} else {
// buffer, as long as we're not destroyed.
this._buffer(data, encoding);
return false;
}
};
一些陷阱:
如果通過http發送,則不是一個好主意。 如果請求未在指定的時間內完成,則瀏覽器可能會將其視為超時。 服務器也將關閉空閑時間過長的連接。 如果客戶端無法跟上,超時幾乎可以確定。
setInterval 10ms也受到一些限制。 這並不意味着它將每10毫秒重復一次,而10毫秒是重復之前等待的最短時間。 這將比您設置的間隔慢。
假設您有機會使數據超載響應,然后服務器將終止連接,並根據設置的限制由413 Request Entity Too Large
響應。
Node.js具有單線程體系結構,最大內存限制約為1.7 GB。 如果您將服務器的上述限制設置得太高,並且有許多傳入連接,則將導致process out of memory
不足錯誤。
因此,如果有適當的限制,它將導致超時或請求太大。 (並且程序中沒有其他錯誤。)
更新
您需要使用drain
事件。 http響應是可寫流。 它具有自己的內部緩沖區。 清空緩沖區后,將觸發耗盡事件。 您應該更深入地了解有關流的更多信息。 這將不僅在http中提供幫助。 您可以找到有關Web流的一些資源。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.