Saturday, June 20, 2009

Clustering MQ Series and BizTalk Send/Receive

We have a 3rd party application that uses MQ Series as an integration bridge. BizTalk is used to manage a business process and perform message transformation between this system and our ERP.

We have been using this configuration for the past couple years and it came time to upgrade this 3rd party application. This application now supports Websphere MQ 6.0 where as we were previously running Websphere MQ 5.3. Since it was time for an upgrade and we do have a pretty large BizTalk farm with a team that is responsible for supporting both BizTalk and MQ we decided to install MQ 6.0 on this same cluster(as BizTalk)...for better or worse(it is

In our previous configuration we had MQ 5.3 running on an Active/Passive Cluster that did not include BizTalk. When running BizTalk 2006 and wanting to use the MQ Series Adapter, there is a component that you must install on the MQ Series servers. The component that is installed is called MQSAgent*. Now if you are running BizTalk 2004 then the component is called MQSAgent where as if you are running BizTalk 2006 it is called MQSAgent2. According to this doc, the component is still called MQSAgent2 for BizTalk 2009. In our previous configuration, I must admit it was rock solid. We never had any fail over issues whatsoever.

We recently ran into some issues in the Test environment with the new configuration. We found that you needed to ensure that MS Distributed Transaction Coordinator (MS DTC) and MQ Series on the same node in order for it to function correctly. MSDTC is leveraged to support Guaranteed Reliable message delivery.

The specific problem that we ran into was that when we failed the MQ Resource group over to a new node, BizTalk would essentially just hang(with respect to MQ message processing). We couldn't send or receive messages with MQ. I then ran into this kb: The BizTalk Server Adapter for MQSeries version 2.0 no longer retrieves messages from a clustered MQSeries queue manager when the queue manager fails over to a different cluster node. This paragraph accurately describes our scenario:

You may configure the Microsoft BizTalk Server Adapter for MQSeries version 2.0 to receive messages from a clustered MQSeries queue manager. If the queue manager fails over to a different cluster node, the BizTalk Server Adapter for MQSeries no longer retrieves messages from the clustered MQSeries queue. When this behavior occurs, the following event is logged in the Application event log:

Event Type: Warning
Event Source: BizTalk Server 2006
Event Category: BizTalk Server 2006
Event ID: 5740
Date: 6/20/2009Time: 10:16:40 AM
User: N/A
Description:The adapter "MQSeries" raised an error message. Details "Error encountered on opening Queue Manager name = ISVC.MSG4.QM.T Reason code = 2059.".
For more information, see Help and Support Center at

Later on in the kb it describes a "Workaround" *cough* HACK */cough* that is suppose to terminate the MQSAgent from the node that previously was hosting the MQ/MSDTC Resource group.

Option Explicit
On Error Resume Next

Dim sComputerName, oWMIService, colRunningServices, oService, colProcessList, objProcess

If Wscript.Arguments.Count = 0 Then

sComputerName = "."
Call ServStat
End If

Sub ServStat
Set oWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & sComputerName& "\root\cimv2")
Set colRunningServices = oWMIService.ExecQuery _
("Select * from Win32_Service where DisplayName='Distributed Transaction Coordinator'")

For Each oService in colRunningServices
'Wscript.Echo oService.DisplayName & VbTab & oService.State
if (oService.State="Stopped") Then
'Wscript.Echo "Stopped"
' find the dllhost
Set colProcessList = oWMIService.ExecQuery ("SELECT * FROM Win32_Process WHERE Name = 'DLLHOST.EXE'")

For Each objProcess in colProcessList
if inStr(objProcess.CommandLine, "6D06157A-730B-4CB3-BD11-D48AC6B8A4BB")>0 then

'Wscript.Echo objProcess.ProcessId
Dim objShell
Set objShell = CreateObject("WScript.Shell")
objShell.Run "cmd /k kill -f " & objProcess.ProcessId & "& exit"
end if
end if

End Sub
I have highlighted two issues with this script in red:

  1. The ID 6D06157A-730B-4CB3-BD11-D48AC6B8A4BB that they are referring to in the script is for the MQSAgent (BizTalk 2004) and not BizTalk 2006. The MQSAgent2 ID (BizTalk 2006) is C691D827-19A0-42E2-B5E8-2892401481F5.

  2. The other issue is that the script will issue the following command to kill the MQSAgent# process on the server that use to host the DTC/MQ Resource group. objShell.Run "cmd /k kill -f " & objProcess.ProcessId & "& exit The problem with this is that the kill command is not available on Windows 2003 and I suspect Windows 2008 as well. This command has been replaced with Taskkill. I opted to go a different route since the script they have provided is based upon WMI and VBscript I have replaced this line with objProcess.Terminate()

My testing to this point have been very successful. I have not had to manually intevene whatsoever and have not lost any messages when failing resources over or rebooting servers. The only delay that you will see is if you have messages inflight while you bounce resources is that if the Queue is still down that BizTalk will use the Send Port's configuration to issue retries. This is very standard BizTalk behaviour and is performing as expected.

So what does this script do? It essentially looks to see if the DTC service is running on the node that this script is running on. If the DTC service is running, the script will exit since we still need the MQSAgent to run on this server with DTC. If DTC is not running then it will look for a process called 'DLLHOST.EXE' that has a Process ID (PID) of the MQSAgent. If it finds an instance of this process it will terminate it so that this process does not lock up BizTalk from sending or receiving messages with MQ Series.

This sounds like an opportunity to cluster the MQSAgent application. However, the guidance from Microsoft is to not cluster it:

There is no requirement to cluster the MQSAgent (MQSAgent2) COM+ application that is used with the BizTalk Server MQSeries adapter. To provide high availability for this component, install the component on each cluster node. If the COM+ application stops, the next call from the client will start it.

I don't know...seems pretty clunky to me. I will have to follow up further with support.


Ben Cops said...

Fantastic - my previous client was the client where this problem occured and went through support and we came up with this workaround! Its still an open issue and as far as I know, it hasn't been resolved yet, but in our testing we found this workaround caused no issues (failover is an uncommon event after all).

For the record, the kill task comes with the resource kit (we put it on the server manually).

Also its known that you can't run MQ on a different node to MSDTC, because you can't access MQ remotely (with the standard components for .net that are in the MQ adapter). This is why you can't run MQ QMs in an active/active config on a windows cluster (if you're using this tech to get/put). There is another MQ adapter that allows you to do this though (the client based biztalk adapter for MQ; MQSC) - see

Kent Weare said...

Thanks for the feedback Ben. The main concern for me around failback is during Windows Patching cycles. I didn't want to take any chances with failover's occuring and having a critial app hung up due to this issue.

kiranmv said...

Could you please let me know how to go about downloading and installing the MQseries adapter for biztalk 2006.I m searching for the same and unable to find iit anywhere.

Kent Weare said...

Hi Kiranmv,

The adapter is installed with is part of the base install. Go into BizTalk Admin - Platform Settings - Adapters and see if it is there.

The MQSAgent is an opt-in install. You will find a "Checkbox" in the additional software section of the install. This is where you enable the developer tools, SSO Admin etc. In order for you to actually be able to install this agent, the install application must detect MQ Series installed.