One of the most oft heard critiques against SOA is that the overhead of SOAP/XML formats make it intrinsically low performing. Yes, we all know that standards are often the result of consensus and aren’t always optimized, but SOA’s flexibility is needed to avoid recreating the monolithic “all-is done-here” view of the older development culture. There is no doubt that SOA architectures can be affected by message transmission delays due to larger message sizes resulting from standardization and overheads associated with modular designs.
So, how to solve this conundrum?
A common mistake is designing with the idea of avoiding these performance problems “from the start”. The outcome? Designs that are too monolithic, and that introduce inflexible interfaces with tightly coupled inter-process calls “in the interest of performance”. Talk about throwing out the baby with the bathwater! A better approach is to design for flexibility, as the SOA gods intended, but to introduce the safety valve of caching throughout the system. Caching is the technique used to preserve recently used information as close as possible to the user so that it can be accessed more rapidly by a subsequent caller. Think of caching as a series of release valves needed to ensure the flow of services occurs as pressure-free as possible from beginning to end.
The idea is to design a system that allows as many caching points as possible. This does not mean you will actually utilize all the caching points. Ironically, there is a performance penalty to caching and you should therefore make certain to follow these tenets when it comes to its use:
·Ensure that the caching logic operates asynchronously from the main execution path in order to avoid performance penalties due to the management of the cache.
·Ensure you use the appropriate caching strategy. There are several different strategies that apply to specific data dynamics. Should you clear the cache based on least-used, oldest, or most recently added criteria? Will you implement automatic caching space recollection techniques (i.e. have a daemon periodically releasing cached elements in the background) or will you do so only when certain thresholds are crossed?
·The rules for caching should be flexible and controllable from a centralized management console. It is imperative to always have real-time visibility of the various cache dynamics and to be able to react appropriately to correct any anomalies. Use the recommended cache flag field in the message headers to give you more controlled granularity of these dynamics.
·Allow pre-loading of caching, or sufficient cache warm-up, prior to opening the applications to the full force of requests.
·Always remember that blindly caching items is not a magic bullet. The success of caching depends significantly on the items you cache. If the items change very frequently, you will have to update the cache frequently as well and this overhead could upset any caching advantages..
Even though there are vendor products that provide single-image views of distributed systems caching, I recommend using them only for well-defined server clusters and not broadly for the entire system. You will be better off designing custom-made caching strategies for each particular service call and data element in your solution. There are several caching expiration strategies, such as time-based expiration, size-based expiration (expiring the oldest x% of cache entries when a certain cache threshold is reached), and change-triggered cache updates using a publish/subscribe mode.
Selecting the right expiration and refresh strategy is essential in ensuring the freshness of your data, high hit cache ratios (low cache ratios can make overall system performance suffer because of the overhead incurred in searching for a non-existing item in the cache), and avoidance of performance penalties due to cache management. Also, if you can preserve the cache in a non-volatile medium in order to permit rapid cache restore during a system start-up, then do so.
Clearly, choosing what data to cache is essential. Data that changes rapidly or whose precision is critical should not be cached (e.g. available product inventory should only be cached if the amount of product in the inventory is larger than the amount of the largest possible order). You’ll need to assess how fresh data must be, for any situation. The optimum strategy must be determined carefully via trial-and-error. You can also apply analytical methods such as simulation (see later) to better estimate the impact of any potential change to either the characteristics of the data being cached, or the preferred caching approach.
Finally, I can’t emphasize enough the need for accurate caching monitoring via use of real-time dashboards. These dashboards are a core component of the infrastructure needed to properly manage a complex SOA system. More on Managing SOA next.
Do you want to watch TV? Grab the remote control and press the ON button. To mute the sound, press Mute. Simple. The service interfaces represent a binding contract between the service provider and the client. Ideally, the contract will be as generic as possible so that it can be flexible and you won’t need to change it for trivial reasons. On the other hand, you have to ensure the interface is complete and sufficiently specific to ensure there are no ambiguities during the request and the response.
The contract should not assume any explicit knowledge between the client and the service provider. In other words, the more abstracted and decoupled the interfaces are between the client and the server, the better. Imagine if every time you drove to a fast-food window you were expected to order the meal differently depending on who was taking the order.
Web services have gained quick acceptance because they rely on high level interfaces like XML. SOAP (Service Oriented Architecture Protocol) improves the situation even more by enforcing an interface view based upon WSDL (Web Services Description Language) as opposed to a view based upon data structures. Other approaches such as REST (Representational State Transfer) utilize the Web stack to provide suitable abstracted interfaces. However, regardless of the specific interface semantics, the point remains: a good interface should completely decouple the HOW a service provider works from the WHAT the service is offering. In the end, the client of the service doesn’t care whether the TV channel is changed via electronic circuitry or via a little gnome living inside the television (an uncomfortable situation for gnomes these days thanks to the advent of flat screens!).
But returning to our restaurant metaphor. . . You have probably been in one of those fast-food places where you can enter your order via a touch-screen. The result is that instead of having an $8/hour employee take your order, you have an $8/hour employer behind the Kiosk guiding you on how to input the order, and probably making you feel like an ignoramus. Unlike ordering your meal from a human being, using a touch-screen exposes some of the intrinsic processes used by the restaurant, and forces you to follow a specific, usually awkward flow, while ordering. This is one of the reasons touch-screens to order meals have failed to really take hold and, analogously, it’s a reason that an older “SOA Protocol” like CORBA (Common Object Request Broker Architecture) failed to catch-on as well. As with the touch-screen example, CORBA forced the client to match the server interface in a way that was not sufficiently transparent. Similarly, we cannot rightly consider remote object invocation protocols such as RMI (Remote Method Invocation) or the analogous RPC/XML (Remote Procedure Call with XML) to provide true SOA interfaces. These protocols force the client to make assumptions about the object methods and data types, while failing to properly hide the implementation of the service such as the way the called “service” represented by the object is constructed or initiated, and the way various data types are handled.
The difference between a service and a function is subtle, but the way to disambiguate it is clear: If the “function” being called is potentially required to be placed in a separate environment or can be provided by a separate vendor, then it should be defined as a service. Yes, RMI/Java APIs are okay for “local services”, but beware of this terminology. If you recall the transparency credo, you know that talking about “local” services is a mistake. If you intend to create a true service, then I suggest you expose it properly from its inception. As such, it should always be exposed as a decoupled service with a truly abstracted and portable interface.
Remote Object Invocation and other function-level interfaces fail to meet the implementation transparency credo required by SOA, making the resulting “service-less” SOA system as pointless as decaffeinated coffee or alcohol-free beer.
While some might argue the “merits” in using RMI or RMI-like protocols to improve SOA performance, this performance improvement, if any, comes at the cost of flexibility. Why? The moment you have to grow the system and try to convert the “local” service into a real service you are bound to face unnecessary decoupling work. This stage of the design process is not where we should be worrying about performance. Creating a function where a service is needed simply to avoid “the overhead” of XML or SOAP is not an appropriate way to design (in any case, said overhead can be minor when using coarse-grained services). Define the services you need first, and then you can focus on streamlining their performance.
Yes, there is a role and a place for RMI and Object Interfaces when you are certain you are creating a function and not a service. Functions are usually fine-grained and can certainly be used for specific intra-system calls to shared common objects. But the bottom-line is this: in case of doubt, use real SOA interfaces.
The beauty of respecting the transparency credo and enforcing the abstraction layer provided by properly laid down service interfaces is that you will then be in a position to leverage the tremendous powers that the underlying service framework provides in rapidly leveraging service ecosystems for the quick delivery of solutions.
This blog covers the practical techniques, trials and tribulations associated with the transformation of IT systems from legacy technologies to systems using SOA and modern open systems. I also include the occasional interlude with rants about technology in general.
About Me
Name: Israel del Rio
Location: Atlanta, GA, United States
Israel has been recognized by Computerworld as one of their Premiere 100 IT honorees. Israel is a business and technology leader who has contributed the technology vision as key strategist and designer behind the enterprise technology roadmaps of large hospitality and travel companies. Israel has also have developed and deployed various mission-critical systems and in the process, he's been instrumental in creating and building effective and skilled development organizations.