2013年6月23日

Windows Azure - 在Web Site下使用Azure SQL Database來存放Session

之前在4月的時候,講過Azure的課程,當時在Web Site底下,要使用Azure SQL Database來存放Session是件很麻煩的事情,因為還要建立資料庫等等。

但現在不用那麼麻煩了,經過小朱前輩的指導,現在官方已經使用Code First來自動建立資料庫了!!,所以之前寫的那篇,大家可以扔到垃圾場去了..

以下文章是前篇的改良版。

相信如果有讀過這篇( p.s 現在官方強烈建議,不要再用Azure Storage當Cache了),那可能會知道,不管是Cloud Service或是Web Site,前面都會有用到Load Balance,當然,如果後面只有一個站台,那就沒甚麼差,但如果後面有兩台以上的站台來分流,那Session的議題就變得很重要了…

而Cloud Service很佛心的準備了內建Cache來解決這部分的問題 ( 不然用Azure Cache會貴森森… ),那Web Site呢!?其實除了貴森森的Azure Cache外,還有大家常知的…沒錯!!就是使用SQL Server來存放Session!!

當然,我們不會傻傻的Web放到Azure上,但卻把Session放在陸地上…所以,這篇的目的,就是要介紹,如何使用Azure的SQL Database來存放Session!! ( 嗯,或許大家會擔心效能上的問題,但根據可靠情報指出,目前Azure 上的SQL Database都是用SSD喔!! )

準備SQL Database

首先,我們當然要先去SQL Database來開一個新的SQL Server,這邊我們是要測試,所以很快的快速創建就好。

image_thumb5

是的,這樣db就完成了,不用像以前一樣,麻煩的做一堆事情,而到這邊,SQL Database就準備妥當了。

ASP.NET的修改( MVC同 )

其實ASP.NET的處理很簡單,我們首先先到NuGet取得以下套件,到線上的地方去搜尋Universal Providers,就可以找到Microsoft ASP.NET Universal Providers Code Libraries和Microsoft ASP.NET Universal Providers,而其實真正重要的是Code Libraries,也可以只裝Code Libraries。

( 其實也可以直接安裝ASP.NET Universal Providers,裝上去的時候,也會一併把ASP.NET Universal Providers Core裝上,其實Core是ASP.NET Universal Providers的底層核心,當安裝ASP.NET Universal Providers的時候,就會順便把ASP.NET Universal Providers Core裝起來,並且順便修改Web.Config;但如果直接裝Core,則不會協助幫忙修改Web.Config,變成要自己在Web.Config加上等下講到的程式碼。 )

image

如果直接裝了Microsoft ASP.NET Universal Providers,那它會自動在Web.config加入以下的Tag。

    <profile defaultProvider="DefaultProfileProvider">
      <providers>
        <add name="DefaultProfileProvider" type="System.Web.Providers.DefaultProfileProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
      </providers>
    </profile>
    <membership defaultProvider="DefaultMembershipProvider">
      <providers>
        <add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
      </providers>
    </membership>
    <roleManager defaultProvider="DefaultRoleProvider">
      <providers>
        <add name="DefaultRoleProvider" type="System.Web.Providers.DefaultRoleProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" applicationName="/" />
      </providers>
    </roleManager>
    <!--
            If you are deploying to a cloud environment that has multiple web server instances,
            you should change session state mode from "InProc" to "Custom". In addition,
            change the connection string named "DefaultConnection" to connect to an instance
            of SQL Server (including SQL Azure and SQL  Compact) instead of to SQL Server Express.
      -->
    <sessionState mode="InProc" customProvider="DefaultSessionProvider">
      <providers>
        <add name="DefaultSessionProvider" type="System.Web.Providers.DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" />
      </providers>
    </sessionState>

是的,其實Microsoft ASP.NET Universal Providers不只是session而已,他還包含了User 、Role等東西,所以覺得Web.config很雜亂的話,也可以把其他的註解調或是刪掉也可以啦…

而現在,我們還需要修改一下Web.Config裡面的SessionState那邊,改成Custom的設定就可以了。( 或許有人會問,為什麼要填寫Customer,而不是SQLServer,原因很簡單,因為官方上面那串綠色的註解是這樣寫的阿XDDD,官方上面寫到,如果要部屬到Cloud環境,而且有多個Instances的話,要把InProc改為Custom,這也就是為什麼要改成Custom的原因… ),其次,因為我們會存放到Azure SQL Database,所以還要改一下連線字串,那連線字串的名稱呢!?是的,就是第二個紅色框框"DefaultConnection"。

image

會變成如下

    <sessionState mode="Custom" customProvider="DefaultSessionProvider">
      <providers>
        <add name="DefaultSessionProvider" 
             type="System.Web.Providers.DefaultSessionStateProvider, 
             System.Web.Providers, Version=1.0.0.0, Culture=neutral, 
             PublicKeyToken=31bf3856ad364e35" 
             connectionStringName="DefaultConnection" />
      </providers>
    </sessionState>

接下來

我們用搜尋的方式找到DefaultConnection( 建議用搜尋的方式,這樣才不會不小心建了兩次的DefaultConnection ),並填入連線字串,而再填入前,要先找到Azure SQL Database的連線字串。

image

然後選擇儀表板

image

然後選擇連線字串,就可以看到了,接下來就把整個連線字串複製下來。

image

最後貼到Web.conig。

image

會變成如下

  <connectionStrings>
    <add name="DefaultConnection" providerName="System.Data.SqlClient" 
         connectionString="Server=tcp:dkegao7az4.database.windows.net,1433;
         Database=ASPNETSessionTest;User ID=sky@dkegao7az4;Password=自己的密碼;
         Trusted_Connection=False;Encrypt=True;Connection Timeout=30" />
  </connectionStrings>

完成後,如果有存取到Session,就可以用瀏覽器的Developer工具來查看Cookie裡面紀錄的Session ID。

image_thumb51

我們可以透過Azure的db管理工具,看到Sessions Table已經自動幫我們建立起來了。

image

我們也可以從裡面看到,已經有對應的SessionID了,所以可以確定,這樣就已經把SESSION存放到DB裡面去了。

image_thumb4

題外話,因為Web Site前面的LB機制會自動認ip,所以通常狂按F5是測試不出來的,所以如果覺得這樣還不能證明,還可以手動去調整Web Site,如果沒有把Session存放到DB裡面去,當改變Web Site的時候,是會掉Session的,但如果存到db裡面去,就不會有這種問題了。

image

基本上,這樣就完成了~

後記

現在透過Web Site,其實整個機制就和一般使用IIS一樣的方便,而且Azure DB的效能也好很多,重點是,也不用自己多做甚麼事情,幾乎都可以輕鬆搞定,這邊,也很感謝小朱前輩利用中午吃便當的時候,一邊被我騷擾,一邊和我說有這種東西,在這邊再次感謝他,如果大家有興趣,下面的參考資料,也有小朱前輩上次上課的超詳細步驟解說!!

最後的最後,也提醒大家一下,這邊的範例,因為方便,所以在撰寫的時候就直接把Connection換成Azure SQL Database,如果在真正的專案執行上,也可以透過VS的發佈工具,動態的改變DB的Connection String,讓開發的時候使用LocalDB,正式的時候,使用Azure SQL Database喔~

以上,謝謝大家~~

參考資料

專案下載

沒有留言:

張貼留言