扩展聊天应用程序 - 短轮询与长轮询(AJAX、PHP)

2022-08-30 13:55:43

我经营一个网站,用户可以通过浏览器相互聊天(想想Facebook聊天)。处理实时交互的最佳方式是什么?(现在,我每30秒进行一次民意调查,以更新在线用户和新传入消息,并且每秒在聊天页面上进行另一次民意调查以获取新消息。

我考虑过的事情:

  • HTML5 Web Sockets:没有使用它,因为它不能在所有浏览器中工作(只有chrome)。
  • Flash Sockets:没有使用它,因为我想最终支持移动网络。

现在,我正在使用短轮询,因为我不知道AJAX长轮询的可扩展性如何。我现在正在从servint运行VPS服务器(运行apache)。我应该使用长轮询还是短轮询?我不需要绝对即时的响应时间(对于聊天应用程序来说,“足够好”)。短轮询这个经常有几十万用户会杀死我的服务器吗?我如何扩展这个,请帮忙!


答案 1

一些注意事项:

  • 每秒轮询一次是过分的。该应用程序仍然会感觉非常灵敏,检查之间会有几秒钟的延迟。
  • 要保存数据库的流量和速度响应,请考虑使用内存中缓存来存储未传递的消息。您仍然可以将消息保存到数据库,内存中的缓存将仅用于查询新消息,以避免每个用户每x秒查询一次数据库。
  • 在处于非活动状态 x 秒后,使用户的聊天超时,以停止对服务器的轮询。这可以确保打开窗口的人不会继续产生流量。提供一个简单的“还在那里吗?“链接表示超时的会话,并在超时之前警告用户,以便他们可以延长超时时间。
  • 我建议从轮询开始,而不是彗星/长轮询/套接字。轮询易于构建和支持,并且在短期内可能会很好地扩展。如果您获得大量流量,则可以将硬件和负载平衡器投入到问题中以进行扩展。整个网络都基于轮询 - 轮询肯定是规模的。有一点,像彗星/长轮询/等替代方案的复杂性是有意义的,但是在额外的开发时间/复杂性得到证明之前,你需要大量的流量。

答案 2

这是每个人在引入彗星和nodejs之前曾经做过的事情。

在我看来,问题是Apache上的PHP请求非常昂贵。如果您的聊天应用程序每秒检查一次消息,您会发现自己处于Apache没有足够的资源来响应请求的情况。我认为需要改进的另一个领域是改善聊天应用程序的上下文。

如果不检索新消息,为什么它每秒更新一次?如果没有消息怎么办?

您可以使用的一些技术;

  • 为您的客户端提供一个轻量级端点,其中包含有关聊天会话的一些上下文,是待处理的新消息,消息数量等。客户端可以通过立即更新来响应此消息,如果没有新消息,则不更新。此终结点可以通过 http 请求提供简单的 json 对象。可以保证此状态消息的大小固定,如果状态的响应未更改,则可以将其衰减。请参阅下一条消息。

  • 在你的javascript轮询中,一个简单的衰减,如果客户端连续几次从服务器收到相同的响应,你可以将轮询增加一个设定的时间,目前你说它是每秒一次。如果这样做,您将递增到每 2,4,6,8,10 秒。一旦来自服务器的响应发生变化,您就可以重置衰减。

需要考虑的一些优化;

  • 使用 PHP 操作码缓存,如 APC。

  • 对所有请求设置较低的超时,您不希望任何请求挂起服务器。

  • 优化您的PHP代码,使其精益快速。

  • 运行一些负载测试以查看限制是什么。

  • 通常对性能进行基准测试,以确保您的应用程序速度更快。

  • 检查 apache 日志,了解应用程序整体运行状况和响应时间的迹象。

当需要扩展时,请添加新服务器并使用负载均衡器分发请求。我使用过Varnish和HAProxy取得了巨大的成功,设置它们也不复杂。