Kevin Lam's WebLog

  • Demystifying Direct Bound Ports - Part 6

    Dynamic Direct Bound Port Clarification

    There seems to have been some confusion generated by readers trying to implement dynamic direct bound ports that I wanted to clarify.  A dynamic direct bound port is merely a direct bound port whose address is set at runtime.  It is not a dynamic send port.  Dynamic send ports allow you to determine at runtime which send adapter the message will be routed to which is derived from the prefix of the address of the endpoint you have provided.  If you try to set the address of a dynamic send port using the msgbox: prefix you will get a routing exception (transport cannot be resolved) as msgbox: is not an alias for any send adapter. 

    The ability to modify the address of a direct bound port is only available in BizTalk Server 2006.

     

  • Demystifying Direct Bound Ports - Part 5

    Dynamic Direct Bound Ports

    A dynamic port allows you to set the address of the logical port to a URI so that at runtime the message can be routed to the correct service to handle the request and the service can then send to the indicated endpoint.  In BizTalk Server 2006 the same can be done for direct bound ports. 

    Setting the address of a port is done by assigning a URI to the Microsoft.XLANGs.BaseTypes.Address property of the port:

     

    Port_1(Microsoft.XLANGs.BaseTypes.Address) = “http://contoso.com/myService”;

     

    The general format of a port address is:

    <adapterAlias><endpointAddress>

     

    A port address is made up of the adapter alias that ultimately maps to a transport, and the actual endpoint as is meaningful to the adapter.  So an adapter alias of HTTP:// will have a URL and a FILE:// will have a URN or a reference to a local file on disk.

    This of course begs the question of, “what does a direct bound port URI look like?” 

    Direct bound port address’ have the following format:

     

    msgbox:<PartnerService>#DirectPortFlavor#<port-type>

     

    So for a direct bound port the transport, what would typically be the adapter alias, is the literal msgbox:. The rest is the endpoint address which, for direct bound ports, is a partner service and a port. The #DirectPortFlavor# indicates how the partner service will be interpreted.  Let’s look at the address of each flavor of a direct bound port.

    Message Box Direct Bound Port Address

    There is no address for a message box direct bound port as it doesn’t make sense since it is a pure publish or subscribe into the message bus (i.e. message box).

    Partner Direct Bound Port Address

    A partner direct bound port has the following format:

    msgbox:<orchestration>#DirectPort#<port-type>

     

    In this case the partner service is the orchestration the port is bound to.  The <orchestration> part is the strong name of the orchestration and has the format:

    namespace.orchestrationTypeName, assemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9876543210abcdef

    and <port-type> is the strong name of the port type and has the format:

    namespace.portType, assemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9876543210abcdef.

     

    The direct port flavor is the literal #DirectPort# and indicates that the partner service is an orchestration.

     

    Here’s an example of what an address would look like:

    msgbox:MyTests.TestOrchestration, MyTests.dll, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9876543210abcdef#DirectPort#MyTests.SomeDirectBoundPortType, MyTests.dll, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9876543210abcdef

     

    Self-Correlating Direct Bound Port Address

    A self-correlating direct bound port has the following format:

    msgbox:<portServiceId>#selfCorrelated#<port-type>

     

    In this case the partner service is the <portServiceId> which is the unique identifier, GUID, given to the port when the orchestration was instantiated and <port-type> is again the strong name of the port-type for this port and has the format:

     

    namespace.portType, assemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9876543210abcdef.

     

    The direct port flavor is the literal #selfCorrelated# and indicates that the partner service is a service instance identifier.

     

    Here’s an example of what an address would look like:

    msgbox:aabbccdd-0011223344-eeff-5566778899aa #selfCorrelated#MyTests.SomeSelfCorrelatingPortType, MyTests.dll, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9876543210abcdef

     

    Scenario for using a self-correlated dynamic direct bound port

    When doing asynchronous inter-orchestration communication, the typical way of correlating a message to a particular instance of an orchestration is by creating a correlation-set, initializing it with particular property values received or sent in a message, then following that correlation-set on a receive shape.  This can make your orchestration more complex if the values of the properties that you need to correlate on are not in the message when it is originally received forcing you to construct a new message with the correlation properties properly set and sending that message somewhere (it has to be sent to be able to initialize the correlation-set but the destination can be some null orchestration (i.e. an orchestration with just a receive shape)[1]).  Another pattern for inter-orchestration communication correlation is when you have a send and receive on separate one-way ports in a loop and you are using the send port to initialize the correlation set and the receive port to follow.  In this case you must unwind the loop (the first send must be outside of the loop) because you cannot initialize a correlation-set inside of a loop (a correlation-set can only be initialized once) thus making your orchestration even more complex[2].  To get around this extra correlation complexity you can use a self-correlating port that under the covers will manage the responsibility of correlating a message back to the current instance of the orchestration.

    In the past the only way we would be able to use a self-correlated direct bound port was by passing the port as a parameter to a ‘started’ orchestration so that it can asynchronously send a message back to the instance of the orchestration that started it. 

    Today in an expression shape you can save the port address of the self-correlated direct bound port in a message,

     

    Msg1.ReturnAddress = SendPort1(Microsoft.XLANGs.BaseTypes.Address);

     

     send it to a partner orchestration and when the partner needs to communicate back to the instance of the orchestration that sent the original request it can set the address of a direct bound port to the port address that was saved in the message. 

     

    ResponsePort1(Microsoft.XLANGs.BaseTypes.Address) = Msg1.ReturnAddress;

     

    This really simplifies the design of the orchestration that is expecting asynchronous responses from its partner orchestrations.

    When you create the send side port it doesn’t matter what type of direct bound port you create as you will be overriding its address.  I would recommend keeping each side as consistent direct bound flavors to make it easier to review the design.

     

    Now that I have lifted the covers of how the dynamic direct bound ports work you can imagine many different scenarios and design patterns.  A few examples include, versioning, dynamic orchestration calling, and, of course, simplified correlation.

     



    [1] When using this pattern of communication be careful as there can be a race condition where a message could be sent to the orchestration before the correlation initialization message is sent.  To avoid this ensure that messages that will follow this correlation are not sent until the correlation set is initialized.

    [2] Another work around is to declare the correlation set within a scope within the loop so that on each iteration of the loop the correlation set falls out of scope and gets re-instantiated and then properly re-initialized.  This may not be a suitable option as there could already be transactional scopes within the loop and adding another transactional scope may cause extra persistence overhead.

  • Demystifying Direct Bound Ports - Part 4

    Self-Correlating Direct Bound Ports

    Self-Correlating direct bound ports are self referential (i.e. the address property includes the service instance identifier of the orchestration) providing the capability of getting messages back to a particular orchestration instance without using a correlation set.

    To configure a self-correlating direct bound port select ‘Self Correlating’ as the ‘Partner Orchestration Port’.

    The way to use it is to create a receive self-correlating direct bound port in orchestration A.  In Orchestration B declare a port as a Send Port Orchestration Parameter of the same port-type as defined in orchestration A.  This declaration will create a logical port on your orchestration designer surface with the direction flipped.  When orchestration B is called with the ‘Start Orchestration’ shape, pass the port as a parameter to orchestration B.  Orchestration B then does whatever business logic it needs to and then can send a message on the port passed in as a parameter.  The message will be sent to the self-correlating port of the instance of orchestration A that originally started orchestration B.

    Although this can be done with a Call Orchestration this would only make sense with a Start Orchestration as it generates an asynchronous instantiation of an orchestration that cannot have out or reference parameters so the self-correlating port can be used as a means of responding back to the orchestration which instantiated it.[1]

    Under the covers what happens is that at run time when orchestration A starts a subscription will be created for each self-correlated direct bound port.  The subscription will look like the following:

    BTS.Operation == Operation_1 And

    BTS.PartnerPort == selfCorrelated And

    BTS.PartnerService == aabbccdd-0011223344-eeff-5566778899aa

    Where Operation_1 is the name of the operation on the port, selfCorrelated is a literal string used as the PartnerPort, and a GUID for the Partner Service that uniquely identifies this port for this instance of the orchestration.

    When orchestration A starts orchestration B the orchestration engine will pass the self-correlated port instance information to orchestration B, along with the other orchestration parameter values.  When orchestration B then sends a message on the self-correlating port that was passed in as a parameter the orchestration engine will set and promote the properties listed above allowing the message to be routed back to the instance of orchestration A that originally instantiated the current instance of orchestration B.

     

    Figure 10 self-correlating port communication

     

    In the next posting I will explain another way of using self-correlating direct bound ports with dynamic direct bound ports.


    [1] Note that you can pass an initialized correlation set as a parameter to a called orchestration and follow the correlation set within the called orchestration.  This means that subscriptions and convoys work across call orchestration boundaries.  This does not work with started orchestrations.

  • Demystifying Direct Bound Ports - Part 3

    Partner Direct Bound Ports

    Partner direct bound ports provide the capability of having inter-orchestration communication via ports. 

    To configure a partner direct bound port you must choose the orchestration and port for the ‘Partner Orchestration Port’ property.  When configuring the two partner ports you must have one side select the orchestration.port it will communicate with and the other side will select its own orchestration.port.  This is a little non-intuitive but will be explained in the sections below.  Also the port types for both ports must be the same, which implies that the message-types must also be the same.  This is one of the places where the Type Modifier property on the port-type matters.  To be able to direct bind to a partner port the port-type type modifier must either be internal for orchestrations within the same assembly or public to allow an orchestration from another assembly to bind to it.  Finally, the polarities of the ports must be opposite.  In other words, if one side is a send port then the other side must be a receive port.

    There are two communication patterns that can be created; forward partner direct binding and inverse partner direct binding.  These two patterns provide explicit inter-orchestration communication.  By explicit I mean that there is an intended recipient orchestration (forward partner direct binding) or an intended sender (inverse partner direct binding).  You can design implicit partner direct binding by having either the receiver be message box direct bound and create a filter that will accept messages from a particular sending orchestration or have the sender be message box direct bound and promote properties that will match a subscription on the receiving orchestration.

    Forward Partner Direct Binding

    This is the typical communication pattern that is used for partner direct binding.  Orchestration A has a partner direct bound send port that will send a message to Orchestration B on its partner direct bound receive port.  To configure this forward partner direct binding you must have orchestrationA.sendPort1, which is of type portType1, select orchestrationB.receivePort1, which is also of type portType1, as its Partner Orchestration Port.  orchestrationB.receivePort1 will select itself, orchestrationB.receivePort1, as its Partner Orchestration Port. 

    Figure 6 Forward Partner Direct Binding Configuration

     

    On the sender’s side what this says is, “I will send messages to orchestrationB.receivePort1” and on the receiver’s side it says, “I will receive any messages sent directly to my receivePort1”. 

    Under the covers when messages are sent out of sendPort1 the orchestration engine will set the following properties:

    BTS.Operation to the operation on the port being used.

    BTS.PartnerPort to the name of the partner direct bound port configured in the Partner Orchestration Port property

    BTS.PartnerService to the strong name of the orchestration referenced in the Partner Orchestration Port property

     

    Note: the strong name of the partner service will usually look something like:

    OrchNamespace.OrchTypeName, AssemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=fedcba9876543210

     

    On the receive side the subscription will be (for brevity I will use the BTS namespace instead of http://schemas.microsoft.com/BizTalk/2003/system-properties as you would see in the actual subscription)

    BTS.Operation == operation1 And

    BTS.PartnerPort == receivePort1 And

    BTS.PartnerService == MyTest.OrchestrationB, MyTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=fedcba9876543210 And

    BTS.MessageType == http://MyNamespace#MyRootNodeTypeName

     

    Something to note here is that there is a strong binding from the sender orchestration to the receiver orchestration.  By strong binding I mean that the sender orchestration is referencing the receiver’s strong name as its partner service.  What this means is that if you want to change the receiver’s side or if you change the version of the receiver’s side you must update the design time configuration of the sender’s port.  But the receiver has no explicit knowledge of the sender so the senders’ orchestrations can be updated without affecting the receiver.

    This type of forward binding allows you to have multiple senders bound to the same recipient. 

     

    Figure 7 N:1 communication

     

    Here orchestrationD would be doing some common asynchronous work needed by many different orchestrations.

    Inverse Partner Direct Binding

    This is not the typical communication pattern that is used for partner direct binding as the direction of binding is inverse of its direction of communication.  Orchestration A has a partner direct bound send port will send a message to Orchestration B on its partner direct bound receive port.  To configure this inverse partner direct binding you must have orchestrationB.receivePort1, which is of type portType1, select orchestrationA.sendPort1, which is also of type portType1, as its Partner Orchestration Port.  orchestrationA.sendPort1 will select itself, orchestrationA.sendPort1, as its Partner Orchestration Port. 

    Figure 8 Inverse Direct Binding Configuration

     

    On the sender’s side what this says is, “I will send a message to anyone who is listening for messages from my send port” and on the receiver’s side it says, “I will receive messages sent from orchestrationA.sendPort1”.

    Under the covers when messages are sent out of sendPort1 the logic for setting properties is still the same as it was for the forward case.  The orchestration engine will still set the following properties:

    BTS.Operation to the operation on the port being used.

    BTS.PartnerPort to the name of the partner direct bound port configured in the Partner Orchestration Port property

    BTS.PartnerService to the strong name of the orchestration referenced in the Partner Orchestration Port property

    On the receive side the subscription will

    BTS.Operation == operation1 And

    BTS.PartnerPort == sendPort1 And

    BTS.PartnerService == MyTest.OrchestrationA, MyTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=fedcba9876543210 And

    BTS.MessageType == http://MyNamespace#MyRootNodeTypeName

     

    In this case the receiver is strongly bound to the sender implying that if you want to change the receiver’s orchestration or update the version then you must update the sender’s port configuration.  The sender has no explicit knowledge of the receiver so the receivers’ orchestrations can be updated without affect the sender.

    This type of inverse binding allows you to have a single sender communicate with multiple receivers.

     

    Figure 9 1:N communication

     

    Inverse direct bound ports allows for a recipient list pattern.  The recipient list is determined by which receive ports are bound to a particular send port and is maintained as part of the orchestration design.  Here either all of the recipient orchestrations can consume any message coming from the send port or they can each have a filter to determine which messages each of the recipients should consume from the sender. 

    One thing to be careful about is that if you are using a two-way port type with inverse partner direct binding then you must setup your filters to ensure that only one of the recipients will consume (i.e. subscription will match) the message.  This is because a solicit-response port is expecting a single response and if multiple recipients get the message, then it will accept the first response and all subsequent responses would be suspended non-resumable.  The engine won’t let that happen and it will instead throw an exception when you try to send the message indicating that there would be multiple recipients for a solicit-response request.

  • Demystifying Direct Bound Ports - Part 2

    Message Box Direct Bound Ports

    Message box direct bound ports, as its name implies, allows you to drop messages directly into the message box without an explicit recipient and it allows you to subscribe to messages, not from any particular sender, which meet certain criteria.  To configure a message box direct bound port set the ‘Partner Orchestration Port’ property to ‘Message Box’.

    Sending a message on a message box direct bound port is equivalent to publishing the message to a message bus, in this case the message box.  For any published message there can be any number of subscribers for that message.  If there are no subscribers interested in the message at the time you publish it a persistence exception is thrown with an inner exception of subscription not found.

    Sometimes when sending a message through a message box direct bound port you may have an implicit recipient in mind and will set properties to particular values that you know a subscriber(s) is looking for and is therefore used as a method for loose-coupling.

    Recipients of the message can be any type of service that can subscribe to messages which include orchestrations and send ports.

    Receiving a message through a message box direct bound port is equivalent to subscribing to a message bus with filter criteria.  For an activating receive shape the subscription will be the message type and the filter and for non-activating receive shapes the subscription will be the message type and the correlation set.

    Every receive shape always includes the message type as part of its subscription. 

    If you don’t add any filter criteria to the activating receive shape connected to a message box direct bound port then the subscription will be:

    http://schemas.microsoft.com/BizTalk/2003/system-properties.MessageType == MyMessageType

    Which can be read as, “Give me every message whose message-type is MyMessageType”.  This is what differentiates a send port subscription from an orchestration subscription.  A send port subscription, if you don’t provide it with a filter, will only handle messages sent directly to it via a bound (specify-now or specify-later) logical orchestration port (i.e. the subscription for a send port includes its send port id as a clause OR’ed with it’s filter).  A message box direct bound receive port that does not have a filter explicitly added will receive every message that matches the message type that the port’s operation is configured for.  [Note: If the message-type is XmlDocument then this is a type-agnostic port.  Type-agnostic ports accept any message type.  To accomplish this the subscription won't include a message-type, implying that it is not filtering based on message-type.  So if there is no filter on the port and the port is type-agnostic then the subscription will be empty and in this case will not match any incoming message as there are no predicates for the routing engine to match against.]

    When using message box direct bound receive ports be careful to make the filter as specific as possible.  I typically caution developers to only use receive message box direct bound ports only when it is absolutely necessary or the benefits (e.g. loose-coupling) out-weigh the risks, as many developers make the mistake of not making their filter distinguishing enough.  The side effect of not having a distinguishing enough filter is that the orchestration can receive messages it didn’t intend to. 

    An example of a mistake that is commonly made is the following; an activating receive shape with a filter using some custom property followed sometime later by a send shape sending the same message to a send port physically bound to an endpoint.  In this case the developer assumes that since the logical send port is bound to a physical send port then only that physical send port will get the message.  This is not the case.  What will happen is that after the first message is published to the message box an infinite number of orchestrations will be activated.  This will happen because the message being sent to the send port endpoint is published to the message box and, because every time a message is sent to the message box all subscriptions are checked for a match, the activation filter of the orchestration will match the message and a new orchestration instance will be started, then recurse to infinity.  If the orchestration is more complex and/or if the receive is using a correlation set as its subscription then the difficulty of trying to debug a similar scenario increases dramatically.

     

    Figure 5 Orchestration that will consume its own messages

     

    In this case the only way to not have the orchestration pick-up the same messages it is sending  (i.e. incorrectly activate a new instance of the same orchestration) is to either construct a new message and change MyProp property to some other value or send a message of a different message-type.

  • Demystifying Direct Bound Ports - Part 1

    Direct Bound Ports

    In BizTalk Server 2004/2006 orchestrations can have direct bound ports. 

    Direct bound ports are logical one-way or two-way ports in your orchestration that are not explicitly bound to physical ports that allow you to have different communication patterns amongst your services.  To create a direct bound port select the binding of the logical port to be direct then choose as the ‘Partner Orchestration Port’ what this port will be bound to.

     

    There are three types of direct bound ports that you can choose as the Partner Orchestration Port; message box, partner, and self-correlating.

     

    Message box direct bound ports allows for publish-subscribe design patterns.  Messages sent on a message box direct bound port are published to the message box without any explicit intent of the message recipients.  Logical receive ports configured as message box direct bound ports get messages directly from the message box whose subscriptions are based only on message type and filter expression (for activating receive shapes) or correlation set (for non-activating receive shapes).

     

    Figure 1 Message Box Direct Bound Ports

     

    Partner direct bound ports provide for inter-orchestration communication.  Messages sent on a direct bound port can be sent to an intended recipient orchestration and messages received on a partner direct bound port can be received from an intended sender orchestration.

     

    Figure 2 Partner Direct Bound Ports

     

    Self-correlating direct bound ports assists you in designing asynchronous inter-orchestration communication.  Messages sent to a self-correlating direct bound port are routed to the instance of the orchestration that created the receiving end of the self-correlated direct bound port.

     

    Figure 3 Self-Correlating Direct Bound Ports

     

    A commonly misunderstood aspect of direct bound ports is its interaction with the message box with some incorrectly thinking that there is direct communication with another instance of an orchestration without traversing the message box.  This is not the case; any message sent through any type of logical port always travels through the message box. 

     

    Figure 4 All logical ports communicate through the message box

     

    Direct bound ports are only logical ports and therefore only a design time configuration feature.  An administrator cannot bind a direct bound port to a physical port nor change the partner it is currently configured for.

    To see each of these different types of ports in action and in context you can look at the Business Process Management (BPM) scenario that ships as part of the SDK in BizTalk Server 2006.

    I will have a separate posting and go into more detail on each type of direct bound port.


  • Get Connected to Free Product Support and Tremendous Online Collaboration

    Have you ever wanted to speak to Microsoft developers of a specific feature of BizTalk Server? I am sure your answer was “Yes let me at them”, so the Business Process Integration Division is extending an invitation to all customers to join our key feature developers, program managers, and testers in the following newsgroups: 

    • microsoft.public.biztalk.accelerator.forsuppliers
    • microsoft.public.biztalk.newuser
    • microsoft.public.biztalk.accelerator.rosettanet
    • microsoft.public.biztalk.admin
    • microsoft.public.biztalk.appintegration
    • microsoft.public.biztalk.framework
    • microsoft.public.biztalk.general
    • microsoft.public.biztalk.library
    • microsoft.public.biztalk.nonxml
    • microsoft.public.biztalk.orchestration
    • microsoft.public.biztalk.sdk
    • microsoft.public.biztalk.server
    • microsoft.public.biztalk.setup
    • microsoft.public.biztalk.tools
    • microsoft.public.biztalk.xlangs
    • microsoft.public.biztalk.xsharp

    We’ve been working very hard over the past year to connect with folks just like you and want to include you in our community of Most Valuable Professionals (MVP), developers, information technology professionals, chief information officers, chief executive officers, or any other role within large, medium, and small companies that hang out in our online newsgroup communities. We want to have you join in this vibrant online community to ask those questions you always wanted to ask but did not know where to go. Well, now you know where to go, we want you to come on in and join us! 

    If you are new to BizTalk Server, try out the NewUser newsgroup, Microsoft.public.biztalk.newuser.  

    We’re offering two levels of interaction with Microsoft Corporation employees as follows: 

    1. Managed Newsgroup Support
    2. Unmanaged Newsgroup Support

    Managed Newsgroup Support

    MSDN managed newsgroups are available in English to MSDN Universal, Enterprise, Professional and Operating Systems subscribers to receive free technical support on select Microsoft technologies as well as to share ideas with other subscribers. MSDN managed newsgroups provide:

    • Unlimited on-line technical support - keep your PSS incidents
    • A commitment to respond to your post within two business days
    • Over 200 newsgroups to choose from
    • Spam protection for your e-mail address when posting items

    Go to the following URL to sign up: http://msdn.microsoft.com/newsgroups/managed .  These newsgroups are monitored by Microsoft support engineers and product group team member as described above.

    Unmanaged Newsgroup Support

    MSDN unmanaged newsgroups are available to all individuals.

    Go to the following URL to participate: http://msdn.microsoft.com/newsgroups. These newsgroups are monitored by Microsoft product group members, other customers like you, most valuable professionals, and various other individuals.

    Questions, suggestions, and direct feedback can be sent to me. 

    James Fort

    BPI Community Lead

    mailto:jfort@microsoft.com

  • Low-latency scenarios that use two-way (solicit-response) HTTP send ports.

    HttpOutCompleteSize

    This setting controls the size of the batch of messages that is returned from the HTTP send adapter.  The default value for this is 5.  If the buffer is not full and there are outstanding responses then the adapter will wait for 1 second until it commits the batch.  For low-latency scenarios this should be set to 1 which will allow the adapter to send response messages immediately to the message box for processing.  This will have the greatest effect during times of low-throughput activity with varied response times from backend systems.

    Actually this setting controls the number of messages being returned to BizTalk (EPM) from the HTTP adapter regardless of whether the port is one-way or two-way.  A message that is returned in the batch includes a request to DeleteMessage, MoveToNextTransport, MoveToSuspendedQ, and, most interestingly, SubmitResponseMessage.  Although this setting will improve response times in low-latency scenarios it does increase the amount of chattiness between the adapter and the message box.

    It is the send side equivalent to the HttpBatchSize on an HTTP receive adapter.  In low-latency scenarios this is typically set to 1 to ensure that the messages are getting processed as quickly as they are received.

    To set this value you need to add HttpOutCompleteSize as a DWORD value to the registry under:

    HKLM\SYSTEM\CurrentControlSet\Services\BTSSvc{guid}\

    where GUID is the ID of the host for HTTP send handler.

     

    This information is specific to BizTalk Server 2004 and there is no guarantee that this setting will behave the same way in the next release of BizTalk Server.

     

    Disclaimer: This is an undocumented setting and was not formally tested since it was not considered to be publicly available.  You must do your own testing to ensure that the behavior and performance of your system are as expected.

     

  • An orchestration pattern that can hog the master message box CPU

    Overview

    We had a customer scenario such that when a complex business process was executed at the rate of 1 request per second the CPU utilization of the SQL Server hosting the master message box quickly grew up to 100% sustained.  Having the master message box’s CPU utilization so high is not desirable as it can:

    • cause SQL connection timeouts, which has the side affect of restarting BizTalk host instances
    • SQL jobs fail, which has the side affect of aged data not getting cleaned out of the database
    • Performance impact, as it will take longer to submit messages into the message box, since the master message box is responsible for subscription matching

    Background

    In this scenario, there were two SQL Servers allocated for BizTalk; one held only the master message box with publication turned off and the other had all of the other BizTalk databases including a secondary message box.  Both SQL Server machines had 8 hyper-threaded 3.0 GHz processors and 8GB of RAM. 

     

    The orchestrations consisted of about 4 orchestrations chained via messaging including about 2 called orchestrations.

     

    In this scenario a new business process is created per order and there can only be one business process running at any one time for a particular {customer, order} pair.  Each order can have updates which can interrupt the currently running business process handling that request.  An interruption can only happen at certain points in the business process (i.e. business process atomicity).  So if an update has come in and a business process is currently handling a request, then the update will be queued up to a point in the business process where it can check to see if this current business process instance should terminate and then allow the update to start a new business process. 

     

    To accomplish this in orchestration we used correlations.  At certain points in the orchestrations there would be a Listen shape with a Delay of 0 on one branch and a Receive following a correlation on the other branch.  So when the orchestration gets to this point in the orchestration, if there is no update then the business process continues until it needs to check again at the next interrupt point.

     

    In the design of the orchestration there are several .NET remoting calls made.  If the remoting call fails then an exception orchestration is “Called”.  Since there are several remoting calls, then there are several of these exception orchestrations called throughout the main orchestration.  The exception orchestration includes logic such that it can post a request to an operator to determine whether or not to terminate the instance or to try again.  Since there is a blocking call waiting for user input, there can be a significant window of time where the orchestration instance is running.  In the meantime an update message could come, which would invalidate this original request.  To accomplish this interruption in the exception handling orchestration, the correlation set was passed in as a parameter to the called orchestration so that it can either wait (listen) for the response from the operator or an update message that interrupts the currently running instance.

    BizTalk Behavior

    The master message box is responsible for doing subscription matching.  If publication is turned off on the master message box, then it will only do subscription matching and the other message boxes will handle message publication and storage.  The master message box can only be scaled up but not out.  So eventually it can become the limiting factor in how far the message boxes can be scaled. 

     

    The orchestration engine creates the necessary subscriptions when the orchestration is instantiated.  One set of subscriptions it will create include the ones for followed correlations.  The orchestration engine will find all of the points where the correlation is followed and create subscriptions for them.  If a correlation set is passed to a called orchestration then the engine crawls the called orchestration to create those subscriptions as well.  A called orchestration is essentially in-lined code which means that the called orchestration will look like it is part of the orchestration that calls it.

     

    A subscription, in this case, will consist of a message type, an orchestration instance, a port operation, and the properties used in the correlation set.  So the subscriptions for the called orchestrations will actually have the name of the caller orchestration as its orchestration instance name.

     

    By default, when you create a port in the orchestration designer the first operation under the port is defaulted to Operation_1.  Unless a developer has an explicit purpose for changing this (for example, if he is exposing an orchestration as a web service this operation will become part of the method name) the developer will typically leave it with the default name.

     

    Since the same called exception orchestration is called many times within the main orchestration with the same correlation set with the same port operation name, then identical subscriptions will be created in the master message box.  As a general rule of thumb, the master message box can get overwhelmed when trying to match a message to a subscription with more than 20 identical subscriptions (I won’t go into the complexities of what happens when a number of subscriptions are matched for a particular message). 

    So in this case each request is putting a lot of strain on the master message box trying to match the request to a particular subscriber since the message would match the subscription for activating receive as well as all of the receives that are in each call to the exception orchestration.  In this case, messages which are destined for the receive points in the exception orchestration are not common, but they are still referenced since the subscriptions are all the same.  To alleviate the strain put on the matching processing we changed the names of the port operations to be unique.  Since the orchestration engine uses the port operation name as the distinguishing property for a subscription, the subscription for the activating receive is now unique and the master message box doesn’t have to waste CPU cycle trying to figure which of the other subscriptions it needs to match against.

     

    In the above described scenario, after making this change, the CPU utilization dropped from 100% to about 20%.

     

    Recommendations

    Change the operation type name to something unique.  Even if the design doesn’t have a called orchestration with a correlation set passed to it, it is a best practice to change these names in case in the future these orchestrations get repurposed.  Also it allows you to more easily find the subscription for a particular operation port in the orchestration.

     

    Lee  talks about this scenario in his blog with some more technical detail under his post on  Is there a pub/sub system underneath BizTalk?

  • Welcome to my blog

    I suppose I should give a little background on myself before I start blogging to give my posts some context.  Before Microsoft I was designing and developing parts of foreign exchange transaction systems for Reuters.  I started at Microsoft about 7 years ago as a software design engineer on Windows working on the index server.  I spent much of my time porting the code to 64-bit.  As the year 2000 approached Microsoft was pushing harder into the Enterprise market with the 2000 series of products (Windows, SQL, BizTalk, Host Integration Server, and Commerce Server) on the horizon.  I was fortunate enough to get a position as an Enterprise Solutions Architect working closely with customers designing systems built on pre-released bits of Microsoft platforms and applications helping make them successful on Microsoft products and getting feedback of our findings back into the product teams.  I have been able to work closely with financial, telecommunication, retail and many other types of companies architecting solutions to work with our latest applications.  

    Now I am part of the Business Process and Integration division still working closely with customers on design wins and architectures but now mostly with projects using BizTalk Server 2004.  While working in this position I have been able to experience both sides of our products; getting the customers’ perspectives and understanding the product group’s inner workings.  

    In this blog I am planning on sharing some of these experiences and findings.  We sometimes discover that users don't understand parts of the system, or didn't know that they had to architect their system in a particular way (for example, many users don't realize that the master secret server must be clustered for a high availability build out).  I will use this blog to share some of that information as well.

     

    There are some folks from the BizTalk team who are already blogging:

    Scott Woodgate

    Kevin Smith

    Lee (the dude) Graber (BizTalk Core Engine)
    Eldar Musayev

    They already have some excellent posts and I would recommend looking at them as well.

     

    Enjoy,

    Kevin


© 2009 Microsoft Corporation. All rights reserved. Terms of Use  |  Trademarks  |  Privacy Statement
Microsoft
Page view tracker