<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 基于云存儲(chǔ)實(shí)現(xiàn)用Windows Azure Storage增強(qiáng)應(yīng)用程序的引擎

          基于云存儲(chǔ)實(shí)現(xiàn)用Windows Azure Storage增強(qiáng)應(yīng)用程序的引擎

          作者: 時(shí)間:2018-09-11 來(lái)源:網(wǎng)絡(luò) 收藏

          概述:您可以在云中運(yùn)行后臺(tái)進(jìn)程。Kevin Hoffman 和 Nate Dudek 使用購(gòu)物車示例演示如何構(gòu)建應(yīng)用程序引擎,以及如何使用 實(shí)現(xiàn)異步消息傳送和處理。

          本文引用地址:http://www.ex-cimer.com/article/201809/388914.htm

           開(kāi)發(fā)人員容易依賴其有形的、可感知的基礎(chǔ)結(jié)構(gòu),就像其是“安全毛毯”。他們知道如何使用、如何操作,如果出現(xiàn)問(wèn)題,他們知道問(wèn)題出在哪兒。而這通常會(huì)成為開(kāi)發(fā)人員采用更新的技術(shù)(例如云計(jì)算)的障礙。

            心存懷疑的開(kāi)發(fā)人員提出的最大疑問(wèn)之一是他們?nèi)绾卧谠浦欣^續(xù)運(yùn)行后臺(tái)進(jìn)程,即他們的引擎如何繼續(xù)運(yùn)行。本文旨在通過(guò)向您演示如何構(gòu)建應(yīng)用程序引擎以及使用 實(shí)現(xiàn)異步消息傳送和處理來(lái)為您揭開(kāi)云中缺乏后臺(tái)處理的神秘面紗。

            為了證明開(kāi)發(fā)人員可以拋開(kāi)其有形的基礎(chǔ)結(jié)構(gòu)這條“安全毛毯”并將其應(yīng)用程序引擎置于云中,我們將介紹如何實(shí)現(xiàn)電子商務(wù)應(yīng)用程序的一個(gè)小型子集 Hollywood Hackers,您可以從中購(gòu)買(mǎi)到 Hollywood 用于完全忽略物理法則和過(guò)時(shí)的常識(shí)的所有神奇技術(shù)。

            我們將介紹的兩個(gè)主要方案如下:

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

            此方案使用 Windows Azure Queue 和 Windows Azure 工作者角色將購(gòu)物車提交給執(zhí)行引擎。

            使用隊(duì)列存儲(chǔ)進(jìn)行內(nèi)部應(yīng)用程序消息傳送

            在介紹具體的方案之前,我們需要先介紹一些有關(guān) Windows Azure Queue 的基礎(chǔ)知識(shí)。云中的隊(duì)列與傳統(tǒng)的 .NET 應(yīng)用程序中的隊(duì)列的運(yùn)行方式不太一樣。在處理 AppDomain 中的數(shù)據(jù)時(shí),您知道該數(shù)據(jù)只有一份,它完整地位于單一托管進(jìn)程中。

            而在云中,您的一部分?jǐn)?shù)據(jù)可能在加利福尼亞,而另一部分可能在紐約,并且您可能會(huì)安排一個(gè)工作者角色在德克薩斯州對(duì)該數(shù)據(jù)進(jìn)行處理,而另一工作者角色在北達(dá)科他州進(jìn)行數(shù)據(jù)處理。

          很多開(kāi)發(fā)人員在適應(yīng)這種分布式計(jì)算和分布式數(shù)據(jù)時(shí)面臨著一些不熟悉的問(wèn)題,例如對(duì)可能出現(xiàn)的故障進(jìn)行編碼、針對(duì)數(shù)據(jù)提交形成多次重試的概念甚至冪等性的理念。

            只要您不將 Windows Azure Queue 視為進(jìn)程內(nèi)的常規(guī) CLR 隊(duì)列,其工作方式其實(shí)非常簡(jiǎn)單。首先,應(yīng)用程序?qū)⑾蜿?duì)列獲取一些數(shù)量的消息(需要記住,一次不會(huì)超過(guò) 20 條)并提供一個(gè)超時(shí)。此超時(shí)控制對(duì)其他隊(duì)列處理客戶端隱藏這些消息的時(shí)間。當(dāng)應(yīng)用程序成功完成需要對(duì)隊(duì)列消息進(jìn)行的所有處理后,將刪除該消息。

            如果應(yīng)用程序引發(fā)異?;蛱幚黻?duì)列消息失敗,則在超時(shí)期限過(guò)后,其他客戶端可以再次看到該消息。因此,當(dāng)一個(gè)工作者角色處理失敗后,其他工作者角色可以繼續(xù)進(jìn)行處理。向隊(duì)列提交消息非常簡(jiǎn)單:應(yīng)用程序直接或借助客戶端庫(kù)形成適當(dāng)?shù)?HTTP POST 消息,然后提交字符串或字節(jié)數(shù)組。隊(duì)列專門(mén)用于進(jìn)行內(nèi)部應(yīng)用程序消息傳送和非永久存儲(chǔ),因此這些消息占用的空間需要相當(dāng)小。

            如上所述,您可能安排多個(gè)工作者角色都嘗試處理同一消息。雖然隱藏當(dāng)前正在處理的消息的不可見(jiàn)超時(shí)很有幫助,但不能確保萬(wàn)無(wú)一失。要完全避免沖突,您應(yīng)該將您的引擎處理設(shè)計(jì)為冪等。換句話說(shuō),同一隊(duì)列消息應(yīng)該可以由一個(gè)或多個(gè)工作者角色處理多次,而不會(huì)使應(yīng)用程序處于不一致的狀態(tài)。

            理想情況下,您希望工作者角色可以檢測(cè)出是否已完成對(duì)給定消息的處理。在編寫(xiě)工作者角色來(lái)處理隊(duì)列消息時(shí),請(qǐng)牢記您的代碼可能會(huì)嘗試處理已處理過(guò)的消息,盡管這個(gè)可能性微乎其微。

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

           圖 1 創(chuàng)建消息并將其提交給 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);

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

          異步消息傳送 (Toast)

            當(dāng)今,交互式網(wǎng)站不僅是一種時(shí)尚,更是一種需求。用戶已經(jīng)習(xí)慣了完全交互式網(wǎng)站,以致于當(dāng)他們遇到一個(gè)靜態(tài)的非交互式頁(yè)面時(shí)會(huì)認(rèn)為什么地方出問(wèn)題了。考慮到這一點(diǎn),我們希望可以在我們的用戶使用這樣的站點(diǎn)時(shí)向他們發(fā)送通知。

            為此,我們將利用 Windows Azure Queue 和 Windows Azure Table 存儲(chǔ)機(jī)制構(gòu)建一個(gè)消息傳遞框架??蛻舳藢⑹褂门c jQuery Gritter 插件結(jié)合的 jQuery 在用戶的瀏覽器中將通知顯示為一個(gè) toast,類似于當(dāng)您收到新的 Outlook 電子郵件、即時(shí)消息或警報(bào)聲時(shí)在 Windows 系統(tǒng)托盤(pán)上方淡出的消息。

            當(dāng)需要向某個(gè)用戶發(fā)送通知時(shí),該用戶將被插入到隊(duì)列中。因?yàn)楣ぷ髡呓巧?fù)責(zé)處理隊(duì)列中的每個(gè)項(xiàng)目,所以該角色將動(dòng)態(tài)確定如何處理每個(gè)項(xiàng)目。在本例中,引擎只需要執(zhí)行一個(gè)操作,但在復(fù)雜的 CRM 網(wǎng)站或支持站點(diǎn)中,要執(zhí)行的操作可能不計(jì)其數(shù)。

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

            盡管隊(duì)列只處理字符串或字節(jié)數(shù)組,但我們可以通過(guò)將任何類型的結(jié)構(gòu)化數(shù)據(jù)序列化為二進(jìn)制文件來(lái)將其存儲(chǔ)在隊(duì)列中,然后在我們需要使用時(shí)再將其轉(zhuǎn)換回來(lái)。這成為將強(qiáng)類型化的對(duì)象傳遞到隊(duì)列中的出色技術(shù)。我們會(huì)將此技術(shù)構(gòu)建到我們的隊(duì)列消息的基類中。然后,我們的系統(tǒng)消息類可以包含我們的數(shù)據(jù),而且可以將整個(gè)對(duì)象提交到隊(duì)列中并根據(jù)需要進(jìn)行利用(請(qǐng)參見(jiàn)圖 2)。

           圖 2 在隊(duì)列中存儲(chǔ)結(jié)構(gòu)化數(shù)據(jù)

          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; }    
            }

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


          上一頁(yè) 1 2 3 4 下一頁(yè)

          關(guān)鍵詞: Windows Storage Azure 云存儲(chǔ)

          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();