Introduction

One of the most common BizTalk architectures is as follows:

With this set up, BizTalk server is deployed using a high availability configuration that will work for most of cases where the environment is receiving information using, for instance, the WCF http binding adapter. The NLB (hardware or software) is spreading the requests between both BizTalk servers in the group.

For the database layer, most of customers provide high availability setting up an MCS cluster (virtual or physical) and typically they also provide HA for the SQL Server Agent Service (or at least they must) , action that opens an interesting option to solve the most common problem when using the FTP BizTalk receiving adapter

The problem

The FTP protocol does not blocks the file, therefore, having more that one host instance configured to process receive locations, could cause a duplicated message.  For instance, if we have a look at our architecture it can happen that host instance on server 1 will pick up files from the FTP server. Because host instances are fully agnostic of what the other host instances in the group are doing, the one running in server 2 might go also to the FTP server at the same time than Server 1. If the file is bigger enough BizTalk will pick up the same message twice. To avoid this issue we normally have two options:

  • Create an MCS cluster at the BizTalk layer and cluster the receiving FTP host instance (preferred option)
  • Disable all the host instances from starting and enabling it in one server only. With this action, just one host instance will be executing and now BizTalk will not get duplicated messages (not recommended as we are having manual HA for FTP host instances)

The power of scripting and SQL Server jobs together

As Microsoft always recommends clustering the SQL Server Agent you could leverage on SQL Server jobs to execute a PowerShell script that will check BizTalk Services status remotely.

Have a look at the following architecture:

The PowerShell script that will run under the SQL Server Agent and it will ensure that your FTP BizTalk hostinstance is running only in 1 server. If that script runs and finds out that there are more hostinstances running, it will shutdown those processes and will enable the hostinstance only in 1 server.

Script Description

This PowerShell script gives a mechanism to provide High availability for windows services, when there is no cluster set up (or when it cannot be used). 

Prerequisites

The SQL Server account that you use to execute this job must be part of the BizTalk Administrator group because and it needs to have permissions to start and stop services within all of your BizTalk Servers.

Parameters

    ServiceName
    This will be the name of the windows Service that you want to provide HA. Don't forget to add the escape character for the BizTalk Services name, as they have the $ symbol, like in this "BTSSvc`$BizTalkServerApplication".

    ServerList
    This is the place in which you have to provide the Server Names that will be part of the HA configuration.

    ServerStatusList
    This is the Server Status List. By status here we refer to the status of the service in all of the Servers that are part of the $ServerList array. The number of items here should be the same than in the $ServerList array.

    DefaultServer
    Change this parameter if you want a different default server. This will be the position in the $ServerList array (So zero, for the first server). The script will know which server should be used as the Default one in the HA configuration. So it will always try to start the service in this Server First.

    LogFilePath
    Yes! the script is logging information. The Script will be logging all the information to the file specified here.

Example

$ServiceName = "BTSSvc`$BizTalkServerApplication"

$ServerList =@("ServerA","ServerB","ServerC","ServerD")

$ServerStatusList=@(0,0,0,0) #This is the Server Status List. By status here we refer to the status of the service in all of the Servers that are part of the $ServerList array. The number of items here should be the same than in the $ServerList array.

$DefaultServer = 1 #Change this parameter if you want a different default server. This will be the position in the $ServerList array (So zero, for the first server). The script will know which server should be used as the Default one in the HA configuration. So it will always try to start the service in this Server First.

$MoreThanOneServiceActive= 0 #If there are more than one service active, we change this to 1, as the objective of this script is to ensure only one instance of the service is running across all the Servers in $ServerList.

$LogFilePath="C:\Logs\PowerShellLog.log" #the Script will be logging all the information to the file specified here.

Conclusion

After you setup all parameters within the code, you can create now the SQL Server agent job that will call the script.  After changes, your architecture would look something similar to the following diagram:


Download the code

You can download the code from here (MSDN Code Gallery)

See Also

Another important place to find an extensive amount of BizTalk related articles is the TechNet Wiki itself. The best entry point is BizTalk Server Resources on the TechNet Wiki.