一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - ASP.NET教程 - 《解剖PetShop》之三:PetShop數據訪問層之消息處理

《解剖PetShop》之三:PetShop數據訪問層之消息處理

2020-01-12 13:54張逸 ASP.NET教程

本文主要講解PetShop4.0的數據訪問層的消息處理部分,需要的朋友可以參考下。

三、PetShop數據訪問層之消息處理

  在進行系統設計時,除了對安全、事務等問題給與足夠的重視外,性能也是一個不可避免的問題所在,尤其是一個B/S結構的軟件系統,必須充分地考慮訪問量、數據流量、服務器負荷的問題。解決性能的瓶頸,除了對硬件系統進行升級外,軟件設計的合理性尤為重要。

  在前面我曾提到,分層式結構設計可能會在一定程度上影響數據訪問的性能,然而與它給設計人員帶來的好處相比,幾乎可以忽略。要提供整個系統的性能,還可以從數據庫的優化著手,例如連接池的使用、建立索引、優化查詢策略等等,例如在PetShop中就利用了數據庫的Cache,對于數據量較大的訂單數據,則利用分庫的方式為其單獨建立了Order和Inventory數據庫。而在軟件設計上,比較有用的方式是利用多線程與異步處理方式。

  在PetShop4.0中,使用了Microsoft Messaging Queue(MSMQ)技術來完成異步處理,利用消息隊列臨時存放要插入的數據,使得數據訪問因為不需要訪問數據庫從而提供了訪問性能,至于隊列中的數據,則等待系統空閑的時候再進行處理,將其最終插入到數據庫中。

  PetShop4.0中的消息處理,主要分為如下幾部分:消息接口IMessaging、消息工廠MessagingFactory、MSMQ實現MSMQMessaging以及數據后臺處理應用程序OrderProcessor。

  從模塊化分上,PetShop自始自終地履行了“面向接口設計”的原則,將消息處理的接口與實現分開,并通過工廠模式封裝消息實現對象的創建,以達到松散耦合的目的。

  由于在PetShop中僅對訂單的處理使用了異步處理方式,因此在消息接口IMessaging中,僅定義了一個IOrder接口,其類圖如下:
《解剖PetShop》之三:PetShop數據訪問層之消息處理
  在對消息接口的實現中,考慮到未來的擴展中會有其他的數據對象會使用MSMQ,因此定義了一個Queue的基類,實現消息Receive和Send的基本操作:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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類型,作為存放數據的隊列。MSMQ隊列是一個可持久的隊列,因此不必擔心用戶不間斷地下訂單會導致訂單數據的丟失。在PetShopQueue設置了timeout值,OrderProcessor會根據timeout值定期掃描隊列中的訂單數據。

  MSMQMessaging模塊中,Order對象實現了IMessaging模塊中定義的接口IOrder,同時它還繼承了基類PetShopQueue,其定義如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Order:PetShopQueue, PetShop.IMessaging.IOrder
 
  方法的實現代碼如下:
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);
}

所以,最后的類圖應該如下:

《解剖PetShop》之三:PetShop數據訪問層之消息處理

注意在Order類的Receive()方法中,是用new關鍵字而不是override關鍵字來重寫其父類PetShopQueue的Receive()虛方法。因此,如果是實例化如下的對象,將會調用PetShopQueue的Receive()方法,而不是子類Order的Receive()方法:

?
1
2
PetShopQueue queue = new Order();
queue.Receive();

從設計上來看,由于PetShop采用“面向接口設計”的原則,如果我們要創建Order對象,應該采用如下的方式:

?
1
2
IOrder order = new Order();
order.Receive();

考慮到IOrder的實現有可能的變化,PetShop仍然利用了工廠模式,將IOrder對象的創建用專門的工廠模塊進行了封裝:
《解剖PetShop》之三:PetShop數據訪問層之消息處理

在類QueueAccess中,通過CreateOrder()方法利用反射技術創建正確的IOrder類型對象:

?
1
2
3
4
5
public static PetShop.IMessaging.IOrder CreateOrder()
{
 string className = path + ".Order";
 return PetShop.IMessaging.IOrder)Assembly.Load(path).CreateInstance(className);
}

path的值通過配置文件獲取:

?
1
private static readonly string path = ConfigurationManager.AppSettings["OrderMessaging"];

而配置文件中,OrderMessaging的值設置如下:

?
1
<add key="OrderMessaging" value="PetShop.MSMQMessaging"/>

之所以利用工廠模式來負責對象的創建,是便于在業務層中對其調用,例如在BLL模塊中OrderAsynchronous類:

?
1
2
3
4
5
6
7
8
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接口的實現發生變化,這種實現方式就可以使得客戶僅需要修改配置文件,而不需要修改代碼,如此就可以避免程序集的重新編譯和部署,使得系統能夠靈活應對需求的改變。例如定義一個實現IOrder接口的SpecialOrder,則可以新增一個模塊,如PetShop.SpecialMSMQMessaging,而類名則仍然為Order,那么此時我們僅需要修改配置文件中OrderMessaging的值即可:

