preload
Mar 31

In the last post I wrote about ways to tackle bottlenecks and to increase the performance of an application. When dealing with a high traffic application servicing tons of concurrent users all requesting the same data, intelligent caching can boost the speed in which requests are processed. As a result, lots of load is taken away from the database.

Querying a database makes much sense when the data requested changes a lot. But imagine the database is backing a blog or news website where the data requested from the database is the same in hundreds or even thousands of cases. The most frequent query sent to the database in such an environment is probably for loading the article on page one, which - once published - probably won’t change a lot. This doesn’t hurt the Database if your private blog has 100 unique visitors per day, but if the frontpage of a popular news website is attacked by 100.000 unique visitors per hour then you are in trouble. You need to use caching in order to take away stress from your database server.

An excellent, widely used open source cache solution which is easy to use and yet powerful is OSCache (http://www.opensymphony.com/oscache/). Besides features like clustering, a servlet filter for caching entire JSP pages or persistent caching it comes with a JSP tag library that enables you to include caching into your jsp based web application so easily it hurts.

All you have to do is:
1)       Add the OSCache jar file to your classpath, put the tld file into the WEB-INF directory of the webapp and declare the OSCache taglib in your jsp page:

<jsp:root version="1.2" xmlns:jsp="http://java.sun.com/JSP/Page"
      xmlns:cms="cms-taglib" xmlns:cmsu="cms-util-taglib"
      xmlns:c="http://java.sun.com/jsp/jstl/core"
      xmlns:fmt="http://java.sun.com/jsp/jstl/fmt"
    xmlns:cache="urn:jsptld:oscache.tld">

2)       mark portions of the jsp-page to be cached in your jsp page with cache tags:

<cache:cache key="${cacheKey}" time="0" language="${language}" time=”1800>
Content to be cached
</cache:cache>

In this example the cached portion of the page is stored under the key defined in the variable cacheKey, it supports multiple languages and expires after 1800 seconds. There are a few other attributes available for configuring the cache tag. More information can be found here http://www.opensymphony.com/oscache/wiki/JSP%20Tags.html

A cache with an invalidation timeout as seen in the above example is great for many situations, but sometimes you need full control on when a cache entry needs invalidating. OSCache offers an API to manage the cache in your Java code. This is an example of how to invalidate it in a Java web application:

ServletContext context = httpServletRequest.getSession().getServletContext();
ServletCacheAdministrator admin = ServletCacheAdministrator.getInstance(context);
Cache cache = admin.getAppScopeCache(context);
cache.flushEntry(key)

Piece of cake!

Take care,

Alex

PS: OSCache is under the OpenSymphony Software License, Version 1.1 which is derived and fully compatible with the Apache Software License.

Tagged with:
Mar 18

The performance of a dynamic web application can be quite unpredictable when you don’t know how many People are going to use it and of course how they are going to use it. You can predict some of the users’ behaviours and do your best to prepare your application to cope with the expected load. But sometime after the launch you suddenly find yourself in a situation where the performance of your application – or at least parts of it - is poor and the customer is unhappy. In cases like this typical reasons why you didn’t find the bottlenecks while developing are:

  • more users than expected
  • unpredicted behaviour of users
  • the amount of data stored in the production database compared to the development database
  • missing indexes on database tables
  • slow queries that need optimizing besides adding indexes
  • inefficient code
  • insufficient resources on the servers

So before using the brute force approach by throwing more hardware at the problem, the most important task to accomplish first is to find the real bottleneck. Just like in war times good intelligence is your key to winning the battle. So gather information first.

  • Find out which parts are slow and under which circumstances the performance is poor. Talking to actual users of the app is a good approach to do so.
  • Monitor the servers using tools like munin. CPU and Memory usage can show you which part of the architecture is stressed. In some cases the webserver idles most of the time, while the database machine is under heavy load
  • Check the Database for slow queries – most databases provide tools and statistics to determine the slowest queries. This will help you find out where indexes might be missing or which queries need optimizing
  • When optimizing queries first look at the explain plan. It can point you to the problem directly.
  • Check the DB for the most frequently executed queries – if a query is executed very often this might be a place where the application code needs optimizing or where caching might help. Add caching wherever the same piece of infrequently changing data is shown to many users many times. A great roundup on open source Java cache implementations can be found here.
  • Use a profiler to find out where in your code the application gets stuck. Chances are high that you end up locating the place where one of the slow queries is executed

