<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        ASP.NET Cache的一些總結分享

        來源:懂視網 責編:小采 時間:2020-11-27 22:42:25
        文檔

        ASP.NET Cache的一些總結分享

        ASP.NET Cache的一些總結分享:1.1.1 摘要 最近我們的系統面臨著嚴峻性能瓶頸問題,這是由于訪問量增加,客戶端在同一時間請求增加,這迫使我們要從兩個方面解決這一問題,增加硬件和提高系統的性能。 大家可以通過各種各樣的方法去優化我們系統,本篇博文將介紹通過Cache方法來優化系統的
        推薦度:
        導讀ASP.NET Cache的一些總結分享:1.1.1 摘要 最近我們的系統面臨著嚴峻性能瓶頸問題,這是由于訪問量增加,客戶端在同一時間請求增加,這迫使我們要從兩個方面解決這一問題,增加硬件和提高系統的性能。 大家可以通過各種各樣的方法去優化我們系統,本篇博文將介紹通過Cache方法來優化系統的

        1.1.1 摘要
        最近我們的系統面臨著嚴峻性能瓶頸問題,這是由于訪問量增加,客戶端在同一時間請求增加,這迫使我們要從兩個方面解決這一問題,增加硬件和提高系統的性能。

        大家可以通過各種各樣的方法去優化我們系統,本篇博文將介紹通過Cache方法來優化系統的性能,減輕系統的負擔。

        1.1.2 正文

        不同位置的緩存

        在Web應用程序中的使用緩存位置主要有:客戶端瀏覽器緩存、客戶端和服務器中以及服務器端,因此緩存可以分為以下幾類:

        客戶端緩存(Client Caching)
        代理緩存(Proxy Caching)
        反向代理緩存(Reverse Proxy Caching)
        服務器緩存(Web Server Caching)
        ASP.NET中的緩存
        ASP.NET中有兩種緩存類型:輸出緩存和數據緩存。

        輸出緩存:這是最簡單的緩存類型,它保存發送到客戶端的頁面副本,當下一個客戶端發送相同的頁面請求時,此頁面不會重新生成(在緩存有限期內),而是從緩存中獲取該頁面;當然由于緩存過期或被回收,這時頁面會重新生成。

        數據緩存

        除此之外,還有兩個特殊的緩存:片段緩存和數據源緩存。

        片段緩存:這是一種特殊的輸出緩存,它不是緩存整個頁面,而是緩存部分頁面;由于緩存整個頁面通常并不可行,因為頁面的某些部分是針對用戶定制的(例如用戶登陸信息),但我們可以把應用程序中共享的部分進行緩存,這時我們可以考慮使用片段緩存和用戶控件緩存。

        數據源緩存:是建立在數據源控件的緩存,它包括SqlDataSource、ObjectDataSource和XmlDataSource控件。數據源緩存使用數據緩存方式,不同的是我們不需要通過顯示方法處理緩存;我們只需設置相應的屬性,然后數據源控件就能存儲和檢索數據。

        輸出緩存
        輸出緩存可以把最終呈現的頁面緩存起來,當客戶端再次請求同一頁面時,控制對象不再重新創建,頁面的生命周期不再啟動,無需再次執行代碼,通過在緩存中獲取緩存的頁面。

        現在我們設計一個頁面,每當用戶發送頁面請求時,就獲取當前代碼執行的時間,然后顯示在頁面上。

        圖1輸出緩存

        這是再簡單不過的例子,每當用戶發送頁面請求都會更新頁面顯示的時間,這是由于每次請求都獲取了一個新的頁面,實際情況中,我們并不需要實時的響應用戶每個頁面請求,我們可以通過輸出緩存把頁面緩存起來每當用戶發送同一頁面請求時,而且在緩存有效期間,可以通過輸出緩存把緩存的頁面返回給用戶。

        我們要實現輸出緩存,只需在頁面中添加如下代碼:
        代碼如下:


        <!-- Adds OutputCache directive -->
        <%@ OutputCache Duration="23" VaryByParam="None" %>

        它支持五個屬性,其中兩個屬性Duration和VaryByParam是必填的

        Duration

        必需屬性。頁面應該被緩存的時間,以秒為單位。必須是正整數。

        Location

        指定應該對輸出進行緩存的位置。如果要指定該參數,則必須是下列選項之一:Any、Client、Downstream、None、Server 或 ServerAndClient。

        VaryByParam

        必需屬性。Request 中變量的名稱,這些變量名應該產生單獨的緩存條目。"none" 表示沒有變動。"*" 可用于為每個不同的變量數組創建新的緩存條目。變量之間用 ";" 進行分隔。

        VaryByHeader

        基于指定的標頭中的變動改變緩存條目。

        VaryByCustom

        允許在 global.asax 中指定自定義變動(例如,"Browser")。

        表1
        輸出緩存屬性

        這里我們把輸出緩存的有效期設置為23秒,也就是說,當緩存超過有效期就會被回收;當用戶再次請求該頁面時,就要重新創建頁面。

        客戶端緩存
        另一種選擇是客戶端緩存,如果用戶在瀏覽器中點擊“后退”按鈕或在地址欄中重新輸入URL,那么在這種情況下,瀏覽器將從緩存獲取頁面;然而,如果用戶點擊“刷新”按鈕,那么瀏覽器中緩存將失效,瀏覽器發送頁面請求。

        如果我們要使用客戶端緩存,只需指定OutputCache中的屬性Location=”Client”就OK了,具體代碼如下所示:

        代碼如下:


        <!-- Sets client OutputCache -->
        <%@ OutputCache Duration="23" VaryByParam="None" Location="Client" %>

        通過在OutputCache中添加Location屬性,我們實現了客戶端緩存,通過設置客戶端緩存我們能夠減少的客戶端請求,也許有人會問:“每個用戶第一次頁面請求都需要服務器來完成,這不能很好的減少服務的壓力”。的確是這樣,相對于服務器緩存,客戶端緩存并沒有減少代碼的執行和數據庫的操作,但是當我們把包含個性化數據的頁面緩存在服務器中,客戶端請求頁面時,由于不同的用戶個性化數據不同,這將會導致請求出現錯誤,所以我們可以使用片段緩存把公用的部分緩存起來或客戶端緩存把用戶信息緩存起來。

        Query String緩存
        在前面的例子中,我們把OutputCache中的VaryByParam屬性設置為None,那么ASP.NET程序只緩存一個頁面副本;如果頁面請求包含查詢參數,那么在緩存的有效期內,我們只可以查看到只是緩存結果,假設我們有個報表程序,它提供用戶根據產品名稱查詢相關的產品信息。

        首先我們創建兩個頁面:查詢和結果頁面,由于時間關系我們已經把頁面設計好了,具體如下所示:

        cahce1

        cache2

        圖2報表程序

        首先我們提供查詢頁面,讓用戶根據成品名稱(ProductName)查詢相應的成品信息,具體的代碼如下:
        代碼如下:


        protected void Page_Load(object sender, EventArgs e)
        {
        if (!Page.IsPostBack)
        {
        // Gets product id from table Production.Product.
        // Then binding data to drop down list control.
        InitControl(GetProductId());
        }
        }
        /// <summary>
        /// Handles the Click event of the btnSubmit control.
        /// Redirects to relative product information page.
        /// </summary>
        protected void btnSubmit_Click(object sender, EventArgs e)
        {
        Response.Redirect(string.Format("Product.aspx?productname={0}", ddlProductName.SelectedValue));
        }

        當用戶點擊Submit按鈕后,跳轉到Product頁面并且在Url中傳遞查詢參數——產品名稱(ProducName)。

        接下來,我們繼續完成查詢頁面,由于在前一頁面中傳遞了查詢參數ProductName,那么我們將根據ProductName查詢數據庫獲取相應的產品信息,具體代碼如下所示:
        代碼如下:


        protected void Page_Load(object sender, EventArgs e)
        {
        // Get product name.
        string productName = Request.QueryString["productname"];

        // Binding data to data grid view control.
        InitControl(this.GetData(productName));
        }

        /// <summary>
        /// Inits the control.
        /// </summary>
        /// <param name="ds">The dataset.</param>
        private void InitControl(DataSet ds)
        {
        dgvProduct.DataSource = ds;
        dgvProduct.DataBind();
        }

        /// <summary>
        /// Gets the data.
        /// </summary>
        /// <param name="productName">Name of the product.</param>
        /// <returns>Returns dataset</returns>
        private DataSet GetData(string productName)
        {
        // The query sql base on product name.
        string sql =
        string.Format(
        "SELECT Name, ProductNumber, SafetyStockLevel, ReorderPoint, StandardCost, DaysToManufacture "
        + "FROM Production.Product WHERE ProductNumber='{0}'",
        productName);

        // Get data from table Production.Product.
        using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLCONN"].ToString()))
        using (var com = new SqlCommand(sql, con))
        {
        com.Connection.Open();
        ////gdvData.DataSource = com.ExecuteReader();
        ////gdvData.DataBind();
        var ada = new SqlDataAdapter(com);
        var ds = new DataSet();
        ada.Fill(ds);
        return ds;
        }
        }

        前面示例,我們通過Request的屬性QueryString獲取ProductName的值,然后根據ProductName查詢數據庫,最后把獲取數據綁定到Datagridview控件中(注:前面實例沒有考慮SQL Injection問題)。

        cache3

        圖3查詢結果

        現在我們在頁面中添加

        輸出緩存,如下代碼:
        代碼如下:

        <!-- Adds OutputCache directive -->
        <%@ OutputCache Duration="30" VaryByParam="None" %>

        前面提到當
        輸出緩存的屬性VaryByParam=”None”時,ASP.NET程序在緩存有效期內只緩存一個頁面副本;現在我們在緩存有效期內(30s)再發送請求。

        cache4

        圖4查詢結果

        通過上圖我們發現,現在查詢參數ProductName=BK-M18B-40,但查詢結果依然是ProductName=BB-9108的數據,這是由于ASP.NET程序在緩存有效期內只緩存一個頁面副本。

        通過上面的示例,我們發現只緩存一個頁面是不適用包含查詢參數的頁面輸出緩存;其實前面的示例我們只需稍稍改動就能符合查詢參數的情況了,想必大家已經知道了,只需把VaryByParam屬性設置為“*”就OK了。

        cache5

        cache6

        圖5查詢結果

        現在查詢可以獲取相應的結果,如果查詢參數和前一個請求相同并且該頁面緩存有效,那么緩存將被重用,否則,創建一個新的頁面緩存。

        由于ASP.NET給每個查詢參數都添加了輸出緩存,但我們要注意的是是否真的有必要緩存每個查詢參數都緩存一個頁面副本,假設查詢Url中增加一個參數參數ProductId,那么現在Url中就有兩個查詢參數了(ProductName和ProductId)。

        前面我們把VaryByParam設置為“*”,所為ASP.NET程序對ProductName和ProductId都創建頁面緩存,如果我們只針對ProductName創建頁面緩存,這時我們可以修改VaryByParam,具體如下所示:
        代碼如下:


        <!-- Sets VaryByParam property-->
        <%@ OutputCache Duration="30" VaryByParam="productname" %>

        自定義緩存控件
        前面我們介紹了通過查詢參數實現緩存一個或多個頁面,其實ASP.NET也允許我們自定義緩存方式來決定是否緩存頁或重用現有的,這時我們可以通過設置VaryByCustom屬性來實現。

        假設,現在我們要設計基于不同UserHostName的緩存,由于程序在執行過程中,首先調用全局方法GetVaryByCustomString()來確定是否緩存頁面或重用現有的,所以我們可以通過重寫GetVaryByCustomString()方法實現基于UserHostName的緩存,首先我們創建一個Global.asax文件然后重新全局方法GetVaryByCustomString()具體實現如下:
        代碼如下:


        /// <summary>
        /// Gets vary cache based on custom string value.
        /// </summary>
        /// <param name="context">Http context.</param>
        /// <param name="custom">custom string</param>
        /// <returns></returns>
        public override string GetVaryByCustomString(HttpContext context, string custom)
        {
        if (string.Equals(custom, "UserHostName", StringComparison.OrdinalIgnoreCase))
        {
        // Indicates that the cache should be vary on user host name.
        return Context.Request.UserHostName;
        }
        return base.GetVaryByCustomString(context, custom);
        }

        前面我們重寫了GetVaryByCustomString()方法,使得UserHostName值不同時,獲取相應的緩存值。

        然后讓程序基于UserHostName創建緩存,所以我們要在頁面添加以下代碼:
        代碼如下:


        <!-- set vary cache based on custom string value -->
        <%@ OutputCache Duration="30" VaryByParam="None" VaryByCustom="UserHostName" %>

        我們通過自定義現在GetVaryByCustomString()方法,實現了Web程序根據UserHostName實施不同的緩存方式,其實,我們還可以實現更多種類緩存方案,例如:基于用戶角色、時間和Url等等。

        片段緩存
        在某些情況下,我們不能緩存整個頁面,但我們仍想緩存部分頁面從而減輕系統的負擔;其實,我們可以通過兩種方法實現:片段緩存和數據緩存.

        為了實現片段緩存,我們需要創建自定義控件緩存部分頁面,然后我們把OutputCache指令添加到自定義控件中,這樣整個頁面將不會被緩存,而自定義緩存控件除外。

        前面我們介紹了

        輸出緩存的使用,只需在頁面中添加OutputCache指令,假設我們要在幾個頁面中添加輸出緩存這可能比較簡單,但我們要在幾十個頁面中添加輸出緩存功能,而且前面介紹的例子中Duration屬性值都是直接Hard code到每個頁面中,如果我們需要修改Duration屬性值,那么就必須修改每個頁面了,ASP.NET還需要重新編譯這些頁面,這不利于我們的維護,最重要的是增加了我們的工作量。

        其實,我們可以在web.config文件中定義一個outputCacheProfile(ProductCacheProfile),然后在頁面中添加CacheProfile屬性并且賦值為ProductCacheProfile,web.config文件設置如下:
        代碼如下:


        <caching>
        <!-- Sets out put cache profile-->
        <outputCacheSettings>
        <outputCacheProfiles>
        <add name="ProductCacheProfile" duration="30"/>
        </outputCacheProfiles>
        </outputCacheSettings>
        </caching>現在,我們在頁面中添加CacheProfile屬性,并且設置為ProductCacheProfile,如下所示:

        代碼如下:

        <!-- set CacheProfile property -->
        <%@ OutputCache CacheProfile="ProductCacheProfile" VaryByParam="None" %>

        數據緩存
        Cache對象是線程安全:這表示無需顯式實現鎖定或解鎖,在添刪Cache對象中的元素,然而,在Cache對象中元素必須是線程安全的。例如,我們創建一個實體Product,而且存在多個客戶端可能同時操作該對象的情況,這時我們必須為實體Product實現鎖定和解鎖操作(同步操作請參考《單例模式(Singleton)的6種實現》)。

        Cache對象中的緩存項自動移除:當緩存過期,依賴項被修改或內存不足緩存ASP.NET會自動移除該緩存項。

        緩存項支持依賴關系:我們可以給緩存項添加文件、數據庫表或其他資源類型的依賴關系。

        SqlDataSource緩存
        當我們在SqlDataSource控件中啟用緩存,它緩存SelectCommand中的結果;如果SQL查詢語句中帶有參數時,SqlDataSource控件會緩存每一個參數值對應的結果。

        這跟我們之前通過

        輸出緩存實現報表程序緩存查詢頁面效果一樣,所以我們將使用SqlDataSource緩存實現該效果。

        假設我們要提供一個報表程序,讓用戶通過選擇產品名稱(ProductName),獲取相應的產品信息。

        首先,我們在頁面中創建兩個數據源控件:sourceProductName和sourceProduct,接著把數據源分別綁定到Dropdownlist和Gridview中,具體實現如下:
        代碼如下:


        <!-- The product number datasource START -->
        <asp:SqlDataSource ID="sourceProductName" runat="server" ProviderName="System.Data.SqlClient"
        EnableCaching="True" CacheDuration="3600" ConnectionString="<%$ ConnectionStrings:SQLCONN %>"
        SelectCommand="SELECT ProductNumber FROM Production.Product"></asp:SqlDataSource>
        <!-- The product number datasource END -->

        <!-- The product datasource START -->
        <asp:SqlDataSource ID="sourceProduct" runat="server" ProviderName="System.Data.SqlClient"
        EnableCaching="True" CacheDuration="3600" ConnectionString="<%$ ConnectionStrings:SQLCONN %>"
        SelectCommand="SELECT Name, ProductNumber, SafetyStockLevel, ReorderPoint, StandardCost, DaysToManufacture
        FROM Production.Product WHERE ProductNumber=@ProductNumber">
        <SelectParameters>
        <asp:ControlParameter ControlID="ddlProductNumber" Name="ProductNumber" PropertyName="SelectedValue" />
        </SelectParameters>
        </asp:SqlDataSource>
        <!-- The product number datasource END -->

        <!-- Binding the product number to gridview control -->
        <!-- NOTE: Due to search and result in the same page, so need to set AutoPostBack is True-->
        <asp:DropDownList ID="ddlProductNumber" AutoPostBack="True" DataSourceID="sourceProductName"
        DataTextField="ProductNumber" runat="server">
        </asp:DropDownList>

        <!-- Binding the product datasource to gridview control -->
        <asp:GridView ID="gvProduct" runat="server" DataSourceID="sourceProduct" CssClass="Product">
        </asp:GridView>

        現在我們對報表程序進行查詢,如果ProudctName之前沒有被緩存起來就會創建相應的緩存,而已經緩存起來的將被重用,查詢結果如下:

        cache8
        圖6查詢結果

        緩存的依賴關系
        緩存項之間的依賴

        ASP.NET Cache允許我們建立緩存之間的依賴關系,即一個緩存項依賴于另一個緩存項;以下示例代碼創建了二個緩存項,并且它們之間建立依賴關系。具體實現如下:
        代碼如下:


        // Creates cache object Key1.
        Cache["Key1"] = "Cache Item 1";

        // Makes Cache["Key2"] dependent on Cache["Key1"].
        string[] dependencyKey = new string[1];
        dependencyKey[0] = "Key1";

        // Creates a CacheDependency object.
        CacheDependency dependency = new CacheDependency(null, dependencyKey);

        // Establishs dependency between cache Key1 and Key2.
        Cache.Insert("Key2", "Cache Item 2", dependency);

        現在,當Key1緩存項更新或從緩存中刪除,Key2緩存項就會自動從緩存刪除。

        文件依賴

        前面我們介紹了緩存項之間的依賴關系,ASP.NET Cache還提供緩存項與文件之間的依賴關系,當文件被更新或刪除對應的緩存項也將失效。

        在上篇博文《Ajax與JSON的一些總結》的最后介紹的一個DEMO——Weibo Feed中,我們通過實時方式向新浪微博API發送請求獲取相應的數據,但在一定時間內請求的次數是有限制的,一旦超出了限制次數就不再接受請求了(具體請參考Rate-limiting)。所以可以通過Cache的方式把數據緩存起來,當客戶端請求時,如果緩存數據已經存在那么直接返回數據,否則重新想微博API請求數據。

        首先,我們創建一個HttpHandler,它負責向微博API發送請求并且把數據保存的文件中,最后把數據返回的客戶端。

        cache9

        圖7 請求流程
        接下來,我們定義CacheData()方法把微博數據保存到文本文件中并且建立緩存與數據文件的依賴關系。
        代碼如下:

        /// <summary>
        /// Caches the data into text file.
        /// </summary>
        /// <param name="context">The http context</param>
        private void CacheData(HttpContext context)
        {
        // Weibo API.
        string uri = context.Request.QueryString["api"] + "?" +
        "source=" + context.Request.QueryString["source"] + "&" +
        "count=" + context.Request.QueryString["count"];
        HttpWebResponse response = this.GetWeibos(uri);
        if (null == response)
        {
        throw new ArgumentNullException("Response is null");
        }
        string jsonData;
        // Writes the reponse data into text file.
        using (var reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(response.CharacterSet)))
        {
        jsonData = reader.ReadToEnd();
        }
        string dataPath = context.Server.MapPath("weibo.json");
        using (var writer = new StreamWriter(dataPath, false, Encoding.GetEncoding(response.CharacterSet)))
        {
        writer.Write(jsonData);
        }
        // Establishs dependency between cache weibo and text file.
        // Sets cache expires after 2 minuntes.
        HttpRuntime.Cache.Insert("weibo", jsonData, Dep, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(2));
        }

        現在我們把數據保存到文本文件中并且建立了緩存weibo與數據文件的依賴關系,接下來我們要把JSON格式數據返回給客戶端。
        代碼如下:

        /// <summary>
        /// Responses the weibo data.
        /// </summary>
        /// <param name="context">The http contex.</param>
        private void ResponseWeibo(HttpContext context)
        {
        // Gets the weibo cache data.
        byte[] buf = Encoding.UTF8.GetBytes(HttpRuntime.Cache["weibo"].ToString());
        // Writes the data into output stream.
        context.Response.OutputStream.Write(buf, 0, buf.Length);
        context.Response.OutputStream.Flush();
        ////context.Response.Close();
        }

        上面我們把JSON格式字符串轉換為Byte數值,然后寫入到OutputStream中,最后把數據返回給客戶端。
        代碼如下:

        // The function to get weibo data.
        loadWeibo: function() {
        $.ajax({
        // Weibo API.
        url: "WeiboHandler.ashx",
        type: "GET",
        // NOTE: We get the data from same domain,
        // dataType is json.
        dataType: "json",
        data: {
        source: JQWeibo.appKey,
        count: JQWeibo.numWeibo
        },
        // When the requet completed, then invokes success function.
        success: function(data, textStatus, xhr) {
        // Sets html structure.
        var html =
        '<div class="weibo">' +
        '<a target="_blank">USER</a>' +
        ':WEIBO_TEXT<div class="time">AGO</div>';
        // Appends weibos into html page.
        for (var i = 0; i < data.length; i++) {
        $(JQWeibo.appendTo).append(
        html.replace('WEIBO_TEXT', JQWeibo.ify.clean(data[i].text))
        // Uses regex and declare DOMAIN as global, if found replace all.
        .replace(/DOMAIN/g, data[i].user.domain)
        .replace(/USER/g, data[i].user.screen_name)
        .replace('AGO', JQWeibo.timeAgo(data[i].created_at))
        );
        }
        }
        })
        }

        cache10圖8請求結果
        1.1.3 總結
        緩存可以使應用程序的性能得到很大的提高,因此在設計應用程序應該予以考慮,本博文主要介紹了ASP.NET中
        輸出緩存和數據緩存的應用場合和區別。

        頁面緩存適用于生成的頁面通常都相同或改變時間比較固定情況,例如:數據在每小時都會更新,那么我們可以設置duration為3600s。

        數據緩存適用生成的頁面總是在變化情況。

        http://www.codeproject.com/Articles/29899/Exploring-Caching-in-ASP-NET
        http://msdn.microsoft.com/zh-cn/library/aa478965.aspx#XSLTsection129121120120
        http://www.amazon.com/Beginning-ASP-NET-3-5-2008-Professional/dp/1590598911

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        ASP.NET Cache的一些總結分享

        ASP.NET Cache的一些總結分享:1.1.1 摘要 最近我們的系統面臨著嚴峻性能瓶頸問題,這是由于訪問量增加,客戶端在同一時間請求增加,這迫使我們要從兩個方面解決這一問題,增加硬件和提高系統的性能。 大家可以通過各種各樣的方法去優化我們系統,本篇博文將介紹通過Cache方法來優化系統的
        推薦度:
        標簽: 分享 的一些 總結
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 亚洲国产高清视频在线观看| 亚洲精品无码乱码成人| 亚洲成年人免费网站| 免费女人高潮流视频在线观看| 中文字幕亚洲不卡在线亚瑟| 久久国产精品免费一区二区三区 | 亚洲色偷偷综合亚洲AV伊人蜜桃| 最近2019中文字幕免费大全5| 91精品国产亚洲爽啪在线影院| 久久午夜夜伦鲁鲁片免费无码 | 精品熟女少妇aⅴ免费久久| 亚洲中文字幕视频国产| 99精品全国免费观看视频..| 亚洲人成无码网站| 最好免费观看高清在线| 亚洲一区免费观看| 中国在线观看免费高清完整版| 亚洲国产综合精品中文第一| 国产成人免费一区二区三区| 黄色免费在线观看网址| 国产亚洲精品a在线观看| 成在人线av无码免费高潮喷水| 亚洲国产一区国产亚洲| 国产v精品成人免费视频400条| 亚洲欧美国产日韩av野草社区| 尤物永久免费AV无码网站| 国产精品综合专区中文字幕免费播放 | 亚洲国产成人乱码精品女人久久久不卡| 免费手机在线看片| 亚洲日本在线观看| 插B内射18免费视频| 曰批免费视频播放免费| 亚洲国产婷婷六月丁香| 国产电影午夜成年免费视频| 亚洲狠狠婷婷综合久久| 亚洲午夜未满十八勿入网站2| 久久99国产综合精品免费| 亚洲av色香蕉一区二区三区| 亚洲人精品午夜射精日韩| 国产精品美女午夜爽爽爽免费| 成在线人视频免费视频|