Bigpipe---FaceBook使用的页面加载技术

BigPipe(FaceBook使用的页面加载技术)

 

理论部分:用户输入域名发送请求到服务端,服务端组合出需要的业务数据返回给客户端,这一过程是现在网页请求最基本传统的方式了。

好处:只做了一次http请求,节省了http连接资源

坏处:如果一次请求数据量过大,会比较慢,并且如果整个业务逻辑部分有一处出问题,很可能导致请求错误返回,整个页面拿不到数据甚至瘫痪。

之后局部刷新技术ajax出现了:客户端可以根据需要去向服务端发不同的请求,加载自己所需要的数据资源,这样请求之间互不影响。

好处:独立请求,可以分开加载数据,是作为分离业务逻辑,模块化的加载的好方式。

坏处:分开加载无疑增加了http请求数,特别是模块分的较多,希望都非常独立的时候,这一样势必是在浪费连接资源;要知道在单次请求数据量很小的情况下,http连接资源可能是更昂贵的代价。

 

可能这个时候为了更加有效利用资源facebook的大牛们用了设计者Changhao Jiang (研究电子电路的博士)设计的技术bigpipe,并应用到实地场景中。

毫无疑问,无论是整个页面一次请求还是ajax都是不优雅的,没有有效利用前端和后端之间的时间差:

这种模式有个缺陷:流程中的操作有着严格的顺序,如果前面的一个操作没有执行结束,后面的操作就不能执行,即操作之间是不能重叠。这样就没有有效利用前后端资源:

服务器生成一个页面的内容时,浏览器是空闲的,显示空白内容;而当浏览器加载渲染页面内容时,服务器又是空闲的, 时间与性能的浪费由此产生。

为了在前后端空闲时,更能有效的并行处理自己要干的事情(前端通过数据渲染页面,后端包装数据传给前端),一个理想的方式就这样诞生了:

前端发了一个请求后,后端根据前端的需要分步拿不同模块的数据,拿好一个立即丢给前端去渲染,这个时候的优势就体现出来:前端渲染后端给的第一部分数据的同时,后端在组装第二部分数据,以此类推,这个并行工作就这样展开了,直到完成所有数据的组装和渲染。对于用户来讲看到的效果就是,打开页面立即就有可看到的内容,不会因为后端数据多大或是页面发出的请求过多,卡死页面的渲染。

 

 

实践demo部分:

 在js群友的帮助下找到一个可参考的测试案例:

http://my.oschina.net/hanshubo/blog/130713

代码如下:在使用队列方面没有仔细斟酌,随便找一个过来,就用了。 


注意一点,就是不要把 PrintWriter 的实例对象拿到多线程里去用,否则会出莫名其妙的异常。 

