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

IT技术 php javascript ajax sockets
2021-02-21 12:04:25

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

我考虑过的事情:

  • HTML5 Web Sockets:没有使用它,因为它不适用于所有浏览器(仅 chrome)。
  • Flash Sockets:没有使用这个,因为我想最终支持移动网络。

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

3个回答

一些注意事项:

  • 每秒轮询一次是矫枉过正的。该应用程序仍然会感觉非常灵敏,检查之间会有几秒钟的延迟。
  • 为了节省数据库的流量和速度响应,请考虑使用内存缓存来存储未传递的消息。您仍然可以将消息保存到数据库中,内存缓存将仅用于查询新消息,以避免每个用户每 x 秒查询一次数据库。
  • 在 x 秒不活动后超时用户的聊天以停止轮询到您的服务器。这可以确保打开窗户的人不会继续产生流量。提供一个简单的“还在吗?继续聊天。” 超时会话的链接并在超时之前警告用户,以便他们可以延长超时。
  • 我建议从轮询而不是彗星/长轮询/套接字开始。轮询很容易构建和支持,并且可能会在短期内很好地扩展。如果您获得大量流量,您可以将硬件和负载平衡器用于解决问题以进行扩展。整个网络都基于轮询——轮询无疑是规模化的。在某种程度上,彗星/长轮询/等替代方案的复杂性是有意义的,但在证明额外的开发时间/复杂性之前,您需要大量流量。
你的最后一点非常有帮助 - 我一直在努力确定我的应用程序中的第一个轮询实现需要如何面向未来,我想我会接受你的建议并快速进行简单的轮询,然后计划一个聪明的长期- 期限解决方案。
2021-04-21 12:04:25

这是在 Cometd 和 nodejs 引入之前每个人都做过的事情。

我看到的问题是 Apache 上的 PHP 请求非常昂贵。如果您的聊天应用程序每秒都检查消息,您会发现 Apache 没有足够的资源来响应请求。我认为需要改进的另一个方面是改进聊天应用程序的上下文。

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

您可以使用的一些技术;

  • 为您的客户端提供一个轻量级端点,该端点具有一些关于聊天会话的上下文、是否有新消息待处理、有多少消息等。如果没有新消息,客户端可以通过立即更新或不更新来对此做出响应。这个端点可以通过 http 请求提供一个简单的 json 对象。您可以保证此状态消息的大小是固定的,如果状态的响应没有改变,您可以衰减它。见下一条消息。

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

一些需要考虑的优化;

  • 使用像 APC 这样的 PHP 操作码缓存。

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

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

  • 运行一些负载测试以查看您的限制。

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

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

当需要扩展时,添加一个新服务器并使用负载均衡器来分发请求。我已经成功使用 Varnish 和 HAProxy,设置它们也不复杂。

动态增量是我从来没有想过的,真的很好
2021-04-19 12:04:25

如果我是你,我会选择一个使用 html5 网络套接字的库,但如果 html5 不可用,则依赖于 Flash 套接字,那么通过破解的浏览器应该是分钟。

此外,您应该放弃 php 或使用 em-websocket 用 python 或 ruby​​ 编写的线程套接字服务器补充它。