繁体   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