每秒请求1000次JSON。这个很贵吗?

时间:2012-09-26 09:16:46

标签: php javascript jquery json

Pseucode:

function getjson() {
   $.getJSON('link_in_my_server_unique_for_each_user_json', function(data) {
     if (data.variable) {
        do_something();
     }
   });​ 
}

setInterval(getjson(), every_second)

让1000个用户每秒在我的服务器中检索json文件并检查该文件是否有一些变量是否很昂贵?

9 个答案:

答案 0 :(得分:21)

首先,你不需要猜测。您可以衡量

  1. 使用适用于您的浏览器的开发人员工具(适用于Firefox的Firebug,适用于Chrome的开发人员工具等),并观察请求并查看每个请求的持续时间。
  2. 观察服务器上的负载。如果它不是0%,你永远不会看到1000个会话同时运行。
  3. 重复上述步骤,但打开一堆浏览器。打开并运行20个浏览器窗口应该很容易。
  4. 请记住,随着服务器负载超过50%,您的性能将变得越来越非线性。一旦你的系统阻塞/颠簸很多,你就不能期望再增加任何客户端。
  5. 一旦进行了基线测量,您就可以考虑优化 - 您是否需要它以及您手上有多大问题?一些常用的解决方案:

    1. 如果可能,请从APC缓存中提供静态文件或一段数据。
    2. 如果您的数据是可缓存的,但您有多个Web服务器,请考虑使用memcached,MongoDB或其他一些集中式非常快速的基于密钥的检索系统等解决方案。
    3. 如果从数据库动态检索数据,请考虑使用持久数据库连接。
    4. 如果每个请求的CPU负载很高,您的代码路径中可能会有一些昂贵的东西。尝试优化该特定请求的代码路径,即使您必须手工制作一个特殊的控制器并绕过您的常用框架。
    5. 如果每个请求的网络延迟很高,请使用HTTP标头尝试说服客户端和服务器保持连接打开。
    6. 最后,如果您想要的性能似乎非常难以达到,那么您需要考虑架构更改。使用WebSockets可能是一个非常不同的代码路径,但可以想象可以产生更好的性能。我必须更多地了解您使用link_in_my_server_unique_for_each_user_json做了什么。

答案 1 :(得分:8)

可能是的,这会杀死你的平均共享主机或小VPS。

完全有可能将大部分内容卸载到CloudFlare或AWS CloudFront等系统,并使用短暂的(约1秒)缓存过期。大多数用户会直接从缓存中获取它,从而为您的服务器节省大部分工作。

答案 2 :(得分:6)

如果您无法缓存,可能会考虑使用COMET模式,因此您每秒可以进行1,000次长时保持呼叫而不是1,000次呼叫,整体上可以减少流量,但可以提供所需的结果。见http://en.wikipedia.org/wiki/Comet_%28programming%29

答案 3 :(得分:2)

您是否考虑过web socket

它与Stack Overflow使用的主体相同。当变量实际更改时,您可以将数据推送给用户。但是您的服务器需要正确设置才能这样做。

答案 4 :(得分:1)

所以我们说的是每秒至少1k个请求。即使对于功能强大的机器,这已被认为是相当高的负载。那么每个请求必须做些什么呢?

  • 连接初始化
  • 处理请求
  • 执行服务器端逻辑

在这种情况下,您几乎消耗了所有可用资源(包括文件i / o)。此外,您正在消耗大部分Web服务器资源以获取某些可能不是您最重要功能的附加值。

什么是更好的方法?

您希望对更改做出反应,而不是轮询它。因此,对于每个用户,我们将有一个包含其事件的频道,当事件发生时,我们希望服务器通知我们。不幸的是,正如另一个答案所提到的,这不是PHP最强的套装。

对于客户端,您可以查看SockJS并将其与Node.jsVert.x配对。您可以免费获得所需的所有架构,并且设置起来并不是很难。 SockJS还提供了一组很好的协议测试,因此很容易实现自己的服务器端实现。

通过这些更改,每个用户只能向SockJS提供商发出一个请求,您可以根据需要单独进行扩展。主要服务也不会被JSON调用中断。所以我们最终得到了

  • 每个页面加载一个请求到SockJS提供程序
  • 每次更改从PHP向SockJS提供商提出的一项请求

它确实使身份验证变得有点棘手,但您可以拥有PHP应用程序和SockJS提供程序都知道的私钥,并使用它来签署一些cookie。然后,您可以使用JSON请求传递该cookie。

答案 5 :(得分:1)

除非变量是唯一且与特定用户相关的,否则我建议使用以下解决方案之一:

  • 使用Cloud Service缓存它
  • 使用Web套接字连接将其推送给用户
  • 使用javascript
  • 将工作卸载到客户端
  • 使用长轮询而不是间隔轮询

数据轮询的时代已经过去,而且通常会有更好,更具成本效益的解决方案。

答案 6 :(得分:0)

只要JSON文件是“静态”请求(webserver直接按原样提供文件,而不将请求传递给某些php / ruby​​ / java / etc。进程),您就可以确定服务器是否可以接受它通过简单的基准测试。

这看起来像是对我的预缓存(要求的信息由服务器预先准备并以结构化响应的形式缓存)。尝试将nginx用于这些类型的请求。它还有用于预先压缩文件的可选模块(如果您更改原始文件,它将自动更新gzip缓存)。这将为您提供额外的CPU(显然带宽更多)。

由于您没有指定文件大小,可用带宽,CPU类型,内存等,因此没有人可以给出“是否昂贵?”的是/否答案。在具有足够带宽(相对于文件大小)的强大服务器上,它可能无关紧要,或者它可能会导致共享主机或弱vps设置中断。

更新:如果使用长保持活动(持久HTTP TCP连接)正确设置过期标头,则可以从HTTP响应代码304 Not Modified中受益(也就是说服务器只会提供此服务)状态和一些标题,而不是整个文件重新开始)。不会涉及脚本,不会涉及服务文件(除非它改变),TCP重新连接不会发生,磁盘读取不会发生(文件统计数据至少由操作系统缓存) - nginx可能是原始的最佳选择静态文件检查/读取/服务的性能。

答案 7 :(得分:0)

你怎么不检查文件是否有一些变量,而是告诉你告诉你的前端是否已经创建了一个变量?观察者模式在工作!

有一些库可以做PHPWebSocket类型的东西。它们通常涉及一些长轮询型策略。

退房:http://code.google.com/p/phpwebsocket/

答案 8 :(得分:0)

这看起来好像是在解决错误的问题。

我怀疑为什么你觉得每个浏览器都需要每隔一秒就能看到你的网站。也许某些背景会有所帮助。

现在,如果你真的需要这种能力,那么你就可以做到。然而,这完全取决于成本。您需要进行测试以确定在负载平衡配置中确切需要多少Web服务器。然后回到那些提出要求的人那里,让他们知道与“特征”相关的成本。