欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

緩存(二)

系統 1669 0

? 在我們打開瀏覽器 , 決定瀏覽某個網頁之前 ( 指人眼看到屏幕上的內容之前 ), 一般來說瀏覽器有幾個事情要做 , 首先根據 url 請求服務器端的 html html 顯示到屏幕上等等 . à 下載 css, js,-------- à , 然后解析 html,------ à 數據 ------ 接著大腦才能感受到 . à 然后眼睛才能感受到 ,-------- à ---------

在這個流程中 , 那么怎么才能讓大腦盡可能快的接受到這個信息呢 , 我想最快的方式是在大腦里放一份該屏幕的拷貝 , 下次想看這份內容的時候直接拿出大 腦的拷貝就可以了 . 如果大腦容量有限 , 那我們可以考慮把這份拷貝放到眼睛里 , 如果眼睛也放不下 , 那我們可以考慮把這份拷貝放到瀏覽器里 , 從這個邏輯上看 , 越靠近大腦的數據越能快速的被我們接受到 .

那么本文的目的其實就是為了研究如何使用大腦和眼睛來緩存數據 ------------------------ 吃驚吧 ,ahuaxuan 瞎扯的 , 回到正題 , 上面這段調侃不是為了說明別的 , 而是為了說明越靠近用戶的數據被用戶感受到的速度就越快 . 也就是近與快的關系
.

接著再讓我們拋開緩存先不說 , 來說說 CDN 和鏡像的問題 ,CDN 的英文名字叫 CDN, 中文名字一般還是 CDN( 請換個調朗誦 ). 呵呵 ,CDN 中文名字是內 容分布網絡 , 簡單來說就是把內容分布出去 , 比如放到全國幾個地方 , 舉例來說做一個圖片服務 , 上海的用戶請求某個圖片服務器 , 那么只需要返回某個離上海最近 CDN 節點上的圖片 , 而不需要路由到北京或者云南的節點上去取數據 , 您要問為啥呢 , 因為快啊 , 上海的用戶訪問北京節點的數據顯然在路由層次上 , 網絡時間 消耗上都要多出很多 , 這說明啥呀 , 還是那個理兒 : 近就會快啊


一般來說 CDN 都是放一些圖片 , 視頻 , 文檔之類的數據 , 那么元數據呢 , 放一塊兒 , 當然也不是 , 這時候可以用鏡像來解決元數據的問題 , 于是變成了上海的用戶訪問上海的鏡像 , 北京的用戶訪問北京的鏡像 . 這還不是就地取材比較方便嘛
.

, 說到這里 , 想必大家對近和快的關系有了一定的認識了 , 下面我們來看看如何把這種原理或者規則運用到緩存中去
.

下面讓 ahuaxuan 和大家先調查一下離眼睛最近的是什么 , 顯示器 ( 別跟我說是屏幕保護膜和鍵盤哈 , 鼠標也不行 ), 不過這些是硬件呀 , 那軟的 , 非瀏覽器莫數了 . 也就是說如果我們把一些可以緩存在瀏覽器上的數據緩存到瀏覽器上 , 那就能加快我們的頁面響應速度了 . 也就是說我們現在找到一個地方 , 也許可以放一點可以緩存的數據
.

下面我們要考察考察什么樣的數據可以緩存在瀏覽器上 , 以及緩存在瀏覽器上的一些優缺點或者限制因素

什么樣的數據可以緩存在瀏覽器上
?
瀏覽器上無法就幾種數據 ,html,css,js,image, . 那么接著我們來看看他們的變化特性
,
html
數據很多情況下是動態的 , 但是也有很多情況下是某個時間段內可以是靜態的
.
Css
一般是靜態的

Js
一般也是靜態的

Image
一般也是靜態的
.

