Saturday, October 27, 2007

BizTalk Licensing

This is old news, but I still get the raised eyebrow look often enough that I thought it was worth re-iterating.

The introduction of multi-core processors has sent the software industry into a tizzy.   Should vendors license by the CPU core?  Or by the CPU socket?  This is one of those things that seems to confuse people because the ingrained 'per CPU' licensing model that has been around forever.

Motherboards have long supported multiple sockets.  Used to be that one socket == one CPU.  Now, we have multi-core CPU's to contend with when budgeting.  Dual core CPU's are commonplace, with quad core here today, and even more cores per CPU on the horizon.

If I have a single socket mother board, and drop in a dual core CPU, the operating system will see two CPU's, but we are really only using the space and energy, for one.  Typically this == more capacity, or more "bang for your buck".

Some vendors erred on the side of the greedy and chose to license by the core, as this is typically what their application 'see's when its running. 

Microsoft Licenses per Socket

Microsoft has taken the stance that they will license by the socket.  This is a breath of fresh air, considering how we usually watch budgeting dollars waste away because of the stacking cost of client access licenses (CAL's) - of course, everyone has to eat, right?  

As someone who has delivered solutions for enterprise for six years now, its easy to grumble at the cost of software, though I have been on the ISV side and can empathize with the need to get paid.

The Importance of per Socket Licensing

Anyway, why is this important?  Lets say that we have delivered a solution that uses 3 BizTalk servers, running Enterprise Edition, and each server supporting a single dual core CPU.  We pay for 3 BizTalk licenses (1 for each socket), but get the processing power of 6 CPU. 

Then, during testing, we discover that we are too close to capacity for the business today and have yet to account for growth.  We need to take those BizTalk servers from '2 ways' to '4 ways'.   Meaning, 2CPU to 4CPU worth of processing power.  Adding the additional dual core CPU into the existing servers would be the cheap way to go, EXCEPT we now have to pay for 3 additional BizTalk licenses.  Ouch!  No money left in the budget for that. 

With a little luck, it turns out the motherboards will support the newer quad core CPUs.  Talk about serendipity!  We pull the dual core CPU's from the BizTalk servers, and give them to another server application that needs them, and then drop in a single quad core CPU into each server.  Voila!   Processing power has gone from 6 CPU's to 12CPU's (for a nominal hardware cost) and no expensive BizTalk licenses to choke on.  The three servers still each only contain a single socket, quad core CPU, and so require only 3 BizTalk licenses.

Tuesday, October 23, 2007


Have you ever wanted to automate the starting/stopping of performance (PERFMON) logging?  Are you a command line kinda guy/gal?  Then look no further!

Microsoft r Logman.exe (6.0.6000.16386)

  C:\Windows\system32\logman.exe [create|query|start|stop|delete|update|import|export] [options]

  create                        Create a new data collector.
  query                         Query data collector properties. If no name
                                is given all data collectors are listed.
  start                         Start an existing data collector and set the
                                begin time to manual.
  stop                          Stop an existing data collector and set the
                                end time to manual.
  delete                        Delete an existing data collector.
  update                        Update an existing data collector's properties.
  import                        Import a data collector set from an XML file.
  export                        Export a data collector set to an XML file.

  -?                            Displays context sensitive help.
  -s <computer>                 Perform the command on specified remote system.
  -config <value>               Settings file containing command options.
  -ets                          Send commands to Event Trace Sessions
                                directly without saving or scheduling.

I picked up the use of this particular utility during my very first lab engagement with Microsoft.  A team member was using it to automate our test process - one that I've even further refined and automated over the years.  Check out a previous post: Test Process Template.  Ah, the memories...that was SUCH a learning experience!  I highly recommend to anyone.

Anyway, once you've created your perfmon counter log its as simple as:

logman start %logname% [-s %computer%]

For example, I've got a log called 'BizTalk' in our lab environment.  In my start/stop scripts its:

logman start BizTalk

The machine that is recording performance data is also the 'automation' server, so the collection is local.  As one of the NANT tasks during the shutdown of the test process, it issues the stop command:

logman stop BizTalk

SynAttackProtect=0 Solves Connectivity Issues

We had been experiencing on again, off again, connectivity errors in our test lab.  Sometimes, there wasn't even any load placed on the system when the error occurred.  However, the two systems under test that experienced the connectivity issues where BizTalk Server 2006 Enterprise Edition and J.D. Edwards 8.11 with 8.96 tools - I don't remember the exact rev at the moment.

  • Connectivity loss for BizTalk would generally show up as a 'General Network Error' (GNE) in the Windows event log while trying to talk to any of the BizTalk databases: EntSSO, BizTalkMsgBoxDb and BizTalkDtaDb. 
  • Connectivity loss for J.D. Edwards would occur with the message in the log file stating 'Communication Link Error'.  Then there would be a cycle of messages as the application re-establishing a connection to the database.

Of course, the SQL Server did not report any connectivity loss, because we believe the connection was never actually established.

In a complete moment of 'doh!' I remembered the TCP/IP registry key SynAttackProtect.  We applied it to the lab environment and things have seemed to settled down.  However, since I do not have a netmon trace of when the error actually occurred, I couldn't say if the conditions we experienced were indicative of the server refusing connections through a reset, or what.  Anyway, we are getting beyond the realm of my experience and I would need to call in our network team to analyze further.  While I'm not beyond wanting to confirm, schedules may dictate your mileage may vary.  Anyway, our current production BizTalk and Sql tiers deploy with SynAttachProtect=0, so it seemed to be inline with our build server documentation.

The default value of SynAttackProtect under Windows 2003 servers is '1'.  Setting it to '0' disables the protection, something you can probably do if you are isolated from a public network.


Script to Get Running BizTalk Host Instance Name

Code snippet dump!  Our enterprise monitoring software needed to be able to iterate the running instances of BizTalk so that it could sample the appropriate performance counters.  This is the 'alpha' version we are running with.    Because of the way the performance counters are registered on a per instance basis, we needed the 'name' of the host and not necessarily the GUID associated with it.  Since administrators could potentially move host instances from node to node, or create, etc (however unlikely) we wanted something that we wouldn't have to remember to maintain if an administrator changed the location of a  host instance at 3am.

Other proposed options included:

  1. Iterate the BTSNTSvc.exe process and parsing the command-line looking for the host name - this tells us the running instance.
  2. Use the BizTalk WMI model to query for the information we needed - this is fairly rich object model.
  3. Iterate the HKLM\CurrentControlSet\Services registry node, looking for nodes that started with 'BTSNTSvc$' and parsing that value, though this didn't give us whether the host instance was actually running.

The code below expects to execute on the machine its querying for, a requirement of the execution model of our monitoring software.

Code: List Running BizTalk Host Instance Names

Option Explicit
' MSBTS_HostInstance.ServiceState valid values
' More information regarding MSBS_HostInstance can be found on MSDN
'Start pending:2
'Stop pending:3
'Continue pending:5
'Pause pending:6
Sub Main
    dim hosts
    dim host
    dim computerName
    computerName = GetLocalComputerName()
   ' returns a wmi object set of MSBTS_HostInstance objects
    Set hosts = GetRunningBizTalkHosts( computerName )
    for each host in hosts
        WScript.Echo host.HostName
        ' do something for each host
End Sub
Function GetLocalComputerName()
    dim wmi
    dim systemInfo
    dim objItem
    dim propertyName
    dim computerName
    set wmi = GetObject("winmgmts:\\.\root\cimv2")
    Set systemInfo = wmi.ExecQuery("Select * From Win32_ComputerSystem")
    for each propertyName in systemInfo
        computerName = propertyName.Name
        exit for
   GetLocalComputerName = computerName
End Function
Function GetRunningBizTalkHosts(machineName) 
    dim hosts
    Set hosts = GetObject("Winmgmts:!root\MicrosoftBizTalkServer").ExecQuery("SELECT * FROM MSBTS_HostInstance WHERE RunningServer = '" & machineName & "' AND ServiceState = 4")
    Set GetRunningBizTalkHosts = hosts
end function