Here's something I see all too often.
I'm working with a client, whose new system has an unusual design. I ask "Why has it been designed this way?", and the answer's always "Because it's SOA".
Now, building a system around a Service Oriented Architecture brings a lot of benefits. If you do it right, you end up with systems that are re-usable, low-maintenance, and scalable.
However, SOA isn't a silver bullet. When you're designing a system, you have a lot of design decisions to make. If you've settled on an SOA design, then some of those decisions have been made for you (distributed architecture, loosely coupled processes, industry standard protocols). But, there are still some decisions you have to make yourself (orchestration versus choreography, service granularity, façade versus direct access), and these things can have a big impact.
Let's see some examples.
Caching is Good
We were testing a system a client was developing. The system wasn't performing as well as they'd hoped, so we were looking at the calls it made, to identify room for improvement. One of the first things we noticed was that it was calling a service which provides static configuration data, over and over again. Since this was data that didn't change, we asked why they were doing this. "Because SOA's stateless", they said.
Now, to be fair, there's a grain of truth to this. SOA is stateless, but only from the client's point of view. The reason it's stateless is that the client shouldn't know or care how the service is implemented. But for precisely this reason, services can be implemented any way you like, and that includes caching infrequently changed data. That's what the big boys do. According to Facebook, their caching infrastructure means 90% of requests never touch the database, and are served straight from the cache. It's a similar story elsewhere.
We persuaded them to cache this data locally, as well as other design tweaks (like moving some logic from middleware to application servers, to reduce the number of network roundtrips). These changes got the response times down from over 2 minutes to under 10 seconds.
The main learning points here are that caching is good (and doesn't break the ideal of statelessness), and that moving logic around (or equivalently, changing the interface that a system exposes - in an SOA system, this is what ultimately defines what it does) can make a big difference
In another example, we were trying to understand what was causing high CPU usage on a back-end system (this system was the n-th tier in an n-tier architecture). As we drilled down into it, we found that a particular service was being called tens on thousands of times per hour. This was somewhat surprising, as the information this service produced was not relevant to most of the requests we were sending into the web front-end (the 1st tier in the n-tier architecture).
We narrowed down the problem to a search function. The web front-end had a function to search for customers, and it only needed some basic info about each customer (their name, customer number, status and join date). However, it achieved this by calling a general-purpose search service on the middleware server, which was pulling back a complete set of information about every customer - address, payment information, the whole kit and caboodle.
In an ideal world, we would have liked to refactor the interface of the middleware system, to allow more control over searches. However, this was an critical system, that was already in use in production, so it would have been expensive and risky to make any changes. The client were able to make some minor tweaks, but in the end the only sensible option was to buy more powerful hardware.
The lesson here is that even within SOA, you've still got a lot of control over the design of your system. In this case, the middleware wasn't exposing the services that the front-end actually needed. It was offering coarse-grained "find out everything about these customers" services, whereas the front-end system wanted fine-grained "find out these pieces of information about these customers" services.
I feel like I shouldn't have to mention it, but it's something I see surprisingly often. All too often, I see systems that send messages that look like:
It's an understandable design. You've got a legacy system that you want to turn into an SOA system, but no-one's really sure how it works, so you just wrap its data in XML.
The problem is, what you end up with isn't an SOA system. The promise of SOA is that clients shouldn't have to understand how the system works - they just use it. In this case, the client needs to understand the binary blob, so it's not SOA. You get all the complexity of a Service based system, but without any of the benefits.
We've tested systems like this, but it's not easy. The first thing we have to do is write a test harness that understands the binary blob, and that can take weeks. By contrast, if we're testing a system that follows industry standards and best practices, a lot of the test preparation is automatic, so we can be ready to test in a few days.
In general, testable systems are good systems (I'll go into more detail on this in a future post), so this should be a worrying omen for any system designer.
Following an SOA approach means a lot of decisions are made for you, and can lead to high quality systems with a low TCO.
However, even in an SOA world, there are important API design decisions to be made. So choose wisely.