這篇文章主要為大家展示了“PetShop數(shù)據(jù)訪問層中消息處理的示例分析”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“PetShop數(shù)據(jù)訪問層中消息處理的示例分析”這篇文章吧。
網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)建站!專注于網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、成都微信小程序、集團企業(yè)網(wǎng)站建設(shè)等服務(wù)項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了成安免費建站歡迎大家使用!PetShop數(shù)據(jù)訪問層之消息處理
在進行系統(tǒng)設(shè)計時,除了對安全、事務(wù)等問題給與足夠的重視外,性能也是一個不可避免的問題所在,尤其是一個B/S結(jié)構(gòu)的軟件系統(tǒng),必須充分地考慮訪問量、數(shù)據(jù)流量、服務(wù)器負荷的問題。解決性能的瓶頸,除了對硬件系統(tǒng)進行升級外,軟件設(shè)計的合理性尤為重要。
在前面我曾提到,分層式結(jié)構(gòu)設(shè)計可能會在一定程度上影響數(shù)據(jù)訪問的性能,然而與它給設(shè)計人員帶來的好處相比,幾乎可以忽略。要提供整個系統(tǒng)的性能,還可以從數(shù)據(jù)庫的優(yōu)化著手,例如連接池的使用、建立索引、優(yōu)化查詢策略等等,例如在PetShop中就利用了數(shù)據(jù)庫的Cache,對于數(shù)據(jù)量較大的訂單數(shù)據(jù),則利用分庫的方式為其單獨建立了Order和Inventory數(shù)據(jù)庫。而在軟件設(shè)計上,比較有用的方式是利用多線程與異步處理方式。
在PetShop4.0中,使用了Microsoft Messaging Queue(MSMQ)技術(shù)來完成異步處理,利用消息隊列臨時存放要插入的數(shù)據(jù),使得數(shù)據(jù)訪問因為不需要訪問數(shù)據(jù)庫從而提供了訪問性能,至于隊列中的數(shù)據(jù),則等待系統(tǒng)空閑的時候再進行處理,將其最終插入到數(shù)據(jù)庫中。
PetShop4.0中的消息處理,主要分為如下幾部分:消息接口IMessaging、消息工廠MessagingFactory、MSMQ實現(xiàn)MSMQMessaging以及數(shù)據(jù)后臺處理應(yīng)用程序OrderProcessor。
從模塊化分上,PetShop自始自終地履行了“面向接口設(shè)計”的原則,將消息處理的接口與實現(xiàn)分開,并通過工廠模式封裝消息實現(xiàn)對象的創(chuàng)建,以達到松散耦合的目的。
由于在PetShop中僅對訂單的處理使用了異步處理方式,因此在消息接口IMessaging中,僅定義了一個IOrder接口,其類圖如下:
在對消息接口的實現(xiàn)中,考慮到未來的擴展中會有其他的數(shù)據(jù)對象會使用MSMQ,因此定義了一個Queue的基類,實現(xiàn)消息Receive和Send的基本操作:
public virtual object Receive() { try { using (Message message = queue.Receive(timeout, transactionType)) return message; } catch (MessageQueueException mqex) { if (mqex.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout) throw new TimeoutException(); throw; } } public virtual void Send(object msg) { queue.Send(msg, transactionType); }
其中queue對象是System.Messaging.MessageQueue類型,作為存放數(shù)據(jù)的隊列。MSMQ隊列是一個可持久的隊列,因此不必擔(dān)心用戶不間斷地下訂單會導(dǎo)致訂單數(shù)據(jù)的丟失。在PetShopQueue設(shè)置了timeout值,OrderProcessor會根據(jù)timeout值定期掃描隊列中的訂單數(shù)據(jù)。
MSMQMessaging模塊中,Order對象實現(xiàn)了IMessaging模塊中定義的接口IOrder,同時它還繼承了基類PetShopQueue,其定義如下:
public class Order:PetShopQueue, PetShop.IMessaging.IOrder 方法的實現(xiàn)代碼如下: public new OrderInfo Receive() { // This method involves in distributed transaction and need Automatic Transaction type base.transactionType = MessageQueueTransactionType.Automatic; return (OrderInfo)((Message)base.Receive()).Body; } public OrderInfo Receive(int timeout) { base.timeout = TimeSpan.FromSeconds(Convert.ToDouble(timeout)); return Receive(); } public void Send(OrderInfo orderMessage) { // This method does not involve in distributed transaction and optimizes performance using Single type base.transactionType = MessageQueueTransactionType.Single; base.Send(orderMessage); }
所以,最后的類圖應(yīng)該如下:
注意在Order類的Receive()方法中,是用new關(guān)鍵字而不是override關(guān)鍵字來重寫其父類PetShopQueue的Receive()虛方法。因此,如果是實例化如下的對象,將會調(diào)用PetShopQueue的Receive()方法,而不是子類Order的Receive()方法:
PetShopQueue queue = new Order(); queue.Receive();
從設(shè)計上來看,由于PetShop采用“面向接口設(shè)計”的原則,如果我們要創(chuàng)建Order對象,應(yīng)該采用如下的方式:
IOrder order = new Order(); order.Receive();
考慮到IOrder的實現(xiàn)有可能的變化,PetShop仍然利用了工廠模式,將IOrder對象的創(chuàng)建用專門的工廠模塊進行了封裝:
在類QueueAccess中,通過CreateOrder()方法利用反射技術(shù)創(chuàng)建正確的IOrder類型對象:
public static PetShop.IMessaging.IOrder CreateOrder() { string className = path + ".Order"; return PetShop.IMessaging.IOrder)Assembly.Load(path).CreateInstance(className); }
path的值通過配置文件獲取:
private static readonly string path = ConfigurationManager.AppSettings["OrderMessaging"];
而配置文件中,OrderMessaging的值設(shè)置如下:
<add key="OrderMessaging" value="PetShop.MSMQMessaging"/>
之所以利用工廠模式來負責(zé)對象的創(chuàng)建,是便于在業(yè)務(wù)層中對其調(diào)用,例如在BLL模塊中OrderAsynchronous類:
public class OrderAsynchronous : IOrderStrategy { private static readonly PetShop.IMessaging.IOrder asynchOrder = PetShop.MessagingFactory.QueueAccess.CreateOrder(); public void Insert(PetShop.Model.OrderInfo order) { asynchOrder.Send(order); } }
一旦IOrder接口的實現(xiàn)發(fā)生變化,這種實現(xiàn)方式就可以使得客戶僅需要修改配置文件,而不需要修改代碼,如此就可以避免程序集的重新編譯和部署,使得系統(tǒng)能夠靈活應(yīng)對需求的改變。例如定義一個實現(xiàn)IOrder接口的SpecialOrder,則可以新增一個模塊,如PetShop.SpecialMSMQMessaging,而類名則仍然為Order,那么此時我們僅需要修改配置文件中OrderMessaging的值即可:
<add key="OrderMessaging" value="PetShop.SpecialMSMQMessaging"/>
OrderProcessor是一個控制臺應(yīng)用程序,不過可以根據(jù)需求將其設(shè)計為Windows Service。它的目的就是接收消息隊列中的訂單數(shù)據(jù),然后將其插入到Order和Inventory數(shù)據(jù)庫中。它利用了多線程技術(shù),以達到提高系統(tǒng)性能的目的。
在OrderProcessor應(yīng)用程序中,主函數(shù)Main用于控制線程,而核心的執(zhí)行任務(wù)則由方法ProcessOrders()實現(xiàn):
private static void ProcessOrders() { // the transaction timeout should be long enough to handle all of orders in the batch TimeSpan tsTimeout = TimeSpan.FromSeconds(Convert.ToDouble(transactionTimeout * batchSize)); Order order = new Order(); while (true) { // queue timeout variables TimeSpan datetimeStarting = new TimeSpan(DateTime.Now.Ticks); double elapsedTime = 0; int processedItems = 0; ArrayList queueOrders = new ArrayList(); using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required, tsTimeout)) { // Receive the orders from the queue for (int j = 0; j < batchSize; j++) { try { //only receive more queued orders if there is enough time if ((elapsedTime + queueTimeout + transactionTimeout) < tsTimeout.TotalSeconds) { queueOrders.Add(order.ReceiveFromQueue(queueTimeout)); } else { j = batchSize; // exit loop } //update elapsed time elapsedTime = new TimeSpan(DateTime.Now.Ticks).TotalSeconds - datetimeStarting.TotalSeconds; } catch (TimeoutException) { //exit loop because no more messages are waiting j = batchSize; } } //process the queued orders for (int k = 0; k < queueOrders.Count; k++) { order.Insert((OrderInfo)queueOrders[k]); processedItems++; totalOrdersProcessed++; } //batch complete or MSMQ receive timed out ts.Complete(); } Console.WriteLine("(Thread Id " + Thread.CurrentThread.ManagedThreadId + ") batch finished, " + processedItems + " items, in " + elapsedTime.ToString() + " seconds."); } }
首先,它會通過PetShop.BLL.Order類的公共方法ReceiveFromQueue()來獲取消息隊列中的訂單數(shù)據(jù),并將其放入到一個ArrayList對象中,然而再調(diào)用PetShop.BLL.Order類的Insert方法將其插入到Order和Inventory數(shù)據(jù)庫中。
在PetShop.BLL.Order類中,并不是直接執(zhí)行插入訂單的操作,而是調(diào)用了IOrderStrategy接口的Insert()方法:
public void Insert(OrderInfo order) { // Call credit card procesor ProcessCreditCard(order); // Insert the order (a)synchrounously based on configuration orderInsertStrategy.Insert(order); }
在這里,運用了一個策略模式,類圖如下所示:
在PetShop.BLL.Order類中,仍然利用配置文件來動態(tài)創(chuàng)建IOrderStategy對象:
private static readonly PetShop.IBLLStrategy.IOrderStrategy orderInsertStrategy = LoadInsertStrategy(); private static PetShop.IBLLStrategy.IOrderStrategy LoadInsertStrategy() { // Look up which strategy to use from config file string path = ConfigurationManager.AppSettings["OrderStrategyAssembly"]; string className = ConfigurationManager.AppSettings["OrderStrategyClass"]; // Using the evidence given in the config file load the appropriate assembly and class return (PetShop.IBLLStrategy.IOrderStrategy)Assembly.Load(path).CreateInstance(className); }
由于OrderProcessor是一個單獨的應(yīng)用程序,因此它使用的配置文件與PetShop不同,是存放在應(yīng)用程序的App.config文件中,在該文件中,對IOrderStategy的配置為:
<add key="OrderStrategyAssembly" value="PetShop.BLL" /> <add key="OrderStrategyClass" value="PetShop.BLL.OrderSynchronous" />
因此,以異步方式插入訂單的流程如下圖所示:
Microsoft Messaging Queue(MSMQ)技術(shù)除用于異步處理以外,它主要還是一種分布式處理技術(shù)。分布式處理中,一個重要的技術(shù)要素就是有關(guān)消息的處理,而在System.Messaging命名空間中,已經(jīng)提供了Message類,可以用于承載消息的傳遞,前提上消息的發(fā)送方與接收方在數(shù)據(jù)定義上應(yīng)有統(tǒng)一的接口規(guī)范。
MSMQ在分布式處理的運用,在我參與的項目中已經(jīng)有了實現(xiàn)。在為一個汽車制造商開發(fā)一個大型系統(tǒng)時,分銷商Dealer作為.Net客戶端,需要將數(shù)據(jù)傳遞到管理中心,并且該數(shù)據(jù)將被Oracle的EBS(E-Business System)使用。由于分銷商管理系統(tǒng)(DMS)采用的是C/S結(jié)構(gòu),數(shù)據(jù)庫為SQL Server,而汽車制造商管理中心的EBS數(shù)據(jù)庫為Oracle。這里就涉及到兩個系統(tǒng)之間數(shù)據(jù)的傳遞。
實現(xiàn)架構(gòu)如下:
首先Dealer的數(shù)據(jù)通過MSMQ傳遞到MSMQ Server,此時可以將數(shù)據(jù)插入到SQL Server數(shù)據(jù)庫中,同時利用FTP將數(shù)據(jù)傳送到專門的文件服務(wù)器上。然后利用IBM的EAI技術(shù)(企業(yè)應(yīng)用集成,Enterprise Application Itegration)定期將文件服務(wù)器中的文件,利用接口規(guī)范寫入到EAI數(shù)據(jù)庫服務(wù)器中,并最終寫道EBS的Oracle數(shù)據(jù)庫中。
上述架構(gòu)是一個典型的分布式處理結(jié)構(gòu),而技術(shù)實現(xiàn)的核心就是MSMQ和EAI。由于我們已經(jīng)定義了統(tǒng)一的接口規(guī)范,在通過消息隊列形成文件后,此時的數(shù)據(jù)就已經(jīng)與平臺無關(guān)了,使得在.Net平臺下的分銷商管理系統(tǒng)能夠與Oracle的EBS集成起來,完成數(shù)據(jù)的處理。
以上是“PetShop數(shù)據(jù)訪問層中消息處理的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
分享文章:PetShop數(shù)據(jù)訪問層中消息處理的示例分析-創(chuàng)新互聯(lián)
本文網(wǎng)址:http://redsoil1982.com.cn/article32/diojsc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供面包屑導(dǎo)航、外貿(mào)建站、企業(yè)網(wǎng)站制作、域名注冊、靜態(tài)網(wǎng)站、App設(shè)計
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容