?
1
<add key="OrderMessaging" value="PetShop.SpecialMSMQMessaging"/>

OrderProcessor是一個控制臺應用程序,不過可以根據需求將其設計為Windows Service。它的目的就是接收消息隊列中的訂單數據,然后將其插入到Order和Inventory數據庫中。它利用了多線程技術,以達到提高系統性能的目的。
  在OrderProcessor應用程序中,主函數Main用于控制線程,而核心的執行任務則由方法ProcessOrders()實現:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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()來獲取消息隊列中的訂單數據,并將其放入到一個ArrayList對象中,然而再調用PetShop.BLL.Order類的Insert方法將其插入到Order和Inventory數據庫中。

在PetShop.BLL.Order類中,并不是直接執行插入訂單的操作,而是調用了IOrderStrategy接口的Insert()方法:

?
1
2
3
4
5
6
7
8
public void Insert(OrderInfo order)
{
 // Call credit card procesor
 ProcessCreditCard(order);
 
 // Insert the order (a)synchrounously based on configuration
 orderInsertStrategy.Insert(order);
}

在這里,運用了一個策略模式,類圖如下所示:
《解剖PetShop》之三:PetShop數據訪問層之消息處理
在PetShop.BLL.Order類中,仍然利用配置文件來動態創建IOrderStategy對象:

?
1
2
3
4
5
6
7
8
9
10
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是一個單獨的應用程序,因此它使用的配置文件與PetShop不同,是存放在應用程序的App.config文件中,在該文件中,對IOrderStategy的配置為:

?
1
2
<add key="OrderStrategyAssembly" value="PetShop.BLL" />
<add key="OrderStrategyClass" value="PetShop.BLL.OrderSynchronous" />

因此,以異步方式插入訂單的流程如下圖所示:

《解剖PetShop》之三:PetShop數據訪問層之消息處理

  Microsoft Messaging Queue(MSMQ)技術除用于異步處理以外,它主要還是一種分布式處理技術。分布式處理中,一個重要的技術要素就是有關消息的處理,而在System.Messaging命名空間中,已經提供了Message類,可以用于承載消息的傳遞,前提上消息的發送方與接收方在數據定義上應有統一的接口規范。

  MSMQ在分布式處理的運用,在我參與的項目中已經有了實現。在為一個汽車制造商開發一個大型系統時,分銷商Dealer作為.Net客戶端,需要將數據傳遞到管理中心,并且該數據將被Oracle的EBS(E-Business System)使用。由于分銷商管理系統(DMS)采用的是C/S結構,數據庫為SQL Server,而汽車制造商管理中心的EBS數據庫為Oracle。這里就涉及到兩個系統之間數據的傳遞。
實現架構如下:

《解剖PetShop》之三:PetShop數據訪問層之消息處理

  首先Dealer的數據通過MSMQ傳遞到MSMQ Server,此時可以將數據插入到SQL Server數據庫中,同時利用FTP將數據傳送到專門的文件服務器上。然后利用IBM的EAI技術(企業應用集成,Enterprise Application Itegration)定期將文件服務器中的文件,利用接口規范寫入到EAI數據庫服務器中,并最終寫道EBS的Oracle數據庫中。
上述架構是一個典型的分布式處理結構,而技術實現的核心就是MSMQ和EAI。由于我們已經定義了統一的接口規范,在通過消息隊列形成文件后,此時的數據就已經與平臺無關了,使得在.Net平臺下的分銷商管理系統能夠與Oracle的EBS集成起來,完成數據的處理。

以上就是PetShop數據訪問層消息處理部分的全部內容,希望能給大家一個參考,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 91短视频在线免费观看 | 国产成人免费在线观看 | 国产精品亚洲综合久久 | 国产男女乱淫真视频全程播放 | www.四虎网站 | 美女扒开腿让男人桶爽免费gif | 国产午夜免费秋霞影院 | 欧美猛男同志同性video | 欧美一级特黄特色大片免费 | 国产无套在线播放 | 胸奶好大好紧好湿好爽 | 美女和男生搞基 | 99热这里只有精品在线 | 欧美一区二区三区免费高 | 人人爱操 | ipx-177绝对领域在线观看 | 国色天香社区在线视频免费观看 | 丝袜足控免费网站xx动漫漫画 | 欧美日韩一区二区中文字幕视频 | 视频免费在线 | 国产愉拍 | 午夜私人影院在线观看 视频 | 女人张开腿让男人桶爽 | 欧美成人免费观看国产 | 免费草比视频 | 波多野结衣在线免费观看 | 午夜DY888国产精品影院 | 日日操免费视频 | 美女扒开肌肌让男人桶 | 免费 视频| 欧美一级高清片 | 国产精品极品美女自在线 | 久久91精品国产91 | 成人免费视频大全 | 72张让男人一看就硬的图片 | 全彩孕交漫画福利啪啪吧 | 精品无人区乱码1区2区3区在线 | 4hc44四虎www在线影院男同 | 女人张开腿 让男人桶个爽 免费观看 | 欧美日韩精品一区二区三区视频播放 | 日本高清在线播放一区二区三区 |