Then start optimizing the parts you expect the most performance boost from. Be careful though when adding indexes on database tables with huge amounts of data – check if there is sufficient disk/table space available on the RDBMS. Indexes can also have effects on the performance of write operations.

If all this brain doesn’t solve the problem you might need to add muscle to your hardware:

  • Scale vertically by adding RAM and increasing CPU
  • Scale horizontally by adding machines, which is a lot easier for web servers as it is for database servers
  • An excellent piece of literature on this topic is “Scalable Internet Architectures” by Theo Schlossnagle

Take care…

Alex

Tagged with:
Mar 05

Let’s face it: we hate writing proposals. We’re engineers and we want to do what we do best: write code, design great architectures, try out new technologies, stuff like that. Nevertheless proposals are extremely important: no proposal -> no project -> no work -> no pay -> no doughnuts.

So here are my rules for writing a good proposal:

1) Embrace Proposals
Especially in times like these, where every customer seems to be cutting back costs, we should be happy about any request for a proposal that comes in. And with this positive attitude our proposals will get a lot better. The customer is our friend. We need her more desperately than the she needs us.

2) Think win-win.
Don’t be too cheap, don’t be too expensive. Just be fair. Customers are smart – they know if they can trust us or not. Both being too cheap and being too expensive may seem like loose-win or win-loose at first sight, but will lead to a loose-loose situation in the long run. If you’re too cheap, the customers get used to your prices and you won’t enjoy working for them anymore. Being too expensive will lead to unhappy customers, because they won’t trust you and find someone else for the job. We are exchangeable.

3) Don’t just think in terms of man-days.
Simply thinking in terms of man-days is not too bad. If estimated properly the project will cover your costs and maybe leave you some profit on top. But imagine you can finish a complex project in a short amount of time, because you already have this great component you’ve written in a previous project that you can use for this one, too? Ask yourself: how much is it worth? How much would others charge for the same project?

4) Cover your back
Always have someone else check your proposal. Never send a proposal to a customer, no one else has taken a good look at. Ask someone to check the proposal critically, question everything from the concept down to the pricing. The resulting proposal will contain less typos and someone else might find something significant you might have forgotten or overlooked. Maybe someone else will think it’s too cheap, too expensive, lacking detail or whatever.

5) Be complete and be clear
The clearer and the more complete the definition of the deliverables, the less potential for discussions with the customer there’ll be. Not only mention what you will deliver, also mention what you will not deliver. If the proposal is about writing a custom intranet application, be sure to mention that setting up the production and staging environment is not part of the proposal – if, of course, someone else is in charge of that. Sometimes, out of laziness, we write stuff like “standard reporting – 1000$”. The customer will probably have a completely different opinion on what a standard report is than you. Sentences like this have the potential of eating up your profit, because the customer expects you to make him happy. And instead of a CSV export of customer addresses, you find yourself writing a full featured CRM application.

7) Find the pitfalls
Every project contains risks. Think about worst case scenarios and everything that could go wrong during the project – e.g. introducing a new technology you haven’t worked with before. The more risks you find, the more buffer you add to the price. Sometimes it even makes sense to mention the risks and the customer will better understand the pricing.

7) Blurry details, blurry price
If it’s not completely clear what the customer wants and what the desired outcome of the project will be, you’re walking on thin ice with a proposal. In that case it’s often better to name ballpark numbers and ranges instead of a fixed price.

Is there anything I’ve forgotten? Let me know and leave a comment – I’ll appreciate it.

Alex

Tagged with: