進程|控制 我們在使用 ASP 程式時常常會遇到這些情況:某個進程花費了過長的時間而導致在用戶端到期、訪問者已經放棄了對你的網站的訪問而離開去了別的網站、或你的伺服器上阻塞了大量的死隊列時,系統出現 "Server is too busy" 錯誤資訊。
當你在設計網站的過程中碰到這些問題時,一個有效解決辦法就是使用 Microsoft Message Queue (MSMQ) 來結束這些進程,讓網站恢複正常!
到底 MSMQ 是個什麼樣的東西呢?我們下面作一下瞭解:
一、 Microsoft Message Queue 的基本介紹:
MSMQ ( 代號又叫 "Falcon") 是運行在 Windows NT 的服務 , 它提供運用程式之間的非同步通訊。你可以在 NT4 Option Pack 中找到它。 MSMQ 的基本概念非常的簡單:它可以被看成是運用程式之間的 email :一個訊息被打包到一個特定類型的容器中,並把這個訊息儲存到一個用與特別作用的隊列中直到收信者接受該訊息為止。這些隊列能夠確保 MSMQ 的傳送,而不管當前網路連接的狀況如何。
象所有的電子郵件一樣, MSMQ 訊息有一個寄件者和一個接收者 , 其中的接收者應該能夠訪問隊列。一個單一隊列中的一個單獨訊息,它擁有多個接受者例如 respinder 。而訊息的寄件者通常是 Web Server(IIS) 。
MSMQ 也能夠和其他訊息系統進行通訊。例如: Sun Solaris, HP-UNIX,OS/2, VMS, AS/400 平台。像其他的 BackOffice 服務一樣, MSMQ 有一個 COM API ( mqoa.dll ) 提供給開發人員開發程式。其中最常用的三個類為: MSMQQueueInfo, MSMQQueue, MSMQMessage 。
( 1 )、 MSQMQueueInfo
MSMQQueueInfo 允許你建立,開啟,刪除隊列中的訊息 . 要和隊列建立聯絡首先需要設定 PathName ,這是一個命名隊列的屬性,它告訴 MSQM 是哪台機器上的隊列。
< %
Dim objQueueInfo
Dim objQueue
Set objQueueInfo=Server.CreateObject("MSMQ.MSMQQueueInfo")
objQueue.PathName = ".\MyQu"
Set objQueue = objQueueInfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)
%>
上面的代碼開啟一個叫 MyQueue 的本地隊列。如果隊列在另外一台伺服器上,代碼應該是這樣的:
objQueue.PathName = "SomeOtherComputer\MyQu"
開啟隊列中有兩個參數: Access 和 ShareMode 。 Access 表示將要對隊列執行什麼操作。一般有三個操作:
MQ_PEEK_ACCESS (32), MQ_RECEIVE_ACCESS (1), MQ_SEND_ACCESS (2) 。
MQ_PEEK_ACCESS 用來在特定的隊列中尋找訊息。但對該訊息不進行操作。
MQ_RECEIVE_ACCESS 用來在讀取隊列中的訊息後刪除它。
MQ_SEND_ACCESS 用來在隊列中發送訊息 , 但不接收訊息。
需要注意的是在使用開啟操作後返回了一個 MSMQQueue 對象。下面是一個典型的建立和刪除操作例子:
< %
Dim objQueue
Set objQueue = Server.CreateObject("MSMQ.MSMQQueueInfo")
objQueue.PathName = ".\MyQu"
objQueue.Create
%>
< %
Dim objQueue
Set objQueue = Server.CreateObject("MSMQ.MSMQQueueInfo")
objQueue.PathName = ".\MyQu"
objQueue.Delete
%>
( 2 )、 MSMQQueue
MSMQQueue 類用來描述一個在 MSMQ 服務中開啟的隊列。該類提供了一個用來在指標隊列中的訊息進行迴圈的功能。你不能夠開啟一個使用了 MSMQQueue 類的隊列要這麼幹只能夠使用 MSQMQueueInfo (見上例),雖然許多 ASP 運用程式通常使用 MSMQ 來發訊息,但是很多時候也需要 ASP 來顯示這個訊息的具體內容。
擷取訊息的方式有兩種:同步方式,非同步方式,但是 ASP 只能夠使用同步方式。這是因為 ASP 不能夠在服務端申明一個 WithEvents 變數。
下面先舉一個非同步方式使用 MSMQ 的例子(僅 VB 中)
Option Explicit
Dim m_objQueueInfo As New MSMQQueueInfo
Dim m_objQueue As MSMQQueue
Dim WithEvents m_objMSMQEvent As MSMQEvent
Private Sub Form_Load()
m_objQueueInfo.PathName = ".\MyQu"
m_objQueueInfo.Label = "My Sample Queue"
On Error Resume Next
m_objQueueInfo.Create
On Error GoTo 0
Set m_objQueue = m_objQueueInfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
Set m_objMSMQEvent = New MSMQEvent
m_objQueue.EnableNotification m_objMSMQEvent, MQMSG_CURRENT, 1000
End Sub
Private Sub m_objMSMQEvent_Arrived(ByVal Queue As Object, ByVal Cursor As Long)
Dim m_objMessage As MSMQMessage
Set m_objMessage = Queue.PeekCurrent
MsgBox "Message Received: " & m_objMessage.Label
m_objQueue.EnableNotification m_objMSMQEvent, MQMSG_NEXT, 10000
End Sub
Private Sub m_objMSMQEvent_ArrivedError(ByVal Queue As Object, ByVal ErrorCode As Long, ByVal Cursor As Long)
MsgBox "Error accorded: " & ErrorCode
End Sub
這段代碼首先建立一個隊列(如果它還不存在的話)。然後 m_objMSMQEvent 對象通過調用 EnableNotification 串連到 MSMQQueue 對象。一旦串連到 MSMQEvent 對象 , 接下來需做的僅僅是完成 Arrived 和 Arrived_Error ( 可選的 ) 事件。 Arrived 事件當一個新的訊息到達隊列時將被觸發該事件返回兩個指標 , 一個是指向隊列中應該從來開始讀訊息的位置,另外一個是當前的位置。如果發生錯誤,將觸發 ArrivedError 事件當同步擷取訊息時,會一直等到訊息可擷取或則逾時時程式才會不被掛起。代碼如下:
Public Sub DisplayMessages()
Dim objQueueInfo As New MSMQQueueInfo
Dim objQueue As MSMQQueue
Dim objMessage As MSMQMessage
objQueueInfo.PathName = ".\MyQu"
objQueueInfo.Label = "My Sample Queue"
On Error Resume Next
objQueueInfo.Create
On Error GoTo 0
Set objQueue = objQueueInfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
Do While True
Set objMessage = objQueue.Peek(, , 1000)
If objMessage Is Nothing Then Exit Do
MsgBox "Message: " & objMessage.Label
Loop
MsgBox "No more new messages."
objQueue.Close
Set objMessage = Nothing
Set objQueue = Nothing
Set objQueueInfo = Nothing
End Sub
( 3 )、 MSMQMessage
MSMQMessage 類支援隊列中訊息的所有屬性。 MSMQ 訊息有兩個方法和繁多的屬性。