filed under:
design & pattern — bruce zhang @ 12:11 pm
《解剖petshop》系列之三
三、petshop資料訪問層之訊息處理
在進行系統設計時,除了對安全、事務等問題給與足夠的重視外,效能也是乙個不可避免的問題所在,尤其是乙個b/s結構的軟體系統,必須充分地考慮訪問量、資料流量、伺服器負荷的問題。解決效能的瓶頸,除了對硬體系統進行公升級外,軟體設計的合理性尤為重要。
在前面我曾提到,分層式結構設計可能會在一定程度上影響資料訪問的效能,然而與它給設計人員帶來的好處相比,幾乎可以忽略。要提供整個系統的效能,還可以從資料庫的優化著手,例如連線池的使用、建立索引、優化查詢策略等等,例如在petshop中就利用了資料庫的cache,對於資料量較大的訂單資料,則利用分庫的方式為其單獨建立了order和inventory資料庫。而在軟體設計上,比較有用的方式是利用多執行緒與非同步處理方式。
在petshop4.0中,使用了microsoft messaging queue(m**q)技術來完成非同步處理,利用訊息佇列臨時存放要插入的資料,使得資料訪問因為不需要訪問資料庫從而提供了訪問效能,至於佇列中的資料,則等待系統空閒的時候再進行處理,將其最終插入到資料庫中。
petshop4.0中的訊息處理,主要分為如下幾部分:訊息介面imessaging、訊息工廠messagingfactory、m**q實現m**qmessaging以及資料後台處理應用程式orderprocessor。
從模組化分上,petshop自始自終地履行了「面向介面設計」的原則,將訊息處理的介面與實現分開,並通過工廠模式封裝訊息實現物件的建立,以達到鬆散耦合的目的。
由於在petshop中僅對訂單的處理使用了非同步處理方式,因此在訊息介面imessaging中,僅定義了乙個iorder介面,其類圖如下:
在對訊息介面的實現中,考慮到未來的擴充套件中會有其他的資料物件會使用m**q,因此定義了乙個queue的基類,實現訊息receive和send的基本操作:
public virtual object receive()
catch (messagequeueexception mqex)
}public virtual void send(object msg)
其中queue物件是system.messaging.messagequeue型別,作為存放資料的佇列。m**q佇列是乙個可持久的佇列,因此不必擔心使用者不間斷地下訂單會導致訂單資料的丟失。在petshopqueue設定了timeout值,orderprocessor會根據timeout值定期掃瞄佇列中的訂單資料。
m**qmessaging模組中,order物件實現了imessaging模組中定義的介面iorder,同時它還繼承了基類petshopqueue,其定義如下:
public class order:petshopqueue, petshop.imessaging.iorder
方法的實現**如下:
public new orderinfo receive()
public orderinfo receive(int timeout)
public void send(orderinfo ordermessage)
所以,最後的類圖應該如下:
注意在order類的receive()方法中,是用new關鍵字而不是override關鍵字來重寫其父類petshopqueue的receive()虛方法。因此,如果是例項化如下的物件,將會呼叫petshopqueue的receive()方法,而不是子類order的receive()方法:
petshopqueue queue = new order();
queue.receive();
從設計上來看,由於petshop採用「面向介面設計」的原則,如果我們要建立order物件,應該採用如下的方式:
iorder order = new order();
order.receive();
考慮到iorder的實現有可能的變化,petshop仍然利用了工廠模式,將iorder物件的建立用專門的工廠模組進行了封裝:
order order = new order();
while (true)
else
//update elapsed time
elapsedtime = new timespan(datetime.now.ticks).totalseconds - datetimestarting.totalseconds;
}catch (timeoutexception)
}//process the queued orders
for (int k = 0; k < queueorders.count; k++)
//batch complete or m**q 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()方法:
public void insert(orderinfo order)
在這裡,運用了乙個策略模式,類圖如下所示:
microsoft messaging queue(m**q)技術除用於非同步處理以外,它主要還是一種分布式處理技術。分布式處理中,乙個重要的技術要素就是有關訊息的處理,而在system.messaging命名空間中,已經提供了message類,可以用於承載訊息的傳遞,前提上訊息的傳送方與接收方在資料定義上應有統一的介面規範。
m**q在分布式處理的運用,在我參與的專案中已經有了實現。在為乙個汽車製造商開發乙個大型系統時,分銷商dealer作為.net客戶端,需要將資料傳遞到管理中心,並且該資料將被oracle的ebs(e-business system)使用。由於分銷商管理系統(dms)採用的是c/s結構,資料庫為sql server,而汽車製造商管理中心的ebs資料庫為oracle。這裡就涉及到兩個系統之間資料的傳遞。
實現架構如下:
PetShop資料訪問層之訊息處理
解剖petshop 系列之三 三 petshop資料訪問層之訊息處理 在進行系統設計時,除了對安全 事務等問題給與足夠的重視外,效能也是乙個不可避免的問題所在,尤其是乙個b s結構的軟體系統,必須充分地考慮訪問量 資料流量 伺服器負荷的問題。解決效能的瓶頸,除了對硬體系統進行公升級外,軟體設計的合理...
PetShop資料訪問層之訊息處理
解剖petshop 系列之三 三 petshop資料訪問層之訊息處理 在進行系統設計時,除了對安全 事務等問題給與足夠的重視外,效能也是乙個不可避免的問題所在,尤其是乙個b s結構的軟體系統,必須充分地考慮訪問量 資料流量 伺服器負荷的問題。解決效能的瓶頸,除了對硬體系統進行公升級外,軟體設計的合理...
PetShop資料訪問層之訊息處理
解剖petshop 系列之三 三 petshop資料訪問層之訊息處理 在進行系統設計時,除了對安全 事務等問題給與足夠的重視外,效能也是乙個不可避免的問題所在,尤其是乙個b s結構的軟體系統,必須充分地考慮訪問量 資料流量 伺服器負荷的問題。解決效能的瓶頸,除了對硬體系統進行公升級外,軟體設計的合理...