February 2010 - Posts
See some update here: http://bloggingabout.net/blogs/gerben/archive/2010/12/20/ibm-websphere-mq-wcf-channels-updated.aspx
Windows Communication Foundation out of the box ships with quite some transport mechanisms. By default it comes with http, tcp, msmq, etc. A channel for the quite widely used IBM WebSphere MQ (WMQ) transport is missing.
To clarify terms up: the WCF thing that really puts the messages on the wire is generally referred to as a channel, transport or transport channel. To able to use that thing in WCF in config you need a binding. A transport combined with a binding is sometimes called an adapter.
Due to history or cross platform support quite some companies are still using WMQ. In the past I've extended WCF with a custom channel for WMQ for a company I worked for and that works fine. Though you actually don't want to build these kinds of things since they're quite complex. Especially if your need robust high volume processing. Luckily enough though both Microsoft and IBM have recently shipped a WCF transport for WMQ. Microsoft ships it with Host Integration Server (HIS) 2009 which is part of BizTalk. HIS is just the shipping vehicle, you don’t need it at runtime. IBM had a transport in alpha for while but it now ships it with WMQ version 7. I evaluated both of these transports and below is my comparison:
|
|
IBM
|
HIS2009
|
|
Fire-and-forget (oneway) client
|
+
|
+
|
|
Fire-and-forget (oneway) service
|
+
|
+
|
|
Request-reply client
|
+
|
-
|
|
Request-reply service
|
+
|
-
|
|
Local transactions
|
+
|
-
|
|
Distributed transactions (DTC)
|
-
|
+
|
|
Client side transactions (DTC)
|
-
|
+
|
|
Backout queue support
|
+
|
-
|
|
Message format
|
-
|
+
|
AppFabric support / IIS Hosting (WAS listener for IIS7) |
-
|
-
|
|
Works with .NET 3.x
|
+
|
+
|
|
Works with .NET 4.0
|
+
|
+
|
|
WMQ6 support
|
-
|
+
|
|
WMQ7 support
|
+
|
+
|
|
Sample code
|
+
|
+
|
|
Documentation
|
+
|
-
|
|
Licensing
|
+
|
-
|
Transaction support
Distributed transaction via DTC only supported in HIS component. Be aware though that you need the WMQ Extended Transactional Client for this, which comes with extra license costs and that HIS2009 doesn’t support backout queues. If the transaction fail it will start to retry indefinitely (poison message) unless you handle this yourself someway.
A local transaction means just that the get from the queue will not be committed in the case of an unhandled exception in the transport channel, WCF runtime or in your own service implementation code. IBM uses a WCF behavior to implement this.
Message format
The IBM channel ties the transport channel to messages with MQHRF2 header, JMS header and puts messages as JMS byte message on the queue. Not a real big surprise since the class name of the channel is "IBM.XMS.WCF.SoapJmsIbmTransportChannel". The IBM channel itself is able to receive messages without all this stuff. But a put on the queue will always be with all this stuff. Disabling via targetClient=1 in the JMS binding is currently not supported.
Sample code / documentation
HIS Channel:
- Samples after installation of “Host Integration Server 2009” or “BizTalk Server 2009 adapters for host systems” available in: \Program Files\Microsoft Host Integration Server 2009\SDK\Samples\MessageIntegration\MQChannel
- Documentation not available is work in progress. Channel is under the cover the same as the BizTalk MQ Series Client adapter, so maybe some documentation from that adapter applies for this one.
IBM.
- After install of WMQ 7 client in: \Program Files\IBM\WebSphere MQ\tools\wcf\samples
Documentation:
http://publib.boulder.ibm.com/infocenter/wmqv7/v7r0/topic/com.ibm.mq.csqzav.doc/un12000_.htm
Licensing
IBM: component is shipped with WMQ client or server version 7.
HIS:
Despite that you only need the assemblies and no BizTalk or HIS to get it working licensing is still via BizTalk. Cheapest way if you're just using the assemblies on a non BizTalk server is to go with the branch edition.
Details at:
http://download.microsoft.com/download/3/9/E/39EB3E63-997C-47CA-9316-AA0B6CD7F9B8/Microsoft%20Host%20Integration%20Server%202009%20FAQ.docx
http://www.microsoft.com/biztalk/en/us/pricing-licensing.aspx
Conclusion
It all looked very nice at first that both Microsoft and IBM are shipping a WCF channel for WMQ. Major disadvantages for me for the Microsoft one are the licensing model and that they don't support request-reply. The IBM channel doesn't have these problems but is missing WMQ 6, distributed transactions and non JMS support for puts on the other side.
Yes I know queues aren't meant for request-reply communication. But there are still quite some old systems around that only are accessible via WMQ, that's why I want request-reply over WMQ.
I know via the TAP that HIS2010 will add some new stuff to the WCF WMQ transport. I’ll update my comparison when HIS2010 is released.
A nice update and overview by Lars: http://startbigthinksmall.wordpress.com/2010/02/17/what-is-left-of-microsoft-oslo-what-now-with-sql-server-modeling-early-2010/
Not a lot happening in this space lately. I only see the team blogging about OData. Still curious where this will go, especially for the M / Grammer part.
Quite some confusion around what AppFabric is lately. Probably due to all the name changes. It breaks down in an on premise and cloud variant:
1. Windows Server AppFabric (on premise)
It's a set of integrated technologies that make it easier to build, scale and manage Web and composite applications that run on IIS. Consists of:
- Distributed Caching (code named "Velocity")
- Service and Workflow Management (code named "Dublin")
2. Windows Azure Platform AppFabric (in the cloud)
Code named .NET Services or BizTalk services longer ago.
It helps to connect apps and services between Windows Azure and on-premises deployments. Consists of:
- AppFabric Access Control
- AppFabric Service Bus
Guess that the confusion comes from that the two variants actually don't have anything in common.
Whooo... it's done! Had these articles in the pipeline for quite a while :-). They come from my years of WCF experience started around 2005 with the CTPs until now.
Hope you find the posts usefull, let me know. Best place is to start is with the introduction post.
In addition to the WCF Best Practices that are already around. WCF Best Practice #6: Know the limits of reliable Messaging with WCF.
WCF has an implementation of WS-ReliableMessaging. Due to its name it’s often thrown in as the solution to all reliability problems. But messages still can get lost with this mechanism if for example the service is shutdown, IIS reset, etc, etc.
Clemens Vasters describes it here. The summary:
"If you need end-to-end durable reliable messaging with full support for transactional I/O you need an infrastructure that's in control of both ends of the communication path and as it happens, such an infrastructure is part of the Windows operating system family. If these are your requirements, your WCF binding of choice is likely the NetMsmqBinding. If you are mostly worried about not losing messages under less-than-optimal networking conditions or require session support – which are the more common use cases – the reliable session support in WCF is the right choice and a great leap forward when compared to the previous Web Services stacks."
Be aware though that MSMQ messages are limited to 4MB in size.
Reliable messaging also isn’t very handy with load balancers:
http://blogs.msdn.com/drnick/archive/2007/07/13/sticky-sessions.aspx
Sticky sessions can be become troublesome in intranet scenarios.
In addition to the WCF Best Practices that are already around. WCF Best Practice #5: One-way is not always really one-way:
Be aware that the client.Close() can block until the service operation is done. Yes you read it right even when oneway closing a client can block until the service side is done. This is happening in quite some cases where bindings are configured to maintain sessions. This happens for example with Message security and or reliable session support.
There is a difference though in this behavior depending on how your contract is composed. This is between contracts with only oneway operations, which I'll call "Oneway contracts" and contracts that do have oneway operations combined with request-reply operations which I'll call "Mixed contracts".
Below is a table for the most common bindings. Check out if Proxy.Close() isn't blocking in the case where you want to do oneway operations:
| Binding |
SecurityMode |
reliableSession |
Close blocks (Mixed) |
Close blocks (Oneway only) |
|
basicHttpBinding (default)
|
None |
- |
No |
No |
| wsHttpBinding |
None |
False |
No |
No |
| wsHttpBinding |
None |
True |
Yes |
No |
|
wsHttpBinding (default)
|
Message |
False |
Yes |
Yes |
| wsHttpBinding |
Message |
True |
Yes |
No |
| netTcpBinding (default) |
Transport |
False |
Yes |
Yes |
| netTcpBinding |
None |
False |
Yes |
Yes |
| netTcpBinding |
None |
True |
Yes |
No |
| netTcpBinding |
Message |
False |
Yes |
Yes |
| netTcpBinding |
Message |
True |
Yes |
No |
Possible solutions if you don`t like the blocking proxy.Close():
- for wsHttpbinding: you could disable use of sessions in service contract via SessionMode.NotAllowed.
- for netTcpbinding: You can't disable sessions since they're used by the tcp transport. You could use streamed transfer mode. Be aware though that this is not working in combination with message security and or reliable sessions. basic, wsHttp or some queuing binding with binary encoding could be an alternative.
Also One-way != asynchronous. Lowy described this one here: http://msdn.microsoft.com/en-us/magazine/cc163537.aspx. The section I’m talking about:
"One-way calls do not equate to asynchronous calls. When one-way calls reach the service, they may not be dispatched all at once and may be queued up on the service side to be dispatched one at a time, all according to the service configured concurrency mode behavior and session mode. How many messages (whether one-way or request-reply) the service is willing to queue up is a product of the configured channel and the reliability mode. If the number of queued messages has exceeded the queue's capacity, then the client will block, even when issuing a one-way call. However, once the call is queued, the client is unblocked and can continue executing while the service processes the operation in the background. This usually gives the appearance of asynchronous calls. All the Windows Communication Foundation bindings support one-way operations."
So be aware of the situations in which a client still can block.
In addition to the WCF Best Practices that are already around. WCF Best Practice #4: know your tools:
Tools from the SDK:
The framework sdk comes with quite some tools that are essential for the WCF developer:
They are listed here: http://msdn.microsoft.com/en-us/library/ms732015.aspx
Svcutil.exe, SvcConfigEditor.exe and SvcTraceViewer.exe will be your new best friends :)
REST starter kit
Toolkit from the WCF Team itself to help with building REST-full services:
http://aspnet.codeplex.com/wikipage?title=WCF%20REST&referringTitle=Home
AppFabric
Hosting part previously code named “Dublin”. When released will help with hosting and tracking and tracing your WCF Services.
Web Services Software Factory (WSSF)
WSSF by Microsoft’s pattern and practices (P&P) team can help with building WCF services. It contains visual designers to build services according to good practices. Check it out at http://servicefactory.codeplex.com
The tool is quite ok but I’m not an enormous fan of it. The designers don’t add a whole lot of abstraction to building WCF Services over code. Plus stuff that comes out from the P&P team is not officially supported. It will work with VS2010 but no guarantees for a longer lifecycle.
David Slot and I wrote an extension a while ago to hook WSSF one up with Enterprise Library: http://entlibextensionswssf.codeplex.com
Enterprise Library (EntLib)
EntLib has some nice integration with WCF for the following blocks:
1. Exception Handling Application Block
ExceptionShieldingBehavior can be specified on a service contract. Calls the Exception Handling Application Block to shield exceptions from the caller
Logging Application Block
2. Logging Application Block
EntLibLoggingProxyTraceListener can be configured to enable the Logging Application Block to process WCF trace events. XmlTraceListener can be used with the block to output events in the format consumable by WCF diagnostics tools.
3. Validation Application Block
ValidationBehavior can be specified on a service contract to enable validation of data contracts
Check out the EntLib documentation for the detailt. WCF info is listed under the documentation of the blocks under the “Key Scenarios” section. For the logging block the info is under the “Developing…” section.
WSCF.Blue
Helps when you want to do contract first development with WCF: http://www.codeplex.com/WSCFblue/
Approach and tool described here:
http://msdn.microsoft.com/en-us/magazine/ee335699.aspx
Additional tools on codeplex
Not familiar with these ones probably worth checking out:
http://wcfloadtest.codeplex.com
http://www.codeplex.com/WCFVisualizer
http://wcfcontrib.codeplex.com/
http://wcfsecurity.codeplex.com/
http://wcfextensions.codeplex.com/
Missing tools
Let me know if I missed some important tools.
In addition to the WCF Best Practices that are already around. WCF Best Practice #3: Contract first:
Not really a best practices but still an important thing to know if you’re new to WCF. WCF isn’t very good at developing contract first. By default you build services CLR based. WCF on runtime creates a WSDL and XSD’s of the CLR based servicecontract and datacontracts.
Important thing to know especially if you come form a world where contract first with XSD’s and WSDL’s is the approach like with BizTalk server.
If you do want to do contract first then check out WSCF.Blue this can help with this in WCF.
http://www.codeplex.com/WSCFblue/
http://msdn.microsoft.com/en-us/magazine/ee335699.aspx
In addition to the WCF Best Practices that are already around. WCF Best Practice #2: Don't forget XmlNamespace settings:
By default WCF puts the “http://tempuri.org/” namespace in your wsdl and contracts. Normally you don’t want this. You can control this from three places:
- In your config file in the services/service/endpoint/bindingNamespace attribute
- In your servicecontract: [ServiceContract(Namespace="http://myuri.net/")]
- In your servicebehavior: [ServiceBehavior(Namespace="http://myuri.net/")]
Update: Ron Jacobs also has a nice step by step article on this one: http://blogs.msdn.com/b/rjacobs/archive/2011/05/12/how-to-eliminate-tempuri-org-from-your-service-wsdl.aspx
In addition to the WCF Best Practices that are already around. WCF Best Practice #1: Don't build a WCF service:
Be sure to know why you’re building a service for something. WCF has impact on development time, deployment, performance, etc. Don’t do it if you can’t articulate clearly why you need your logic as a WCF Service. I’ve seen quite people build services for almost anything while an assembly with a good interface also suited their needs.
About the same thesis is explained in the Microsoft Application Architecture Guide (2nd Edition). Chapter 19: Physical Tiers and Deployment. msdn.microsoft.com/.../ee658120.aspx.
The whole chapter is relevant, but "Recommendations for Locating Components within a Distributed Deployment" summarizes the most.
So reasons when you do choose to build a service could be:
- Security reasons (business Logic in perimeter network)
- Shared business logic (multiple apps or non .NET apps)
- Heavy resource consumption (long-running?)
- Separate maintainable
- Separate scalable
If not applicable: don't build WCF services!
WCF is already around for a while, though best practices aren’t very well known in the developer community. In my search for resources that summarize them best I can recommend the following ones:
- Mehran Nikoo indexed the Microsoft articles that are around.
- Christian Weyer collected a nice selection of tips and tricks from the field.
- Brian Noyes also collected quite some best practices.
My top most useful practices out of these from my experience in the field are:
- Watch out with the using statement with proxies.
- Use WCF tracing and message logging to see what’s going on. Some bad things sometimes don’t come up as an exception, but only as errors or warning in the traces.
- Out of the box WCF is configured pretty conservative for performance, you almost always have to change the default settings.
Although the above resources contain quite some practices, I’m still missing some. I’ll describe these myself in separate posts and these are:
#1 Don't build a WCF service
#2 Don't forget XmlNamespace settings
#3 Contract first
#4 Know your tools
#5 One-way is not always really one-way
#6 Know the limits of reliable messaging with WCF