, 看上去后幾者基本都可以緩存在瀏覽器 , html 是否緩存要看 html 中數據的特性了 . 那么問題來了 , 瀏覽器是依據什么設置來緩存 html, 或者 css, 或者 js 的呢 . 答曰 ,expires 或者 max-age.
Expires
代表該份數據緩存到瀏覽器上 , 直到某個時間點后過期 , max-age 表示緩存在瀏覽器上直到某個時間段之后過期
.

對于靜態內容:設置文件頭過期時間 Expires 的值為 “Never expire” (永不過期)

動態頁面 , 在代碼中添加 cache-control, 表示多少時間之后過期 ,
:
response.setHeader("Cache-Control", "max-age=3600");
表示 1 個小時后過期 , 即在瀏覽器上緩存一個小時
.

但是這樣問題又來了 , 如果設置 10 天后過期 , 那我明天就要改變 ,css,js 都變了 , 咋辦吶 , 答曰 , 加版本號吧 , 這樣瀏覽器就會重新加載新的 css js
.
但是如果是動態數據 , 那就沒有折了 , 所以動態數據的 max-age 一般不推薦太大 , 否則啊 , 您吶 , 就得挨個通知您得用戶按一下 Ctril+F5
.

一般來說靜態數據需要緩存 , 我們一般通過 webserver( apache,lighttpd 之流 ), 只需要配置一下即可 , 而動態數據是比較重 要的 , 因為其改變的周期段 , 而且只能由 servlet 容器或者 fastcgi 之類的服務器返回 , 所以其應付大量并發的能力是有限的 . 那么這里理論上可能有 一個瓶頸 , 就是如果訪問的獨立用戶較多 , 那么這份動態數據還是會被請求 1* 用戶數 = n , 那么我們可以想象 , 一樣的請求對于我們的 servlet 容器或者 fastcgi 來說其實是多余的 , 我們可以想一個方法 , 把這些一樣的請求擋在 servlet 容器或者 fastcgi 進程之前
.

正如在第一說中說到的 , 在瀏覽器和 servlet 容器或者 fastcgi 進程之間 , 還有很大的空間可以發揮 , 在這一部分的緩存 ,ahuaxuan 稱之為
webcache.

目前在 webcache , 最流行的估計就屬 squid , 然后還有 varnish 等等 . 為了有一個比較直觀的感受 , 我們來看看下面這張圖唄
:

