新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 如何構建應用程序引擎以及使用 Windows Azure Storage 實現異步消息傳送

        如何構建應用程序引擎以及使用 Windows Azure Storage 實現異步消息傳送

        作者: 時間:2012-02-18 來源:網絡 收藏

        心存懷疑的開發人員提出的最大疑問之一是他們如何在云中繼續運行后臺進程,即他們的引擎如何繼續運行。本文旨在通過向您演示如何構建引擎以及使用 和處理來為您揭開云中缺乏后臺處理的神秘面紗。

        本文引用地址:http://www.104case.com/article/149634.htm

          為了證明開發人員可以拋開其有形的基礎結構這條“安全毛毯”并將其引擎置于云中,我們將介紹如何電子商務的一個小型子集 Hollywood Hackers,您可以從中購買到 Hollywood 用于完全忽略物理法則和過時的常識的所有神奇技術。

          我們將介紹的兩個主要方案如下:

          將文本 (“toasts”) 發送給使用該應用程序的用戶,以通知他們發生的重要事件(如已提交他們的購物車)或在員工之間發送。此方案使用 Queue、 Table 和 Windows Azure 工作者角色。

          此方案使用 Windows Azure Queue 和 Windows Azure 工作者角色將購物車提交給執行引擎。

          使用隊列存儲進行內部應用程序消息

          在介紹具體的方案之前,我們需要先介紹一些有關 Windows Azure Queue 的基礎知識。云中的隊列與傳統的 .NET 應用程序中的隊列的運行方式不太一樣。在處理 AppDomain 中的數據時,您知道該數據只有一份,它完整地位于單一托管進程中。

          而在云中,您的一部分數據可能在加利福尼亞,而另一部分可能在紐約,并且您可能會安排一個工作者角色在德克薩斯州對該數據進行處理,而另一工作者角色在北達科他州進行數據處理。

        很多開發人員在適應這種分布式計算和分布式數據時面臨著一些不熟悉的問題,例如對可能出現的故障進行編碼、針對數據提交形成多次重試的概念甚至冪等性的理念。

          只要您不將 Windows Azure Queue 視為進程內的常規 CLR 隊列,其工作方式其實非常簡單。首先,應用程序將向隊列獲取一些數量的消息(需要記住,一次不會超過 20 條)并提供一個超時。此超時控制對其他隊列處理客戶端隱藏這些消息的時間。當應用程序成功完成需要對隊列消息進行的所有處理后,將刪除該消息。

          如果應用程序引發異常或處理隊列消息失敗,則在超時期限過后,其他客戶端可以再次看到該消息。因此,當一個工作者角色處理失敗后,其他工作者角色可以繼續進行處理。向隊列提交消息非常簡單:應用程序直接或借助客戶端庫形成適當的 HTTP POST 消息,然后提交字符串或字節數組。隊列專門用于進行內部應用程序消息和非永久存儲,因此這些消息占用的空間需要相當小。

          如上所述,您可能安排多個工作者角色都嘗試處理同一消息。雖然隱藏當前正在處理的消息的不可見超時很有幫助,但不能確保萬無一失。要完全避免沖突,您應該將您的引擎處理設計為冪等。換句話說,同一隊列消息應該可以由一個或多個工作者角色處理多次,而不會使應用程序處于不一致的狀態。

          理想情況下,您希望工作者角色可以檢測出是否已完成對給定消息的處理。在編寫工作者角色來處理隊列消息時,請牢記您的代碼可能會嘗試處理已處理過的消息,盡管這個可能性微乎其微。

          圖 1 中的代碼段顯示了如何使用隨 Windows Azure SDK 一起提供的 Client 程序集創建消息并將其提交給 Windows Azure Queue。Client 庫實際上只是 Windows Azure Storage HTTP 接口周圍的包裝。

         圖 1 創建消息并將其提交給 Windows Azure Queue

        string accountName; 
        string accountSharedKey; 
        string queueBaseUri; 
        string StorageCredentialsAccountAndKey credentials; 
         
        if (RoleEnvironment.IsAvailable) 
        { 
        // We are running in a cloud - INCLUDING LOCAL! 
         accountName = 
         RoleEnvironment.GetConfigurationSettingValue(AccountName); 
         accountSharedKey =  
         RoleEnvironment.GetConfigurationSettingValue(AccountSharedKey); 
         queueBaseUri = RoleEnvironment.GetConfigurationSettingValue 
         (QueueStorageEndpoint); 
        } 
        else 
        { 
         accountName = ConfigurationManager.AppSettings[AccountName]; 
         accountSharedKey = 
         ConfigurationManager.AppSettings[AccountSharedKey]; 
         queueBaseUri = 
         ConfigurationManager.AppSettings[QueueStorageEndpoint]; 
        } 
        credentials = 
        new StorageCredentialsAccountAndKey(accountName, accountSharedKey); 
        CloudQueueClient client = 
        new CloudQueueClient(queueBaseUri, credentials); 
        CloudQueue queue = client.GetQueueReference(queueName); 
        CloudQueueMessage m = new CloudQueueMessage( 
         /* string or byte[] representing message to enqueue */); 
        Queue.AddMessage(m);

          對于本文中的其他示例,我們使用了可以簡化此過程的一些包裝類(位于 Hollywood Hackers 的 CodePlex 站點中,網址為:hollywoodhackers.codeplex.com/SourceControl/ListDownloadableCommits.aspx)。

        消息傳送 (Toast)

          當今,交互式網站不僅是一種時尚,更是一種需求。用戶已經習慣了完全交互式網站,以致于當他們遇到一個靜態的非交互式頁面時會認為什么地方出問題了。考慮到這一點,我們希望可以在我們的用戶使用這樣的站點時向他們發送通知。

          為此,我們將利用 Windows Azure Queue 和 Windows Azure Table 存儲機制構建一個消息傳遞框架。客戶端將使用與 jQuery Gritter 插件結合的 jQuery 在用戶的瀏覽器中將通知顯示為一個 toast,類似于當您收到新的 Outlook 電子郵件、即時消息或警報聲時在 Windows 系統托盤上方淡出的消息。

          當需要向某個用戶發送通知時,該用戶將被插入到隊列中。因為工作者角色負責處理隊列中的每個項目,所以該角色將動態確定如何處理每個項目。在本例中,引擎只需要執行一個操作,但在復雜的 CRM 網站或支持站點中,要執行的操作可能不計其數。

          工作者角色在隊列中遇到用戶通知時,會將該通知存儲在表存儲中并將其從隊列中刪除。這樣,消息可以保留很長時間并等待用戶登錄進行處理。隊列存儲中的消息的最大保存期限比較短,不會超過幾天。當用戶訪問網站時,我們的 jQuery 腳本將異步獲取表中的所有消息,并通過在控制器上調用可返回 JavaScript Object Notation (JSON) 的方法在瀏覽器中以常見的形式顯示這些消息。

          盡管隊列只處理字符串或字節數組,但我們可以通過將任何類型的結構化數據序列化為二進制文件來將其存儲在隊列中,然后在我們需要使用時再將其轉換回來。這成為將強類型化的對象傳遞到隊列中的出色技術。我們會將此技術構建到我們的隊列消息的基類中。然后,我們的系統消息類可以包含我們的數據,而且可以將整個對象提交到隊列中并根據需要進行利用(請參見圖 2)。

         圖 2 在隊列中存儲結構化數據

        namespace HollywoodHackers.Storage.Queue 
        { 
          [Serializable] 
          public class QueueMessageBase 
          { 
            public byte[] ToBinary() 
            { 
              BinaryFormatter bf = new BinaryFormatter(); 
              MemoryStream ms = new MemoryStream(); 
              ms.Position = 0; 
              bf.Serialize(ms, this); 
              byte[] output = ms.GetBuffer(); 
              ms.Close(); 
              return output; 
            } 
            public static T FromMessageT>(CloudQueueMessage m) 
            { 
              byte[] buffer = m.AsBytes(); 
              MemoryStream ms = new MemoryStream(buffer); 
              ms.Position = 0; 
              BinaryFormatter bf = new BinaryFormatter(); 
              return (T)bf.Deserialize(ms); 
            } 
          } 
          [Serializable] 
          public class ToastQueueMessage : QueueMessageBase 
          { 
          public ToastQueueMessage() 
              : base() 
            { 
            } 
            public string TargetUserName { get; set; }     
            public string MessageText { get; set; } 
            public string Title { get; set; } 
            public DateTime CreatedOn { get; set; }    
          }

         請記住,要使用 BinaryFormatter 類,需要以完全信任模式(可以通過服務配置文件啟用此模式)運行 Windows Azure 工作者角色。


        上一頁 1 2 3 下一頁

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 马关县| 嘉兴市| 田东县| 孟州市| 郧西县| 澎湖县| 册亨县| 玉龙| 张家口市| 平江县| 余庆县| 囊谦县| 滦平县| 巍山| 淳化县| 纳雍县| 洛宁县| 瑞昌市| 云梦县| 蕲春县| 霍林郭勒市| 嘉峪关市| 民勤县| 灵宝市| 交城县| 枣阳市| 宁蒗| 阳春市| 五台县| 富蕴县| 曲沃县| 宜春市| 兴业县| 寿阳县| 白城市| 尼勒克县| 乐亭县| 南汇区| 肇源县| 成武县| 肥城市|