0

伪代码:

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 文件并检查该文件是否有一些变量是否昂贵?

4

9 回答 9

21

首先,您无需猜测。你可以测量

  1. 使用可用于您的浏览器的开发人员工具(Firefox 的 Firebug、Chrome 的开发人员工具等)并观察请求并查看每个请求需要多长时间。
  2. 观察服务器上的负载。如果它不是 0%,您将永远不会看到 1000 个会话同时运行。
  3. 重复上述步骤,但打开一堆浏览器。打开并运行 20 个浏览器窗口应该很容易。
  4. 请记住,随着服务器负载超过 50%,您的性能将变得越来越非线性。一旦你的系统被阻塞/颠簸很多,你就不能指望增加更多的客户端。

一旦你有了基线测量,你就可以考虑优化——你需要它吗?你手上有多大的问题?一些常见的解决方案:

  1. 如果可能,请提供静态文件或 APC 缓存中的一段数据。
  2. 如果您的数据是可缓存的,但您有多个 Web 服务器,请考虑使用 memcached、MongoDB 或其他一些集中式、非常快速的基于键的检索系统之类的解决方案。
  3. 如果数据是从数据库中动态检索的,请考虑使用持久数据库连接。
  4. 如果每个请求的 CPU 负载很高,那么您的代码路径中可能有一些昂贵的东西。尝试优化该特定请求的代码路径,即使您必须为它手工制作一个特殊的控制器并绕过您通常的框架。
  5. 如果每个请求的网络延迟很高,请使用 HTTP 标头尝试说服客户端和服务器保持连接打开。

最后,如果您想要的性能似乎遥不可及,您将需要考虑架构更改。使用 WebSockets 可能是一个非常不同的代码路径,但可以想象得到更好的性能。我必须更多地了解你在做什么link_in_my_server_unique_for_each_user_json

于 2012-10-03T20:25:16.433 回答
8

很有可能,这会杀死您的普通共享主机或小型 VPS。

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

于 2012-09-28T15:38:27.497 回答
6

如果您不能缓存,或许可以考虑 COMET 模式,这样您将有 1,000 个长期调用,而不是每秒 1,000 个调用,总体上服务的流量较少,但会提供所需的结果。见http://en.wikipedia.org/wiki/Comet_%28programming%29

于 2012-09-28T15:41:25.000 回答
2

你有没有想过一个网络套接字

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

于 2012-10-02T15:47:19.333 回答
1

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

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

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

什么是更好的方法?

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

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

通过这些更改,每个用户对 SockJS 提供者只有一个请求,如果需要,您可以独立扩展它。主要服务也不会被 JSON 调用中断。所以我们最终得到

  • 每页加载一个请求到 SockJS 提供程序
  • 每次更改从 PHP 向 SockJS 提供者发出一个请求

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

于 2012-09-30T13:17:50.293 回答
1

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

  • 使用云服务缓存它
  • 使用 Web Socket Connection 将其推送给用户
  • 使用 javascript 将工作卸载到客户端
  • 使用长轮询而不是间隔轮询

轮询数据的时代即将结束,而且通常有更好、更具成本效益的解决方案。

于 2012-10-03T11:25:14.360 回答
0

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

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

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

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

于 2012-09-29T09:43:31.153 回答
0

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

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

查看:http ://code.google.com/p/phpwebsocket/

于 2012-10-03T01:16:50.020 回答
0

这看起来真的像你在解决错误的问题。

我会质疑为什么你觉得有必要让每一个浏览器在他们查看它的每一秒都点击你的网站。也许一些背景会有所帮助。

现在,如果你真的需要这种能力,那么是的,你可以做到。然而,这一切都与成本有关。您需要对其进行测试,以确定负载平衡配置中需要多少 Web 服务器。然后回到提出要求的人那里,让他们知道与该“功能”相关的成本。

于 2012-10-05T14:19:13.857 回答