知道MSMQ,控制ASP進(jìn)程 (一)
發(fā)表時(shí)間:2024-02-16 來(lái)源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]我們?cè)谑褂?ASP 程序時(shí)常常會(huì)遇到這些情況:某個(gè)進(jìn)程花費(fèi)了過長(zhǎng)的時(shí)間而導(dǎo)致在客戶端過期、訪問者已經(jīng)放棄了對(duì)你的網(wǎng)站的訪問而離開去了別的網(wǎng)站、或你的服務(wù)器上阻塞了大量的死隊(duì)列時(shí),系統(tǒng)出現(xiàn) "Server is too busy" 錯(cuò)誤信息。 ...
我們?cè)谑褂?ASP 程序時(shí)常常會(huì)遇到這些情況:某個(gè)進(jìn)程花費(fèi)了過長(zhǎng)的時(shí)間而導(dǎo)致在客戶端過期、訪問者已經(jīng)放棄了對(duì)你的網(wǎng)站的訪問而離開去了別的網(wǎng)站、或你的服務(wù)器上阻塞了大量的死隊(duì)列時(shí),系統(tǒng)出現(xiàn) "Server is too busy" 錯(cuò)誤信息。
當(dāng)你在設(shè)計(jì)網(wǎng)站的過程中碰到這些問題時(shí),一個(gè)有效的解決辦法就是使用 Microsoft Message Queue (MSMQ) 來(lái)結(jié)束這些進(jìn)程,讓網(wǎng)站恢復(fù)正常!
到底 MSMQ 是個(gè)什么樣的東西呢?我們下面作一下了解:
一、 Microsoft Message Queue 的基本介紹:
MSMQ ( 代號(hào)又叫 "Falcon") 是運(yùn)行在 Windows NT 的服務(wù) , 它提供運(yùn)用程序之間的異步通訊。你可以在 NT4 Option Pack 中找到它。 MSMQ 的基本概念非常的簡(jiǎn)單:它可以被看成是運(yùn)用程序之間的 email :一個(gè)消息被打包到一個(gè)特定類型的容器中,并把這個(gè)消息保存到一個(gè)用與特別作用的隊(duì)列中直到收信者接受該消息為止。這些隊(duì)列能夠確保 MSMQ 的傳送,而不管當(dāng)前網(wǎng)絡(luò)連接的狀況如何。
象所有的電子郵件一樣, MSMQ 消息有一個(gè)發(fā)送者和一個(gè)接收者 , 其中的接收者應(yīng)該能夠訪問隊(duì)列。一個(gè)單一隊(duì)列中的一個(gè)單獨(dú)消息,它擁有多個(gè)接受者例如 respinder 。而消息的發(fā)送者通常是 Web Server(IIS) 。
MSMQ 也能夠和其他消息系統(tǒng)進(jìn)行通訊。例如: Sun Solaris, HP-UNIX,OS/2, VMS, AS/400 平臺(tái)。像其他的 BackOffice 服務(wù)一樣, MSMQ 有一個(gè) COM API ( mqoa.dll ) 提供給開發(fā)者開發(fā)程序。其中最常用的三個(gè)類為: MSMQQueueInfo, MSMQQueue, MSMQMessage 。
( 1 )、 MSQMQueueInfo
MSMQQueueInfo 允許你新建,打開,刪除隊(duì)列中的消息 . 要和隊(duì)列建立聯(lián)系首先需要設(shè)置 PathName ,這是一個(gè)命名隊(duì)列的屬性,它告訴 MSQM 是哪臺(tái)機(jī)器上的隊(duì)列。
< %
Dim objQueueInfo
Dim objQueue
Set objQueueInfo=Server.CreateObject("MSMQ.MSMQQueueInfo")
objQueue.PathName = ".\MyQu"
Set objQueue = objQueueInfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)
%>
上面的代碼打開一個(gè)叫 MyQueue 的本地隊(duì)列。如果隊(duì)列在另外一臺(tái)服務(wù)器上,代碼應(yīng)該是這樣的:
objQueue.PathName = "SomeOtherComputer\MyQu"
打開隊(duì)列中有兩個(gè)參數(shù): Access 和 ShareMode 。 Access 表示將要對(duì)隊(duì)列執(zhí)行什么操作。一般有三個(gè)操作:
MQ_PEEK_ACCESS (32), MQ_RECEIVE_ACCESS (1), MQ_SEND_ACCESS (2) 。
MQ_PEEK_ACCESS 用來(lái)在特定的隊(duì)列中查找消息。但對(duì)該消息不進(jìn)行操作。
MQ_RECEIVE_ACCESS 用來(lái)在讀取隊(duì)列中的消息后刪除它。
MQ_SEND_ACCESS 用來(lái)在隊(duì)列中發(fā)送消息 , 但不接收消息。
需要注意的是在使用打開操作后返回了一個(gè) MSMQQueue 對(duì)象。下面是一個(gè)典型的新建和刪除操作例子:
< %
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 類用來(lái)描述一個(gè)在 MSMQ 服務(wù)中打開的隊(duì)列。該類提供了一個(gè)用來(lái)在指針隊(duì)列中的消息進(jìn)行循環(huán)的功能。你不能夠打開一個(gè)使用了 MSMQQueue 類的隊(duì)列要這么干只能夠使用 MSQMQueueInfo (見上例),雖然許多 ASP 運(yùn)用程序通常使用 MSMQ 來(lái)發(fā)消息,但是很多時(shí)候也需要 ASP 來(lái)顯示這個(gè)消息的具體內(nèi)容。
獲取消息的方式有兩種:同步方式,異步方式,但是 ASP 只能夠使用同步方式。這是因?yàn)?ASP 不能夠在服務(wù)端申明一個(gè) WithEvents 變量。
下面先舉一個(gè)異步方式使用 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
這段代碼首先建立一個(gè)隊(duì)列(如果它還不存在的話)。然后 m_objMSMQEvent 對(duì)象通過調(diào)用 EnableNotification 連接到 MSMQQueue 對(duì)象。一旦連接到 MSMQEvent 對(duì)象 , 接下來(lái)需做的僅僅是完成 Arrived 和 Arrived_Error ( 可選的 ) 事件。 Arrived 事件當(dāng)一個(gè)新的消息到達(dá)隊(duì)列時(shí)將被觸發(fā)該事件返回兩個(gè)指針 , 一個(gè)是指向隊(duì)列中應(yīng)該從來(lái)開始讀消息的位置,另外一個(gè)是當(dāng)前的位置。如果發(fā)生錯(cuò)誤,將觸發(fā) ArrivedError 事件當(dāng)同步獲取消息時(shí),會(huì)一直等到消息可獲取或則超時(shí)時(shí)程序才會(huì)不被掛起。代碼如下:
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 類支持隊(duì)列中消息的所有屬性。 MSMQ 消息有兩個(gè)方法和繁多的屬性。其中兩個(gè)最主要的屬性是: Body 和 LabeL 。最主要的方法有 Send 。有兩種方法來(lái)獲取消息: opening , peeking 。當(dāng)使用 opening 方式后,該消息將會(huì)被刪除掉;當(dāng)使用 peeking 方式后,該消息仍然保存在隊(duì)列中直到它過期。它們的返回值都是指向該消息的指針。下例的代碼將打開一個(gè)消息,并顯示其 Body 和 Label
Private Sub LookForMessage()
Dim objQInfo As New MSMQQueueInfo
Dim objQReceive As MSMQQueue
Dim objMessage As MSMQMessage
objQInfo.PathName = ".\test"
Set objQReceive = objQInfo.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
Set objMessage = objQReceive.Receive(, , , 1000)
If Not objMessage Is Nothing Then
MsgBox objMessage.Label & " - " & objMessage.Body
Else
Msgbox "Nothing in the queue"
End If
objQReceive.Close
Set objQInfo = Nothing
Set objQReceive = Nothing
Set objMessage = Nothing
End Sub
這段代碼打開一個(gè)隊(duì)列并在該隊(duì)列中查找消息,使用 Receive 方法,主要是設(shè)置一個(gè) 1000 微秒的超時(shí) , 它告訴 MSMQ1000 微秒后停止查找設(shè)置一個(gè)非常段的超時(shí)的功能主要是用來(lái)檢查是否存在消息而不是等候一個(gè)消息。也就是說(shuō)如果你知識(shí)想看看是否有消息可以使用該方法。如果無(wú)消息,返回的指針為空 (If Not objMessage Is Nothing) 。下面是發(fā)送一個(gè)消息的代碼:
< %
Dim objQInfo
Dim objQSend
Dim objMessage
Set objQInfo = Server.CreateObject("MSMQ.MSMQQueueInfo")
objQInfo.PathName = ".\test"
Set objQSend = objQInfo.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)
Set objMessage = Server.CreateObject("MSMQ.MSMQMessage")
objMessage.Label = "This is the label."
objMessage.Body = "This is the body."
objMessage.Send objQSend
objQSend.Close
Set objQInfo = Nothing
Set objQSend = Nothing
Set objMessage = Nothing
%>
對(duì)于 MSMQ 的有關(guān)基本知識(shí)我們已做了舉例介紹,下面將就它的具體運(yùn)用進(jìn)行的了解及探討!