In my last post, I talked about how I keep my approach to application performance simple – I use my one semester’s worth of microeconomics knowledge to continuously evaluate the supply and demand sides of my application architecture. What can go wrong, right? 🙂
One of the points we’ll explore further in this post is that supply shouldn’t be viewed simply as a measure of hardware capacity. Better to view supply as that which is demanded (see what I did there…?). In a complex environment, supply can be measured as the number of connections, available SOA services, process space, and hardware. Here’s a good visualization of what I’m talking about:
This application (i.e., website) makes demands on two services. One service is a webserver powered by Apache. The other is an application front-end powered by Tomcat. Each service has its own job to do. In turn, the application components make their demands on each subsequent asset in the chain, all the way down to the network infrastructure.
So instead of thinking of supply simply as available cycles and memory, I think of supply as what’s demanded at each layer. I then reefine supply requirements based on these demands.
In the example below you see a list of the web requests requested by a browser, along with the response time of each request. Viewing this from an inventory standpoint, can I supply the Web requests the customer is requesting? Do I have the right Web requests to deliver? Can I get the requests to the customer in time?
Looking at this example, I better have a lot of instances of /orange.jsf available and I’d better be able to deliver them quickly.
My analogy begins to stretch a little thin at this point. I obvously don’t have a stockroom with a bucket of web requests – Instead I have a program that runs in a container. The program is the code (i.e., inventory) that is executed while the container controls (via logistics) how I get to that inventory. Knowing this, I now need to view my supply through a higher level of metrics:
My code is really made up of requests to other services. Here the evaluation process begins anew: do I have an adequate supply of JourneyService available? What’s most interesting here is CPU time. Remember that the Tomcats were hosted across 4 machines? This means that the supply is robust and scalable. What would happen if we hosted the cluster across 6 or 8 machines?
To answer this question we must finally address the supply = infrastructure part of the conversation. Looking at the processes that support this service, you can see that there is plenty of supply, indicated by low processor utilization.
In each instance, there is plenty of capacity supply, so adding more won’t help. However, clustering on faster boxes will improve speed. Though only marginally because this service demands more of other services than hosts.
Returning to my inventory analogy, having something in stock is of no use if you can’t put your hands on it. That’s what the container does; it manages access to resources.
I’ve talked a lot about the supply of cycles and services, but memory supply is important, too. Assuming that supply is finite, the conversation eventually reverts back to using available supply as wisely as possible. For example, garbage collection is a process that helps manage memory supply. Continuing with the stockroom and inventory analogy, GC is equivalent to wanting to give a customer an answer regarding their request for a product and putting them on hold while you research whether or not you carry the requested product, and if so, where is the product stored. In terms of network performance, this is the negative impact of garbage collection, commonly known as suspension time.
Talking about complex applications and environments using technology-specific jargon can create confusion. Even in this short article, it was an easy walk from simple concepts to complicated metrics. It can be easy to lose sight of the simplicity your goals too, but keep the faith and remember these guidelines:
- View supply in the context of what is being demanded.
- Each supplier in a stack either does its own work or calls on something else to do work. The work it does itself can be considered infrastructure supply.
Infrastructure supply comes in two forms – more and faster. Running out of capacity? Add more. Running slow? Add speed. Just watch out for the cardinal sin of adding more when the application will only benefit from faster.