据我理解,Node的事件驱动IO模型的一个后果是,在您连接了接收事件处理程序(或以其他方式开始监听数据)后,无法告诉正在通过TCP套接字接收数据的Node进程阻塞。如果接收方无法快速处理传入的数据,则可能会产生“无限并发”,Node在底层会继续尽可能快地从套接字读取数据,调度新的数据事件到事件循环中,而不是在套接字上阻塞,直到进程最终耗尽内存并停止运行。接收方无法要求node减慢其读取速度,否则TCP内置的流量控制机制将会起作用,并提示发送方需要降低速度。
首先,我所描述的是否准确?是否有我遗漏的东西可以让node避免这种情况?
Node Streams自动处理背压(backpressure)是其中一个受热捧的特性。据我所知,可写流(tcp套接字)判断自己是否需要放慢速度的唯一方式是查看socket.bufferSize(表示已写入但尚未发送到套接字的数据量)。鉴于Node在接收端始终以尽可能快的速度读取数据,这只能表明发送方和接收方之间存在缓慢的网络连接,而不能表明接收方无法跟上发送方的速度。
其次,在这种情况下,Node Streams自动背压是否能够处理无法跟上速度的接收方?
似乎这个问题也会影响通过Websockets接收数据的浏览器,原因类似于Websockets API没有提供一种机制来告诉浏览器放慢对套接字的读取速度。
那么,解决这个问题的唯一方法是Node(和使用Websockets的浏览器)在应用程序级别实现手动流控制机制,明确告诉发送进程要放慢速度吗?
首先,我所描述的是否准确?是否有我遗漏的东西可以让node避免这种情况?
Node Streams自动处理背压(backpressure)是其中一个受热捧的特性。据我所知,可写流(tcp套接字)判断自己是否需要放慢速度的唯一方式是查看socket.bufferSize(表示已写入但尚未发送到套接字的数据量)。鉴于Node在接收端始终以尽可能快的速度读取数据,这只能表明发送方和接收方之间存在缓慢的网络连接,而不能表明接收方无法跟上发送方的速度。
其次,在这种情况下,Node Streams自动背压是否能够处理无法跟上速度的接收方?
似乎这个问题也会影响通过Websockets接收数据的浏览器,原因类似于Websockets API没有提供一种机制来告诉浏览器放慢对套接字的读取速度。
那么,解决这个问题的唯一方法是Node(和使用Websockets的浏览器)在应用程序级别实现手动流控制机制,明确告诉发送进程要放慢速度吗?
highWaterMark
选项。这是如何处理背压的:当Node填满其输入缓冲区时,它会减慢读取速度;如果输出缓冲区已满,则还将停止发送数据。 Node会以尽可能快的速度读取...直到填满其缓冲区。在缓冲区再次为空之前,它不会读取任何更多的数据。我建议研究此示例的“流缓冲区长度”(Stream Buffer Length)。 - Paul Mougel