2012-07-18 69 views
4

我们使用多个服务器处理以循环方式进行负载平衡的传入Web请求。我遇到了一个我不确定如何解决的问题。分片服务器配置中的PHP文件上传

使用AJAX(qqFileUploader),我正在上传文件。默认情况下它会进入/tmp文件夹,这很好。问题是,当我尝试检索该文件时,该检索请求被下一台服务器处理,其中没有有我上传的文件。如果我一再重复请求,它将最终到达存储文件的原始服务器(通过轮循负载均衡),然后我可以打开它。显然这不是一个好的解决方案。代码:http://jsfiddle.net/Ap27Z/。为了简洁,我删除了一些内容。您会看到上传器对象调用PHP文件进行文件上传,然后在文件上传完成后,另一个AJAX调用将处理该.csv文件的脚本。这是循环过程中迷失的地方。

我在这里读了几个关于上传文件到内存的问题,看起来它基本上不是现在可行的。是否有另一个选项可用于上传文件并在同一请求中处理所有文件?

+0

为什么网页必须告诉服务器来处理它?你可以将文件变成数据库中的BLOB吗? – Pete 2012-07-18 14:25:43

+1

您需要能够使用绝对名称引用每个服务器(即每个服务器都有自己的A记录),并且您需要在响应中返回单个服务器的名称,以便将文件上载到POST请求客户端 - 例如用cookie - 这样客户端可以在尝试检索文件时用绝对名称引用正确的服务器。 – DaveRandom 2012-07-18 14:25:44

+0

出于兴趣,这是一个DNS循环或反向代理? – DaveRandom 2012-07-18 14:28:21

回答

6

这种类型的问题的经典解决方案是在负载均衡器上使用粘性会话。这可能不是一个好的解决方案,因为它会修改整个设置来解决一个小问题。

我会建议为每台机器添加一个子域前缀,例如上传到www.example.com,然后为每台服务器分配一个额外的子域www1.example.com,www2.example.com,它们总是直接传递到该服务器,而不是循环DNS。

作为成功结果的一部分,您可以传回指向确切服务器的服务器名称,而不是负载平衡名称,然后所有引用上载数据的后续Ajax调用都使用该服务器特定的域名,而不是通用的负载平衡域名。

是否有另一个选项可用于上传文件并在同一个请求中处理所有文件 ?

当然,为什么不呢?处理数据POST的代码可以做你想做的任何事情。

+0

LOL的很好的解释,有时候简单的事情是被忽视的东西。我没有考虑只处理上传文件的代码中的文件处理。 – 2012-07-18 14:31:46

2

有(至少)2个解决你的问题:

  1. 更改负载平衡

有几个负载均衡代理支持会话亲和力a.k.a.“粘性会话”。这意味着用户总是在会话中获得同一台服务器。

两个方案可以以这种方式行事是HAProxyrelated question here on SO)和nginxa custon moduletutorial here)。

  1. 您有机会获得文件的位置

另一个选择是改变您存储文件的位置,所有服务器都可以通过同一位置访问某些地方。例如,这可以是NFS挂载或数据库(将文件存储为BLOBS)。这样,哪个服务器处理请求并不重要,因为它们都可以访问该文件。

+0

我没有选择更改负载平衡的选项,但是像存储临时文件的静态位置的想法一样。 – 2012-07-18 14:32:53

+0

但是不要通过NFS挂载'/ tmp'。其他进程可能使用该文件夹(例如,默认配置中的PHP会话),并通过NFS发送所有内容可能会减慢一切。而是,为您上传的文件使用单独的文件夹。 – Carsten 2012-07-18 14:35:54