import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class BigPipeServlet extends HttpServlet {
 
    private static ExecutorService executor = Executors.newFixedThreadPool(50);
 
    public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
        final ArrayBlockingQueue<String> q = new ArrayBlockingQueue<String>(6);
 
        for (int i = 0; i < 6; i++) {
            final int id = i + 1;
 
            executor.execute(new Runnable() {
                public void run() {
                    try {
                        Thread.sleep((int) (Math.random() * 10000));
                        q.put(pagelet("content" + id, "Wohooo" + id));
                    } catch (InterruptedException e) {
                    }
                }
            });
        }
 
        response.setContentType("text/html;charset=gb2312");
        PrintWriter out = response.getWriter();
        out
                .println("<html><head>"
                        + "<script type=\"text/javascript\">function arrived(id,text) { var b=document.getElementById(id); b.innerHTML = text; }</script>"
                        + "</head><body>" + "<div>Progressive Loading");
        content(out, "content1", "content2", "content3", "content4", "content5", "content6");
        out.println("</div>");
 
        for (int i = 0; i < 6; i++) {
            try {
                out.println(q.take());
                out.flush();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
 
        out.println("</body></html>");
    }
 
    private void content(PrintWriter writer, String... contentIds) {
        for (String id : contentIds) {
            writer.println("<div id=\"" + id + "\">-</div>");
        }
    }
 
    private String pagelet(String id, String content) {
        return "<script>" + "arrived(\"" + id + "\", \"" + content + "\");" + "</script>";
    }
}

这个案例的服务端是java实现的,有多线程就是有福,不过php也不是不可以,他的模块的扩展能辅助搞定这个问题。

简单讲一下基本做法:

后端创建一个线程池,去维护前端需要的模块数的线程(有几个模块就创建几个线程),然后每个线程response write之后立即flush,这样每个线程的操作就立即返给了前端,

由于http管道只有一个,后端多线程就无法做到多线程并发去flush了,需要堵塞一个个操作或者加锁。做个猜想:如果http管道中也能相应产生多个独立的位置让多线程并发去append到指定的位置,

这样是不是就做到了,多个部分数据可以同时丢给前端。(可能理解有误)

并在前端执行操作。由于不像ajax那样单个请求前后端逻辑完全独立,在bigpipe中,设定好每个模块的顺序就是必须的了。

struts2 自定义标签实现的
https://www.ibm.com/developerworks/cn/java/j-lo-bigpipe/
注:nginx gzip打开时,out.flush无效,怀疑是数据量没达到nginx默认缓存,不会输出,只等到所有数据一起输出,
这样就达不到bipipe的目的了。

成功案例部分:

新浪微博:http://blog.sina.com.cn/s/blog_482611850100xpb1.html

http://v.youku.com/v_show/id_XMzUyOTgyMDY4.html

简单介绍下:

新浪微博提到了用

HTTP协议的chunked编码的方式来处理多个部分

 

 

淘宝:

[浅析]淘宝详情页的BigRender优化的最佳方式

 http://www.csdn.net/article/2011-09-27/304989

 

 

参考:http://www.cnblogs.com/mofish/archive/2011/11/03/2234858.html

 

 

转载于:https://www.cnblogs.com/loveluluxiu/p/3403572.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/259224.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

maven搭建多模块项目和管理

在eclipse下构建maven项目&#xff0c;该项目由多个子模块组成。 1.创建一个父项目 NEW -->project-->maven-->maven Project&#xff0c;点击下一步&#xff0c;进入new maven Project的Select project name and location界面 &#xff0c;什么也不做&#xff0c;直接…

shsh验证服务器,教你从Cydia上取出SHSH并验证有效性!

原标题&#xff1a;教你从Cydia上取出SHSH并验证有效性&#xff01;今天在第一篇内容中和大家说了如何让32位设备进行降级&#xff0c;但这其中有个很重要的问题就是如何提取出对应设备的SHSH&#xff0c;虽然说本篇内容并不是对所有人都有效&#xff0c;但至少多了一个可选择的…

Discuz!$_G变量的使用方法

1&#xff0c;G变量的使用方法&#xff1a;例如&#xff1a;$_G[style][boardlogo]风格变量篇$_G[style] > Array(官方模板区 cr180整理$_G[style][styleid] > 当前风格ID$_G[style][name] > 当前风格名$_G[style][templateid] > 当前模板体系$_G[style][tpldir] &…

n!后面有多少个0(转载)

我的思路&#xff1a; 从”那些数相乘可以得到10”这个角度&#xff0c;问题就变得比较的简单了。 首先考虑&#xff0c;如果N的阶乘为K和10的M次方的乘积&#xff08;N&#xff01;K∗10M&#xff09;&#xff0c;那么N!末尾就有M个0。 如果将N的阶乘分解后&#xff0c;那么…

ico的尺寸_批量压缩、加水印、调整尺寸……用这 6 款 Mac 图片工具一键解决

不论是写文章、做教程&#xff0c;还是处理摄影作品、上传社交平台&#xff0c;对图片的处理肯定少不了。庞大又贵重的专业软件不仅成本较高&#xff0c;还有着不小的上手难度。如果我们仅仅是想要&#xff1a;缩小图片体积、添加水印或者批量对图片进行操作等等&#xff0c;使…

转:MAC 下安装PHONEGAP开发环境

MAC 下安装PHONEGAP开发环境 什么是Phonegap呢&#xff1f;Phonegap是一个利用HTML5去开发App的框架。可以为安卓、iOS、WP、黑莓、火狐等移动操作系统。采用HTML5来编写交互界面。其优点是编写一次可以编译到各种移动平台上&#xff0c;大大为公司节省了开发周期。但是它也是有…

Sql 行转列问题总结

1、行转列---1、最简单的行转列 /* 问题&#xff1a;假设有张学生成绩表(tb)如下: 姓名 课程 分数 张三 语文 74 张三 数学 83 张三 物理 93 李四 语文 74 李四 数学 84 李四 物理 94想变成(得到如下结果)&#xff1a; 姓名 语文 数学 物理 李四 74 84 94 张三 74 8…

寻找第K大的数字

寻找第k大的数字&#xff0c;有很多方法&#xff0c;最基本的就是将数组按照从大到小的顺序排列&#xff0c;找出第k个元素即可。但是这种方法的时间复杂度为o(nlog(n)),我们还能找到更好地方法。下面我们将介绍另外两种办法&#xff0c;一种是基于快排Partition的方法&#xf…

(12)MSP430F5529 常用内置函数和一些说明

&#xff08;1&#xff09; MSP430F5529支持最高工作频率为25MHZ&#xff0c;也就是说你通过 锁相环倍频来提高系统运行速度是有一个限制的&#xff0c; 最高只能到25MHZ&#xff08;再高没意思了&#xff09;。 &#xff08;2&#xff09;几个重要的内联函数 &#xff08;内联…

从零开始学android编程_android初学者的入门秘籍

大概是去年年底开始接触android原本是学习嵌入式的我&#xff0c;领导让我看看能不能搞一下这个android APP。一开始的我懵逼得很。。。这android APP 不是得用java写吗&#xff1f;&#xff1f;&#xff1f; 现在我看网上说比较多还是用kotlin&#xff0c;没去学。。。好家伙&…

修改了sql默认路径无法登录服务器,PostgreSQL错误'无法连接到服务器:没有这样的文件或目录'...

像其他一些人一样,当我在我的项目中运行rake db:migrate或者甚至为我的Ruby on Rails 3.2应用程序尝试大多数数据库任务时,我收到此错误.PGError(无法连接到服务器:没有这样的文件或目录.服务器是否在本地运行并接受Unix域套接字上的连接"/tmp/.s.PGSQL.5432"&#x…

QMarkDowner编译

第一次完整的编译一个工程。哈哈 记录一下 准备环境 我的环境是win7 x64, python2.7.5 x64的。 python 3.x的我没试过,有需要的朋友可以试一下。 安装python2.7.5 x64 确保将安装路径加入到Path中 PyQt4 啊 我的环境是win的 当然要下win版 (PyQt4-4.10.3-gpl-Py2.7-Qt4.8.5-x6…

C++ STL的查找算法

假设你有一个序列容器&#xff0c;或者有一对迭代器标识了一个区间,现在你希望在容器中查找一些信息&#xff0c;这样的查找工作如何进行呢&#xff1f;你的选择往往是&#xff1a; count,count_if,find,find_if,binary_search,lower_bound,upper_bound,equal_range.该如何选择…

习题七

umask 022 &#xff0c;请描述该命令的含义创建目录时默认的权限为&#xff1a;755 rwxr-xr-x创建文件时默认的权限为&#xff1a;644 rw-r--r--note:创建文件的默认权限是拿掉了X 所以最大为666&#xff0c;而目录最大为777 umask NUM 就是去掉相应的权限转载于:https://blo…

web中的cookie管理

本篇是以JSP为背景介绍&#xff0c;但是在web开发中也是相同的原理。 什么是cookie 由于http是一种无状态的协议&#xff0c;因此服务器收到请求后&#xff0c;只会当做一次新的请求。即便你重复发送了1000次同样的请求&#xff0c;这1000次都属于独立的请求。 这样显然效率很低…

unity怎么设置游戏页面_杭州有没有正规的unity游戏开发培训机构?

现在Unity游戏开发是个火热的行业&#xff0c;薪资待遇比较高&#xff0c;未来的发展方向和前景也比较不错&#xff0c;很多人也都想成为专业Unity游戏开发工程师&#xff0c;学习Unity游戏开发已经成为很多追求更好就业前景的人的选择。学习专业、系统的Unity游戏开发知识并达…

VC++ 使用attributes定义接口

1.定义预处理命令_ATL_ATTRIBUTES 2.在一个全局的Cpp文件里面配置module的attribute [module(dll, uuid "{3845951F-15B8-4286-8E7D-E9D4F5C7B6CE}", name "TestApp")]3.定义接口 [object,uuid("9F414A8A-1D5E-4aff-A60E-CFD65155ABB6"),dual,…

h3c 虚拟服务器 下一跳,H3CNE 312题和313题 直连路由静态路由的下一跳问题

321.在MSR 路由器上看到路由表里有如下显示&#xff1a; Destination/Mask Proto Pre Cost NextHop Interface 127.0.0.0/8 Direct 0 0 127.0.0.1 InLoop0 127.0.0.1/32 Direct 0 0 127.0.0.1 InLoop0 192.168.96.0/19 Direct 0 0 192.168.120.153 S6/0 那么关于目的地321.在MS…

C++成员变量的初始化顺序问题

先来看两道题&#xff1a; // count algorithm example #include <iostream> // std::cout #include <algorithm> // std::count #include <vector> // std::vector using namespace std; class A { public:A() { cout << "in A()&q…

Knockout.Js案例一Introduction

在这第一个教程中,您将体验的一些基本知识构建的web UI Model-View-ViewModel使用knockout.js(MVVM)模式。案例1&#xff1a;添加:data-bind <p>First name: <strong data-bind"text:firstName">1</strong></p><p>Last name: <stro…