Long polling

这两天在公司的项目里用了 Long polling,了解了它的实现原理,其实不像它的名字那么玄乎,只是 Ajax 和 HTTP 的类似小妙招的办法。

先解释一下 Long polling 是什么:

首先得说到传统的 Polling,Polling 是 Ajax 隔一段时间去抓取服务器上的数据,检查数据是否更新,但这样有很大问题,首先是每次请求会实用一个  HTTP request,对应的服务器就得建一个新的线程来处理这个 HTTP request,消耗网络流量、服务器资源不说,绝大多数情况下,数据短时间内是不会更新的,也就是说绝大多数的 Ajax 请求都只能无功而返。

而 Long polling 就是用来解决这个问题的。


它的核心是:
1. 做一个超时非常长的 Ajax 请求,并且在错误捕获代码里不断执行自己。2. CGI 部分接收到请求后在限定的时间内(Ajax 超时时间内)每隔一段时间(例如一秒)对数据库进行查询,可以使用 sleep 类似的方法。
3. 如果有新的数据则返回,如果即将到 Ajax 超时的时间则返回一个错误值,比如 404,这样那个非常长的 Ajax 请求会再发一个过来,继续查询。

这个办法的最大价值是有效减少了 HTTP 请求数,对服务器而言就不用开启新的线程去处理它,旧的线程如果不是因为超时,则只会在数据已经更新的情况下返回数据。可以节约大量资源,而且实时性更高。

目前,人人网的消息提示、Web 版阿里旺旺、新浪微博的新微博提示应该都是使用这种方法做的。

但这个办法对开发有一定困扰,Django 内置的 Web service 是单线程的,一个非常长的 Ajax 请求会占用那唯一一个线程,导致别的请求无法响应。

所以最好做好两套配置,一套用于产品环境的多线程环境,一个用于开发的单线程环境。

我依然对那位在现有架构下想出这种办法的人表示钦佩。

这儿有范例代码,简单又实用:http://stackoverflow.com/questions/333664/simple-long-polling-example-code

Posted by K*K Fri, 08 Jul 2011 17:49:20 +0800