簡體   English   中英

nodejs http response.write:是否可能內存不足?

[英]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;
  }
};

一些陷阱:

  1. 如果通過http發送,則不是一個好主意。 如果請求未在指定的時間內完成,則瀏覽器可能會將其視為超時。 服務器也將關閉空閑時間過長的連接。 如果客戶端無法跟上,超時幾乎可以確定。

  2. setInterval 10ms也受到一些限制。 這並不意味着它將每10毫秒重復一次,而10毫秒是重復之前等待的最短時間。 這將比您設置的間隔慢。

  3. 假設您有機會使數據超載響應,然后服務器將終止連接,並根據設置的限制由413 Request Entity Too Large響應。

  4. Node.js具有單線程體系結構,最大內存限制約為1.7 GB。 如果您服務器的上述限制設置得太高,並且有許多傳入連接,則將導致process out of memory不足錯誤。

因此,如果有適當的限制,它將導致超時或請求太大。 (並且程序中沒有其他錯誤。)

更新

您需要使用drain事件。 http響應是可寫流。 它具有自己的內部緩沖區。 清空緩沖區后,將觸發耗盡事件。 您應該更深入地了解有關流的更多信息。 這將不僅在http中提供幫助。 您可以找到有關Web流的一些資源。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM