`

借鉴bigpipe思路在项目ajax调用时的一点改进

 
阅读更多

要处理的情况:
一次用户请求,后台要处理业务:

step1,查询并大数据且复杂的业务处理,得到结果集A;
step2,基于结果集A,调用web service查询结果集B
step3,将A和B显示在页面上

 

之前的方案就是在step1完成后就直接进入step3显示A的信息,然后在页面渲染完后,用ajax,基于页面上的A的信息,异步到后台调用web service查询结果集B,然后再重画部分页面。这个方案是常用的提高用户体验的方法,减少用户的等待时间,尽早的将部分有效的信息响应给用户,后续用ajax逐步补充剩下的信息。
这种方案确实帮我们提高了用户体验,不过现实中的问题还有。。那就是step2的通过web service去查询结果集B的时间有些长,具体说,就是在渲染完第一步结果集A后,我们在页面前端放置了些转动的圈圈类表示仍有部分信息正在loading,而这个圈圈转动的时间有点长,有时候用户看完结果集A后,还没渲染。。这确实头大,在web service调用那块进行了tuning,结果并不乐观。


后来看了facebook的bigpipe技术,其使得用户感受到的延迟时间降低了一半,具体的关于bigpipe的信息,可参考:
http://www.searchtb.com/2011/04/an-introduction-to-bigpipe.html

 

具体的bigpipe实现在我们项目中实现难度较大,评估了下还是放弃了,不过相比较正常的ajax的处理,bigpipe从最终实现上至少减少了部分数据传输时间,部分页面渲染时间,和不少于一次的服务器再次交互发起时间等,所以我思考是否可以将上面的结果集B的查询还是放在第一次查询的请求中进行,只不过可以另起一个线程去跑,启动后,拿结果集A去渲染页面,本次交互结束,后续仍然通过ajax来取回结果集B,类似于将bigpipe的部分思路通过服务器代码实现,手工完成。具体的执行步骤:
1.用户发起请求
2.服务器端进行step1的操作,得到结果集A
3.生成一个token,并另起线程,将结果集A及token传入这个线程,进行B的查询。
  注意:这里的线程不能源于主线程,否则当主线程结束时,子线程似乎也断了,可以独立出一个线程池,从线程池中取线程使用。在新线程中,如果B查询结束,以token为key,以B为value存在session里.
4.处理结果集A的数据结构,便于页面渲染,然后返回
5.根据返回信息渲染页面,并发出ajax请求,参数为token
6.服务器端根据token去session里取得结果集B,如果这时还没有,则设置等待,等待时间设置为个适当的时间,譬如最多20S,还没出结果可以当成没有结果集B匹配。否则将B返回渲染页面。

 

上面的实现步骤相比较正常的ajax处理,省去了4,5两步的时间,目前已经在我们产品线上运行。

当然,这种方案更适合并发响应少的应用上。

 

写得有点乱,不过也只是个小尝试,并非什么技术难点,只是做个笔记。

 

 

分享到:
评论
1 楼 helloqidi 2013-06-04  
  cool,谢谢分享

相关推荐

Global site tag (gtag.js) - Google Analytics