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.pswp.cn/news/259224.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/259224.shtml
英文地址,請注明出處:http://en.pswp.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…