[網站效能] 存取Application變數,Application每隔一段時間更新資料來源

[網站效能] 存取Application變數,Application每隔一段時間更新資料來源

目前開發的專案還在測試中,就發現網站載入速度太慢

為改進效能問題,昨晚跟同事討論了一個解決方案:

 

先介紹目前此專案在測試環境中的架構(請按照數字順序閱讀)

 原本的架構圖

 

3、4點是此網站的效能瓶頸

為了讓前台儘量減少直接存取資料庫,並避免當太多User連上前台網站時,造成產生太多DataTable佔Server的記憶體

所以打算把DataTable存入Application變數,前台部份程式不連資料庫,直接從Application變數中取資料

又因為Application變數為共用的,比起new太多DataTable,期望可以改善前台Server記憶體的佔用

但又希望資料存入Application時,當後台有異動資料時,前台的Application可以即時更新

於是想出在前台網站掛一個WebService給後台呼叫

請見下圖:

目標架構圖

理論上應該可行,但要修改後台程式(我動作拖拖拉拉的XD)

另一位同事建議改成讀取(前台網站)Global.asax的Application變數,別玩太大

Application變數更新頻率設為1天

實現代碼如下:


<%@ Application Language="C#" %>
<%@ Import Namespace="System.Data" %>


<script runat="server">
    protected void Application_BeginRequest(object sender, EventArgs e)
    {
       
    }
    
    //只會執行一次在IIS啟動時(除非Web.config檔被修改)
    void Application_Start(object sender, EventArgs e) 
    {
        // 應用程式啟動時執行的程式碼
       
		 
    }
    
    void Application_End(object sender, EventArgs e) 
    {
        //  應用程式關閉時執行的程式碼
        
    }
        
    void Application_Error(object sender, EventArgs e) 
    { 
        // 發生未處理錯誤時執行的程式碼
       
    }

    
    //每個User連接到此網站時
    void Session_Start(object sender, EventArgs e) 
    {
       
        // 啟動新工作階段時執行的程式碼
        //此User連接到此網站的時間
        String today = DateTime.Now.ToString("yyyy/MM/dd"); 
        		
      
        //Application更新時機:
        //或Application["Sys_dt"]為null(為了防呆)
        //或Application["Sys_Update_Date"]為null(指IIS第一次啟動)
        //或當日第一位User拜訪此網站
        if ( Application["Sys_dt"] == null
           || Application["Sys_Update_Date"] == null 
           || ((string)Application["Sys_Update_Date"])!=today)
        {
            //當日第一位User拜訪此網站,改變Application["Sys_Update_Date"]紀錄
            Application["Sys_Update_Date"] = today;		
		
           
            DataTable dt = new DataTable();//假設這是從DB撈出DataTable
            //DataTable存入Application
            Application["Sys_dt"] = dt;
			 			
			
        }		
        
    }

    void Session_End(object sender, EventArgs e) 
    {
        // 工作階段結束時執行的程式碼。 
        // 注意: 只有在 Web.config 檔將 sessionstate 模式設定為 InProc 時,
        // 才會引發 Session_End 事件。如果將工作階段模式設定為 StateServer 
        // 或 SQLServer,就不會引發這個事件。
      
    }
       
</script>

因為Application預計是會變動的(但不希望變動頻率太高),所以不會寫在Application_Start

而使用者另開新頁發生Application_BeginRequest頻率比Session_Start高

所以結論把代碼寫在Session_Start事件

各事件說明可參考:Global events in ASP.NET

至於原本提的第一個方案有空再來實現,這邊就先紀錄有這個solution,供日後復習