我正在尝试设置一个 coldfusion 服务器来接受大文件的上传,但遇到了一些限制。以下是我目前观察到的情况:
ColdFusion Administrator 中有两个设置可以限制上传的大小:“发布数据的最大大小”和“请求限制内存”。如果您的上传大小(包括 HTTP 开销)大于这两个设置中的任何一个,则上传将被拒绝。我不明白为什么我们需要其中两个;据我所知,无论哪个设置得更高都没有任何影响。较低的那个获胜。
当有人尝试上传一个过大的文件时,他们不会收到一条友好的错误消息。在发送大约 1 个 TCP 窗口的数据后,上传就永远挂起了。而且挂起的方式非常糟糕。即使在客户端放弃并断开连接后,关联的 apache 线程仍然被绑定(我可以使用 mod_status 看到这一点)。卡住的线程不断增加,直到没有线程可以接受新请求,并且必须重新启动服务器。
我真的不明白“请求限制”是什么。所有关于它的文档都将其描述为内存区域的大小。如果是这样,那么我看不出它与文件大小有什么关系。它暗示了一件我根本不想相信的事情:ColdFusion 会将整个上传文件写入内存,然后再将其写入磁盘。没有一个理智的人会这样做,因为上传循环(读取中等大小的块,将其写入磁盘,重复直到完成)是如此简单。(我知道 HTTP 多部分/表单数据帖子的结构使它有点困难,但……像 Adobe 这样拥有 Web 开发产品的大公司肯定可以做到这一点……他们做不到吗?)
如果整个文件读取确实是这种情况,他们又如何能指望我们选择一个可行的大小限制呢?允许 1 GB 的内存,几个同时使用的用户甚至可能毫不费力就耗尽你的服务器内存。我们该怎么办呢?不是允许上传 GB 大小的视频?人们有视频要发布,却没有时间编辑它们!
附加信息
以下是一些版本号。
网络服务器:
Server: Apache/2.2.24 (Win64) mod_jk/1.2.32
ColdFusion:
Server Product ColdFusion
Version ColdFusion 10,285437
Tomcat Version 7.0.23.0
Edition Enterprise
Operating System Windows Server 2008 R2
OS Version 6.1
Update Level /E:/ColdFusion10/cfusion/lib/updates/chf10000011.jar
Adobe Driver Version 4.1 (Build 0001)
附加信息 #2
我不知道您为什么想知道我在限制字段中输入了什么值,但一段时间以来它们都设置为 200 MB。我将“帖子数据的最大大小”增加到 2000 MB,但没有效果。我已经发现,如果我将“请求节流内存”增加到 2000 MB,它将允许更大的上传量。我在这里寻找的不是快速的“在那里填入更大的数字!”答案,而是详细解释这些设置的实际含义以及它们对服务器内存使用的影响。
为什么服务器线程在超出限制时会永远停止而不是返回错误消息可能是另一个问题。我以为这是一个众所周知的问题。也许我应该先问问是否有人可以重现它。我从未见过 ColdFusion 向客户端返回“文件太大”错误消息。应该有一个吗?
附加信息 #3 一些实验让我找到了部分答案。我忽略的第一件事是“请求节流内存”(RTM)在设置为更高而不是“最大帖子数据大小”(MSOPD)。在我的第一轮测试中,由于不知道它们之间的关系,我把它们反过来了。根据我的新理解,我可以看到 RTM/MSOPD 比率是当它们都接近最大大小时允许同时上传的数量。
假设“请求节流内存”实际上是一个内存缓冲区,而不是一个临时文件,这意味着我最担心的事情是正确的。每个文件在上传的整个过程中都完全保存在内存中。没有人说任何话让我相信不是这样(尽管我也没有看到任何人跳出来表示“是的,他们做了这件蠢事”)
此外,有了这种新的理解,上传停滞也有些道理。服务器没有可用内存来接受上传,因此它只是不从套接字读取。TCP 缓冲区已满,窗口大小变为 0,客户端等待它再次打开,这应该在服务器开始读取请求后立即发生。但就我而言,出于某种原因,这种情况从未发生过。服务器完全忘记了请求,所以它只是徘徊不前。
“帖子数据的最大大小”被达到的情况仍然有点神秘。达到硬限制的请求不应排队,而应被拒绝。我确实收到了拒绝消息(“帖子大小超过最大限制 200 MB。”)server.log
。但在这种情况下,服务器似乎忘记了请求,而从未向客户端发送错误。
答案1
我还将尝试解释调整设置:-
- POST 请求参数的最大数量- 这是指通过特定请求发送的属性/参数的最大数量。特别用于在表单上发布数据时。
- 发布数据的最大大小- 这是服务器上可以发布的最大数据量。这是 POST 请求期间特定表单中所有数据的总和。
- 请求限制阈值- 必要时,ColdFusion 可以限制(强制减慢)传入请求。但是,无论限制状态如何,都可以允许非常小的请求(负载较小的请求)通过。要允许处理小请求,请指定允许的最大大小(默认最大为 4 MB)。
- 请求节流内存- 要限制请求,请指定分配给限制的最大内存量。如果总内存不足,ColdFusion 将对请求进行排队,直到有足够的内存可用(默认值为 200 MB)。它不会为 Req1 保留内存,因为它低于阈值。
假设有三个同时发生的请求 Req1 (3 MB)、Req2 (6 MB) 和 Req3 (9 MB)。使用默认设置,请求节流阈值设置为 4MB,ColdFusion 将在节流内存中保留 (6+9=15MB)。同样,它将继续为所有同时发生的请求添加请求节流内存,限制就是我们为请求节流内存设置的上限(默认值为 200 MB)
希望这可以帮助。
答案2
您可以使用 cftry-catch 捕获错误并向用户显示自定义消息。话虽如此,为POST 请求参数的最大数量、POST 数据的最大大小、请求限制阈值和请求限制内存。您使用的是 CF Std 还是 Ent,ColdFusion 的版本是什么?