最终,
这是我第三次尝试解决上传问题(在内存中缓冲全部内容)
我尝试通过多种方式解决这个问题
- 通过暂时禁用传入套接字上的 fd-events 来实现流量控制。这本可以带来更好的流量整形效果。但一步到位实现它太复杂了。这大大推迟了 1.4.0 版本的发布。
- 将接收阶段分为两步:第一步读取头部并启动后端进程,第二步读取请求内容并转发给后端。这将在后续版本中再次实现,并会带回上传进度条功能。
- 最终,我实现了在邮件列表和 IRC 频道上多次提出的想法:简单处理,缓冲到磁盘。
这现在已经添加到 Subversion 树中,并将成为 1.4.5 版本的一部分。
当有人想向服务器发送超过 64KB 的内容时,内容将不再像以前那样在内存中缓冲,而是以 1MB 大小的块存储在 /var/tmp/ 的临时文件中。全部内容将在转发到后端之前进行缓冲。一旦块被转发到后端,它就会被释放,要么通过删除磁盘上的临时文件,要么通过释放内存中的缓冲区。这使我们能够轻松处理 ISO 文件的上传,在我这里不再触及 3MB 的限制。在 1.4.4 版本中,这导致 lighttpd 进程占用大量内存。
FastCGI 仍存在一个之前已经发现的问题:后端可能会在我们发送最后一个数据包时,用 EPIPE(远程端关闭连接)来终止连接。到目前为止我不知道为什么。从我们发送的协议层面来看,它看起来是正常的。这是唯一遗留的问题。
我鼓励大家进行测试,即使它目前只能从 SVN 获取。