This post will, hopefully, give you a high level overview of what the NServiceBus gateway is, where to use it and perhaps more importantly where to not use it.
The main purpose of the gateway is to allow you to do the same durable fire and forget messaging that NServiceBus has got you used to across physically separated sites, by sites i mean locations where you run IT infrastructure and not web sites. The gateway only comes into play where you can't use the regular queued transports for communication i.e. when setting up a VPN-connection is not an option. The reason for not using a VPN is usually security concerns, bandwidth limitation, latency problems, high availability constraints etc.
When to not use the Gateway
The gateway should not be used when the reason for running separated sites is disaster recovery. Under those circumstances all your sites are exact replicas and is not logically different from each other. In this scenario you're much better off using what ever support your infrastructure has to keep your sites in sync. Examples here are are SAN snapshots, SQL server log shipping, RavenDB replication etc.
So if your sites aren't logically different then choose another technique to keep your sites in sync.
Ok, but what do you mean by logically different?
When I talk about logically different I mean sites that serve a different business purpose, ie differs in behavior from other sites. Imagine a chain of retail stores where you would have a headquarter that is keeping the prices for the different goods you're selling. Those prices need to be available to all your stores in a highly available manner. Not being able to do business if the link to the HQ is down is bad for sales , trust me!
If we look at this scenario from a logical view we see that all the communication goes on withing the same business service (BS), pricing in this case. In terms of behavior the different physical sites are having different logical behavior. This is a sure sign that the gateway might come in handy. Lets dig a bit deeper and look at that actual responsibilities of each site.
- Headquarter - Maintains the prices and pushes any price change out to the different stores on a daily basis
- Store - Stores the prices locally for read only purposes
Prices are usually set for a least a day at a time so it's good enough for the HQ to push them to the sites once per day, lets model this as a DailyPriceUpdates message containing the list of price updates for the coming business day. Given this design we only need to get one message across to each site per day which lowers the requirement for the infrastructure used. Internally in HQ other business services may need more frequent updates so we model this with another logically different message, PriceUpdatedForProduct that will allow us to use the pub/sub pattern while communicating with other BS. The gateway doesn't support pub/sub, more on that later, but this isn't a problem since request/response is perfectly fine within a BS and remember those sites are physically different but the communication is done within the same logical BS. So when you use the gateway the guideline is to model the messages going across sites explicitly. If we extend the sample to include a sales service responsible for reporting the sales statistics so that the pricing service can set appropriate prices we end up with the folowing picture: (from NServiceBus.com)
As you can see the prices gets pushed daily to the stores and sales reports are pushed daily to the HQ. Any pub/sub needed goes on within the same physical site and this is the reason that the NServiceBus gateway doesn't support pub/sub across sites since it shouldn't be needed in a well designed system. Going across sites usually means radically different transport characteristics like latency, bandwidth, reliability and explicit messages for the gateway communication is helping to make it more obvious for developers that they are about to make cross site calls. This is where Remote Procedure Call (RPC) starts to really break down. RPC completely hides the fact that you're now going out of your data center and will meet all the fallacies of distributed computing head on.
Using the gateway
The gateway in NServiceBus 3.0 is included in the core assembly and that means that every endpoint is capable to running a gateway. The gateway can easily be turned on by calling Configure.Gateway(). To send messages we've added a new method the IBus interface called SendToSites
As you can see this allows you to pass in a list of sites to where you want to send your messages. Each site can be configured to use a different transport mechanism. Currently the supported channels are http/https but you could easily extend the gateway with your own implementation.
On the receiving side there will be another gateway listening on the input channel and forward the incoming message to the target endpoint. The image below shows the physical parts involved
As you can see there is a gateway running inside of each host process. The gateway gets its input from a regular MSMQ queue and forwards the message over the desired channel, HTTP in this case, to the receiving gateway. The receiving side deduplicates the message and forwards it to the main input queue of its local endpoint.
I'm going into the nitty gritty details of the gateway in a follow up post but in short the gateway has the following features:
- Automatic retries
- Deduplication of messages
- Transport level encryption with SSL
- Support for data bus properties with large payloads
- Can listen on multiple channels of different types
- Included in every endpoint
- Easily extensible with other channels
Hopefully this post gave you a better insight into where the gateway can help you out and where other tools are more appropriate.
Key thing to take away
- Only use the gateway for logically significant sites
- Use explicit messages for your cross site communication
- The gateway doesn't support pub/sub
- Automatic deduplication and retries comes out of the box