【问题标题】:PHP File Upload in Sharded Server Configuration分片服务器配置中的 PHP 文件上传
【发布时间】:2012-07-17 14:40:33
【问题描述】:

我们使用多台服务器来处理传入的 Web 请求,这些请求以循环方式进行负载平衡。我遇到了一个不知道如何解决的问题。

使用 AJAX (qqFileUploader),我正在上传一个文件。默认情况下,它会进入 /tmp 文件夹,这很好。问题是当我尝试检索该文件时,该检索请求将由 没有 具有我上传的文件的下一个服务器处理。如果我一遍又一遍地重复请求,它最终会到达存储文件的原始服务器(通过循环负载平衡),然后我可以打开它。显然这不是一个好的解决方案。

这里基本上是代码:http://jsfiddle.net/Ap27Z/。为了简洁起见,我删除了一些。您将看到上传器对象调用 PHP 文件进行文件上传,然后在文件上传完成后,对脚本进行另一个 AJAX 调用以处理 .csv 文件。这就是流程在循环中迷失的地方。

我在这里阅读了一些关于将文件上传到内存的问题,似乎目前基本上不可行。我可以使用其他选项来上传文件并在同一个请求中处理所有内容吗?

【问题讨论】:

  • 为什么网页要告诉服务器去处理呢?你能把文件变成你数据库中的 BLOB 吗?
  • 您需要能够使用绝对名称引用每个服务器(即每个服务器都有自己的 A 记录),并且您需要在响应 POST 请求时返回单个服务器的名称文件上传到客户端的位置 - 例如使用 cookie - 因此客户端在尝试检索文件时可以使用其绝对名称引用正确的服务器。
  • 出于兴趣,这是 DNS 循环还是反向代理?
  • @DaveRandom 我不确定是什么类型,系统管理员会处理它。我喜欢您关于传递服务器名称的建议。我会调查的。
  • @DaveRandom,如果是反向代理,是否可以使用会话来解决这个问题?

标签: php javascript file-upload load-balancing round-robin


【解决方案1】:

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

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

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

我可以使用其他选项来上传文件并处理所有内容吗 在同一个请求中?

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

【讨论】:

  • LOL,有时最简单的事情是最容易被忽视的事情。我没有考虑只在上传文件的代码中处理文件处理。
【解决方案2】:

您的问题有(至少)2 个解决方案:

  1. 您更改负载平衡

有几个负载平衡代理支持会话亲和性,也就是“粘性会话”。这意味着用户在会话中始终获得相同的服务器。

可以以这种方式运行的两个程序是HAProxy (related question here on SO) 和nginxa custon module (tutorial here)。

  1. 文件的位置由您决定

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

【讨论】:

  • 我没有更改负载平衡的选项,但喜欢使用静态位置存储临时文件的想法。
  • 但是不要仅仅通过 NFS 挂载/tmp。其他进程可能正在使用该文件夹(例如,默认配置中的 PHP 会话),并且通过 NFS 发送所有这些可能会减慢一切。而是为您上传的文件使用单独的文件夹。
猜你喜欢
  • 1970-01-01
  • 2014-07-16
  • 1970-01-01
  • 1970-01-01
  • 2017-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-18
相关资源
最近更新 更多