緩存(二)
?
從這張圖上 , 我們可以看出 , 瀏覽器 1 在請求了一份數據之后 , 其實這份數據已經在 webcache 上了 , 瀏覽器再來請求 2 的時候 , 請求到了 webcache 這層就返回了 , 這樣就降低了 servlet container 的壓力了 . 雖然說我們在 servlet 容器上也是可以建 page cache, 但是畢竟 servlet 本身的并發能力有限 .( 如何在 servlet container 上使用 page cache : http://www.iteye.com/topic/128458 )

而且更重要的是一般 webcache 的并發能力要比 servlet container 或者 fastcgi process 要高出很多 ( 沒辦法 , 誰叫它是專業的 cache ). 所以使用 webcache 也能夠提供更高訪問量的服務 . 一舉多得 , 何樂而不為呢 . 但是聲明一下 , 您吶 , 別以為上 面這種方式是標準方式 , 我們還有 webserver, 負載均衡器等等 , 上圖只是為了便于說明本文的論點 , 而且互連網需求和解決方案層出不窮 , 切不可以胡搬 亂套 , 還是要分析分析再分析 , 思考 , 思科再思考 .

說到這里即使以前沒有接觸過得筒子大概也明白了 web cache 得作用了 . 下面我們再來看看如何使用 web cache , 呵呵 , 其實和瀏覽器上緩存數據得方式一樣 . 也是通過在 response header 中指定 expires 或者 max-age 來實現的 .( 但是據 ahuaxuan 觀察在使用 squid 的時候有一個要求 , 瀏覽器的請求必須滿足 http 的語義 , 也就是說只有 method=get 的時候 web cache 才能緩存數據 , 如果是 post, 那么 web cache 認為這個是一個創建數據的請求 , 并不會緩存其返回結果
.)

Squid,
如果您要系統的學習 squid, 請看
:
http://www.squid-cache.org/ ????? http://blog.s135.com/book/squid/

補充 , 在有些情況下 ,web cache 中的數據很有可能是有狀態的 . 比如根據瀏覽器的 locale 返回不同的數據 , 那么雖然訪問的 url 是一樣的 , 但是返回的值卻是不一樣的 , 咋辦 , 別擔心 , 我們有 vary, 只要在 response 里指定 vary 參數為 accept-language ok. 您也可以指定為 cookie 中的值 , 就完全看您的需要了 . 如果您還是不明白 vary 的作用 , 請看 : http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.44

總結 :
說到這里 , 關于近和快的話題也基本可以結束了 ( 這個話題再寫下去就變成裹腳布了 ). 所以一般情況下 , 我們可以認為有如下事實 :” == ”, 但是 近和快并不只是表現在人的體驗上 , 如果換個角度 , 速度的感受者不是人 , 而是機器 , 那么我們也可以這么認為 local cache remote cache 更靠近 cpu, 所以 local cache 的速度更快 ( 當然他們的功能不是重疊的 , 各自適用的場景不一樣而已 , 而且很多情況下他們可以配合使用 , 在后續的文章中將會討論這個問題

).

如何在只使用 tomcat 的情況下 , 自動緩存 js css 或者 image 等文件 .
第一步 : 寫一個 filter, 可以根據路徑的正則來判斷該路徑的請求是否需要設置 max-age:

    public class CacheFilter implements Filter{  
  
    private static transient Log logger = LogFactory.getLog(CacheFilter.class);  
      
    private Integer cacheTime = 3600 * 24;  
    private List<Pattern> patternList = new ArrayList<Pattern>();  
      
    private static ResourceBundle rb = ResourceBundle.getBundle("cache-pattern");  
    public void destroy() {  
          
    }  
  
    public void doFilter(ServletRequest rq, ServletResponse rqs,  
            FilterChain fc) throws IOException, ServletException {  
          
        fc.doFilter(rq, rqs);  
        if (rq instanceof HttpServletRequest && rqs instanceof HttpServletResponse) {  
            HttpServletRequest request = (HttpServletRequest) rq;  
            HttpServletResponse response = (HttpServletResponse) rqs;  
              
            if (matchPattern(request.getRequestURI())) {  
                response.setHeader("Cache-Control", "max-age=" + cacheTime);  
                if (logger.isDebugEnabled()) {  
                    StringBuilder sb = new StringBuilder();  
                    sb.append(" set cache control for uri = ").append(request.getRequestURI());  
                    sb.append(" and the cache time is ").append(cacheTime).append(" second");  
                    logger.debug(sb.toString());  
                }  
            }  
          
        } else {  
            if (logger.isWarnEnabled()) {  
                logger.warn("---- the request instance is not instanceof HttpServletRequest ---");  
                logger.warn("---- the response instance is not instanceof HttpServletResponse ---");  
            }  
        }  
          
    }  
  
    public void init(FilterConfig arg0) throws ServletException {  
        Enumeration<String> keys = rb.getKeys();  
        while (keys.hasMoreElements()) {  
            String p = keys.nextElement();  
            String value = rb.getString(p);  
            patternList.add(Pattern.compile(value, Pattern.CASE_INSENSITIVE));  
              
            if (logger.isInfoEnabled()) {  
                logger.info(">>>>>>>>>>> init the cache pattern " + value);  
            }  
        }  
          
        if (arg0 != null) {  
            String ct = arg0.getInitParameter("cache-time");  
            if (!"".equals(ct) && null != ct) {  
                cacheTime = new Integer(ct);  
                if (logger.isInfoEnabled()) {  
                    logger.info(">>>>>>>>>> the cache time is " + cacheTime);  
                }  
            }  
        }  
    }  
      
    private boolean matchPattern(String url) {  
        for (Pattern pattern : patternList) {  
            if (pattern.matcher(url).matches()) {  
                return true;  
            }  
        }  
          
        return false;  
    }  
  
    public static void main(String [] args) throws ServletException {  
        CacheFilter cf = new CacheFilter();  
        cf.init(null);  
        System.out.println(cf.matchPattern("/css/prototype.CSS"));  
    }  
}  

  

?

第二步 : classpath 路徑下創建一個 cache-pattern.properties 文件 , 內容如下 :

Java 代碼

1?=?.*ext-all.js??

2?=?.*prototype.js??

3?=?.*/css/.*\\.css??

1 = .*ext-all.js

2 = .*prototype.js

3 = .*/css/.*\\.css


在這個配置文件中 , 您可以根據 js css 的路徑來配置哪些目錄 , 或者哪些文件需要設置 max-age.

第三步 :
web.xml 添加如下內容 :

Java 代碼

<filter>??

?????????<filter-name>cache-filter</filter-name>??

?????????<filter-class>com.filter.CacheFilter</filter-class>??

?????????<init-param>??

????????????<param-name>cache-time</param-name>??

????????????<param-value>86000</param-value>??

????????</init-param>??

????</filter>??

??

<filter-mapping>??

????????<filter-name>cache-filter</filter-name>??

????????<url-pattern>*.js</url-pattern>??

????</filter-mapping>??

??????

????<filter-mapping>??

????????<filter-name>cache-filter</filter-name>??

????????<url-pattern>*.css</url-pattern>??

</filter-mapping>??

<filter>

??????? ? <filter-name>cache-filter</filter-name>

??????? ? <filter-class>com.filter.CacheFilter</filter-class>

??????? ? <init-param>

??????????? <param-name>cache-time</param-name>

??????????? <param-value>86000</param-value>

??????? </init-param>

??? </filter>

?

<filter-mapping>

??????? <filter-name>cache-filter</filter-name>

??????? <url-pattern>*.js</url-pattern>

??? </filter-mapping>

???

??? <filter-mapping>

??????? <filter-name>cache-filter</filter-name>

??????? <url-pattern>*.css</url-pattern>

</filter-mapping>



如此 3 , 就可以將 js css 文件緩存于無形 . 快哉 .

倉卒之間成文 , 再加上 ahuaxuan 水平有限 , 本文如有紕漏之處 , 還望各位看官您不吝指正 , 先謝過了 .

?

?

?

?

?

?

?

?

?

緩存(二)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产精品免费观看 | 国产在线精品一区二区三区 | se就是色94欧美setu | 亚洲欧洲中文日韩久久AV乱码 | 国产精品99爱免费视频 | 日本久久网 | 97色伦图片97综合影院 | 一国产一级淫片a免费播放口 | 欧美日本中文字幕 | 清纯唯美综合 | 精品国产第一国产综合精品gif | 四虎在线免费观看 | 欧美激情在线观看一区二区三区 | av中文字幕在线 | 国产精品国产成人国产三级 | 日日干天天摸 | 中文字幕亚洲欧美 | 91精品视频在线播放 | 亚洲a网 | 国产精品免费观看视频 | 色网址在线 | 欧美福利视频一区二区三区 | 亚洲午夜久久久久中文字幕久 | 三级视频在线观看 | 看免费黄色大片 | 草草国产成人免费视频 | 青青青青手机在线视频观看国产 | 狠狠躁日日躁夜夜躁A片小说按摩 | 日本在线国产 | 久久网精品视频 | 91精品国产777在线观看 | 性夜黄 a 爽免费看 性xxxxx视频 | 性夜黄a爽爽免费视频国产 尤物tv在线 | 99久久免费费视频在线观看 | 亚洲成在人线中文字幕 | 光根电影院 | 国产高清在线视频 | 天天摸天天操天天干 | 五月激情综合婷婷 | 亚洲国产aⅴ成人精品无吗 国内成人自拍视频 | 亚洲成人精品在线观看 |