Monitor mixed transports with ServiceControl adapter

Component: ServiceControl Transport Adapter
NuGet ServiceControl.TransportAdapter (1.x)
Target NServiceBus Version: 6.x

This sample shows how to configure ServiceControl to monitor endpoints and retry messages when using mixed transports. The main transport for the solution is MSMQ and this is the transport used by the ServiceControl. Some endpoints, however, use SQL Server transport.

Prerequisistes

  1. Install ServiceControl.
  2. Using ServiceControl Management tool, set up ServiceControl to monitor endpoints using MSMQ transport:
  • Add a new ServiceControl instance:
  • Use default Particular.ServiceControl as the instance name (make sure there is no other instance of SC running with the same name).
If other ServiceControl instances have been running on this machine, it's necessary to specify a non-default port number for API. Adjust ServicePulse settings accordingly to point to this location.
  1. Ensure the ServiceControl process is running before running the sample.
  2. In the local SQL Server Express instance, create database for the shipping endpoint: shipping.
  3. Install ServicePulse
In order to connect to a different SQL Server instance, ensure all database connection strings are updated in the sample.

Running the project

  1. Start the projects: Adapter, Sales and Shipping (right-click on the project, select the Debug > Start new instance option). Make sure adapter starts first because on start-up it creates a queue that is used for heartbeats.
  2. Open ServicePulse (by default it's available at http://localhost:9090/#/dashboard) and select the Endpoints Overview. Samples.ServiceControl.MixedTransportAdapter.Shipping endpoint should be visible in the Active Endpoints tab as it has the Heartbeats plugin installed.
  3. Go to the Sales console and press o to send a message.
  4. Notice the Sales endpoint receives its own message and successfully processed it.
  5. Press f to simulate message processing failure.
  6. Go to the Sales console and also press f to simulate message processing failure.
  7. Press o in both Sales and Shipping to create more messages.
  8. Notice both messages failed processing in their respective endpoints.
  9. Open ServicePulse and select the Failed Messages view.
  10. Notice the existence of one failed message group with two messages. Open the group.
  11. Press the "Retry all" button.
  12. Go to the Shipping console and verify that the message has been successfully processed.
  13. Go to the Sales console and verify that the message has been successfully processed.
  14. Shut down the Shipping endpoint.
  15. Open ServicePulse and notice a red label next to the heart icon. Click on the that icon to open the Endpoints Overview. Notice that Samples.ServiceControl.MixedTransportAdapter.Shipping is now displayed in the Inactive Endpoints tab.

Code walk-through

The following diagram shows the topology of the solution:

Topology diagram

The code base consists of three projects.

Sales

The Sales project contains endpoint that simulates execution of business process by sending a message to itself. It includes message processing failure simulation mode (toggled by pressing f) which can be used to generate failed messages for demonstrating message retry functionality. The Sales endpoint uses the MSMQ transport (same as ServiceControl).

Shipping

The Shipping project also contains endpoint that simulates execution of business process by sending a message to itself. It includes message processing failure simulation mode (toggled by pressing f) which can be used to generate failed messages for demonstrating message retry functionality.

The Shipping endpoint uses the SQL Server transport and requires an adapter in order to communicate with ServiceControl.

The Shipping endpoint has the Heartbeats plugin installed to enable uptime monitoring via ServicePulse.

Adapter

The Adapter project hosts the ServiceControl.TransportAdapter. The adapter has two sides: endpoint-facing and ServiceControl-facing. In this sample the endpoint-facing side uses SQL Server transport and the ServiceControl-facind side uses MSMQ:

var transportAdapterConfig = new TransportAdapterConfig<SqlServerTransport, MsmqTransport>("ServiceControl.SqlServer.Adapter");

The following code configures the adapter to use SQL Server transport when communicating with the business endpoints (Shipping).

transportAdapterConfig.CustomizeEndpointTransport(
    customization: transport =>
    {
        transport.ConnectionString(@"Data Source=.\SQLEXPRESS;Initial Catalog=shipping;Integrated Security=True;Max Pool Size=100;Min Pool Size=10");
        //HACK: SQLServer expects this to be present. Will be solved in SQL 3.1
        transport.GetSettings().Set<EndpointInstances>(new EndpointInstances());
    });

How it works

Heartbeats

The heartbeat messages arrive at the adapter's Particular.ServiceControl queue. They are then moved to Particular.ServiceControl.SQL queue in ServiceControl database. In case of problems (e.g. destination database being down) the forward attempts are repeated configurable number of times after which messages are dropped to prevent the queue from growing indefinitely.

Audits

The audit messages arrive at adapter's audit queue. They are then moved to the audit queue in ServiceControl database and are ingested by ServiceControl.

Retries

If a message fails all recoverability attempts in a business endpoint, it is moved to the error queue located in the adapter database. The adapter enriches the message by adding ServiceControl.RetryTo header pointing to the adapter's input queue in ServiceControl database (ServiceControl.SqlServer.Adapter.Retry). Then the message is moved to the error queue in ServiceControl database and ingested into ServiceControl RavenDB store.

When retrying, ServiceControl looks for ServiceControl.RetryTo header and, if it finds it, it sends the message to the queue from that header instead of the ultimate destination.

The adapter picks up the message and forwards it to the destination using its endpoint-facing transport.

Duplicates

By default NServiceBus transports use the highest supported transaction modes. In case of MSMQ and SQL Server transports this means TransactionScope. Because of that the Adapter requires the Distributed Transaction Coordinator (DTC) service to be configured. In this mode there is no risk of creating duplicate messages when moving messages between the transports. This is especially important for the messages that are selected for retry.

Related Articles


Last modified