Actualizado: octubre de 2011
Learn more about RBA Consulting.
Along with a number of bindings for different communications scenarios, the Service Bus also provides two different modes for senders and receivers to connect to one another. The default is relayed mode. In relayed mode, messages are always exchanged through the service relay that is part of the messaging fabric. The following figure illustrates relayed mode.
Relayed mode ensures that senders and receivers can communicate because it only uses the Service Bus. Using the Service Bus avoids problems that might arise if the senders and receivers tried to communicate directly, through incompatible network topologies.
Hybrid mode is possible when the sender's and receiver's network infrastructures are compatible, and they can communicate directly. The following figure illustrates this.
Direct connections do not incur any of the additional latency that may result if messages are relayed through the Service Bus.
In the hybrid connection model, the initial connection between the sender and the receiver is established as a relayed connection through the Service Bus. If a hybrid connection is specified in the configurations of the sender and the receiver, the Service Bus surveys the network topologies of both the sender's and receiver's networks to determine if a direct connection can be established. If it can, the Service Bus automatically switches to a direct connection. The following code is an example of a configuration file of a service that uses hybrid mode.
<system.serviceModel> <bindings> <netTcpRelayBinding> <binding name="myHybridBinding" connectionMode="Hybrid"> <security mode="None" /> </binding> </netTcpRelayBinding> </bindings> ... </system.serviceModel>
The Service Bus can be used in a variety of ways. This section discusses three usage patterns that are well suited to it. They are service remoting, eventing, and tunneling.
Service remoting is useful if you have an existing service that you want to expose outside of a company's firewall. The service remoting pattern allows for 1:1 and N:1 communication scenarios, and requires no changes to the current network topology. The following diagram illustrates how the Service Remoting pattern is implemented with the Service Bus.
Service Remoting does assume that firewall port 80 and/or port 443 are configured to allow inbound traffic. Service remoting supports both simple and complex protocols. You can use HTTP for simple messaging, and you can use TCP for complex, high-performance messaging scenarios. Service remoting also allows for full-duplex communications. Additionally, underlying security constructs, including end-to-end authentication and encryption, guarantee secure communications.
To modify an existing WCF service so that it can use the Service Bus for service remoting requires only minor configuration changes. This change enables the service to authenticate to and connect with the Service Bus. You can effect this change in either the service's configuration file or in code.
Clients that want to use services that are exposed by service remoting should perform these steps:
Use the solution's Atom feed to query the Service Bus registry for a list of endpoints.
Select an endpoint with which to communicate.
Establish a communication channel with the selected endpoint.
Send a message to the endpoint through the Service Bus.
There are many benefits to the service remoting pattern. Some of them are:
Service remoting makes it easy to expose internal functionality.
Service remoting requires no changes to the existing networking infrastructure.
Service remoting requires no large, up-front investments in technologies or hardware.
Service remoting requires only minor configuration changes to existing services.
The service remoting pattern makes it fairly easy to expose services outside of the firewall. However, at some point you may need to send notifications to multiple listeners. For example, you may want to notify vendors that you are accepting bids on a new project. The event pattern, which enables you to notify consumers, is appropriate for these situations. The following figure illustrates the eventing pattern.
For example, to notify vendors that you are accepting bids, a service sends the relevant message to a single endpoint on the Service Bus. The Service Bus then relays this message to the listeners that have registered to receive the message. Note that the listeners are not listening directly to your service; rather they are listening to the Service Bus for the message. The listeners are unaffected if the IP address of the machine where the service resides changes, or if the service is moved to another machine. They listen to the message relay, and not to the actual source of the message.
The eventing pattern has the same benefits as the service remoting pattern, as well as these advantages:
Messaging solutions are scalable from the outset and require no polling.
Clients that occasionally connect can use message buffers for short-lived message storage.
Tunneling is a way for you to interconnect (or "cloud-enable") a service that does not have exposed endpoints. With the tunneling pattern, a listening service or application is placed at either end of a tunnel to listen for low-level protocols, and to forward requests and responses over the Service Bus. The following figure illustrates the tunneling pattern.
This pattern can be implemented to create a high-performance TCP/IP tunnel over HTTP by routing through the Service Bus. One of the benefits of using this approach is that it provides an automatic fallback that tunnels over simple HTTP if the situation requires it.
An example of when to use the tunneling pattern is if you want to expose an application that is not service-oriented, and that does not implement eventing. If this is true, and you must handle NAT and firewall traversal challenges, use the Service Bus to expose the application's protocols, and to negotiate any connectivity issues. Because the Service Bus enables you to mimic connectivity over the protocols your application already uses, you do not have to change, or rewrite, the application to expose it as a service. Examples of such applications include Microsoft SQL Server®, and mail servers. Both of these applications can use tunneling to expose functionality on the cloud from their on-premises locations.
Keep in mind that tunneling is not trivial to implement. Connecting to the Service Bus is the easiest part. There are two other components that you must put into place. The first is the agent. The agent resides on the same computer or network as the application. The agent listens for traffic on a specified port or pipe, and forwards that traffic to and from the Service Bus. The second component is the bridge. The bridge listens for traffic on the Service Bus, and forwards this traffic to and from the local port or pipe. Depending on the type of application for which you create a tunnel, both the agent and the bridge can be quite complicated to implement.
Before you decide to move forward and use the Service Bus in your solutions, there are several considerations to keep in mind. While the Service Bus is capable of dealing with NAT and Dynamic DNS, there are some minimal firewall configurations required for both the senders and the receivers, in order for the Service Bus to work effectively. You will also need to perform some additional steps if you want to host Service Bus-enabled services in Windows Azure. Finally, there are security considerations that you must think about. This section discusses these issues.
The Windows Azure is designed to be network-topology agnostic, and, as a result, places very few requirements on the network. At a minimum, outbound HTTP traffic should be allowed on ports 80 and 443. A better option would also allow outbound traffic on ports 9350 and 9351 to support TCP-based connectivity. Additionally, if there is a proxy server, authentications must be performed against the proxy. Keep in mind that outbound HTTP/TCP connectivity can be limited to well-known port ranges. As a result, even though you open the ports listed above in order to enable connectivity to the Service Bus, you can also ensure that outbound traffic goes to Windows Azure data centers only. The following tables shows the IP address ranges that are associated with each of the Windows Azure data centers at the time of this writing.
As time passes, these IP values may become outdated. For an up-to-date list please refer to http://blogs.msdn.com/b/windowsazureappfabricannounce/archive/2010/01/28/additional-data-centers-for-windows-azure-platform-appfabric.aspx.
Just as you can limit outbound traffic, you should also be mindful of incoming traffic because there is always a potential for attacks. For example, someone with malicious intent could obtain a Service Bus account and attempt to tunnel through a proxy server to your network. To prevent this type of attack, your application should determine where incoming traffic originates, and determine whether or not that source endpoint can be trusted.
The Service Bus can be used for more than exposing on-premises services. You can also expose services that run in Windows Azure. While either a web or worker role can host a service that is on the Service Bus, the common pattern is to use a worker role, and configure the service entirely in code.
The first step is to obtain the credentials that are required to authenticate against the Service Bus. These credentials are generally kept in the worker role's App.config file. The following code is an example of these credentials.
string serviceNamespaceDomain = ConfigurationManager.AppSettings["serviceNamespaceDomain"]; string issuerName = ConfigurationManager.AppSettings["issuerName"]; string issuerSecret = ConfigurationManager.AppSettings["issuerSecret"];
The next step is to create a credential object for the endpoint. The Service Bus will use the credential object for authentication. The following code shows an example of how to do this.
TransportClientEndpointBehavior sharedSecretServiceBusCredential = new TransportClientEndpointBehavior(); sharedSecretServiceBusCredential.CredentialType = TransportClientCredentialType.SharedSecret; sharedSecretServiceBusCredential.Credentials.SharedSecret.IssuerName = issuerName; sharedSecretServiceBusCredential.Credentials.SharedSecret.IssuerSecret = issuerSecret;
Once the credentials for the endpoint are created, create the URI that will expose the service on the Service Bus. The following code shows how to do this.
Uri address = ServiceBusEnvironment.CreateServiceUri("sb", serviceNamespaceDomain, "HelloWorldService");
After you create the Service Bus URI, instantiate a ServiceHost object. The following code shows how to do this.
ServiceHost host = new ServiceHost(typeof(HelloWorldService), address);
The last step is to attach the required Service Bus credentials to the endpoint and open the ServiceHost object. The following code shows how to do this.
foreach (ServiceEndpoint endpoint in host.Description.Endpoints) endpoint.Behaviors.Add(sharedSecretServiceBusCredential); host.Open();
The result is a service that is hosted in Windows Azure and that can use the Service Bus.
There are two points to keep in mind when you use a role and code. First, the worker role (or web role) that hosts the service must run with full trust. An attempt to run the role with partial trust will cause an exception. Second, it is slightly more difficult to configure the service. This is because the Windows Azure SDK is not installed within Azure instances. Consequently, each instance's Machine.config file is missing entries that are associated with Service Bus. There are two ways to work around this. The first is to configure the service entirely in code (as was shown above). The second is to include the appropriate entries from your development machine's Machine.config file in the role's Web.config or App.config file. If you select this approach, add the following content to the role's configuration file.
<system.serviceModel> <extensions> <behaviorExtensions> <add name="connectionStatusBehavior" type="Microsoft.ServiceBus.Confi guration.ConnectionStatusElement, Microsoft.ServiceBus, Version=220.127.116.11, Cult ure=neutral, PublicKeyToken=31bf3856ad364e35"/> <add name="transportClientEndpointBehavior" type="Microsoft.ServiceBu s.Configuration.TransportClientEndpointBehaviorElement, Microsoft.ServiceBus, Version=18.104.22.168, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> <add name="serviceRegistrySettings" type="Microsoft.ServiceBus.Config uration.ServiceRegistrySettingsElement, Microsoft.ServiceBus, Version=22.214.171.124 , Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> </behaviorExtensions> <bindingElementExtensions> <add name="tcpRelayTransport" type="Microsoft.ServiceBus.Configuratio n.TcpRelayTransportElement, Microsoft.ServiceBus, Version=126.96.36.199, Culture=ne utral, PublicKeyToken=31bf3856ad364e35"/> <add name="httpRelayTransport" type="Microsoft.ServiceBus.Configurati on.HttpRelayTransportElement, Microsoft.ServiceBus, Version=188.8.131.52, Culture= neutral, PublicKeyToken=31bf3856ad364e35"/> <add name="httpsRelayTransport" type="Microsoft.ServiceBus.Configurat ion.HttpsRelayTransportElement, Microsoft.ServiceBus, Version=184.108.40.206, Cultur e=neutral, PublicKeyToken=31bf3856ad364e35"/> <add name="onewayRelayTransport" type="Microsoft.ServiceBus.Configura tion.RelayedOnewayTransportElement, Microsoft.ServiceBus, Version=220.127.116.11, Cu lture=neutral, PublicKeyToken=31bf3856ad364e35"/> </bindingElementExtensions> <bindingExtensions> <add name="basicHttpRelayBinding" type="Microsoft.ServiceBus.Configur ation.BasicHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Version=1 .0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> <add name="webHttpRelayBinding" type="Microsoft.ServiceBus.Configurat ion.WebHttpRelayBindingCollectionElement, Microsoft.ServiceBus, Version=1.0.0 .0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> <add name="ws2007HttpRelayBinding" type="Microsoft.ServiceBus.Configu ration.WS2007HttpRelayBindingCollectionElement, Microsoft.ServiceBus, Version =18.104.22.168, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> <add name="netTcpRelayBinding" type="Microsoft.ServiceBus.Configurati on.NetTcpRelayBindingCollectionElement, Microsoft.ServiceBus, Version=22.214.171.124 , Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> <add name="netOnewayRelayBinding" type="Microsoft.ServiceBus.Configur ation.NetOnewayRelayBindingCollectionElement, Microsoft.ServiceBus, Version=1 .0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> <add name="netEventRelayBinding" type="Microsoft.ServiceBus.Configura tion.NetEventRelayBindingCollectionElement, Microsoft.ServiceBus, Version=1.0 .0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/> </bindingExtensions> </extensions> </system.serviceModel>
Any bindings that are not used can be removed from the configuration file as appropriate.
Although security is discussed throughout this article, this section consolidates the points that were made into some best practices for securing communications on the Service Bus. Remember that the SSL channel terminates in the Service Bus. This means that messages that travel within the messaging fabric in the Windows Azure data centers are not encrypted. Under the privacy policies that are associated with the Windows Azure platform, Microsoft does not look at the contents of your messages unless you give them explicit permission to do so, perhaps to troubleshoot a problem. However, security breaches can and do happen. To ensure that other parties cannot view the contents of your messages, you should hide your payloads. Use WS-Security to protect the end-to-end path, and ensure that you own all the keys that protect the payloads. If you implement these two additional practices, you will ensure end-to-end protection of your Service Bus messages.
Windows Azure Service Bus has a number of capabilities that help enterprises overcome challenges related to connecting on-premises services to the cloud, or exposing them to business partners. The naming system, service registry and messaging fabric of the Service Bus can overcome the challenges that NAT, Dynamic DNS and multiple firewalls present. With the Service Bus, you can connect endpoints that reside on different networks, without making changes to the network infrastructures. The Service Bus also has the intelligence to enable direct connections between endpoints whenever it is possible, in order to decrease latency and increase performance. The Service Bus also offers end-to-end security. From a development perspective, the Service Bus is an attractive option for two reasons. First and foremost, existing services require only minor modifications to use the Service Bus. In many cases, you only need to update a configuration file. The second reason is that the Service Bus provides a familiar programming model based on WCF.