Tuesday, October 27, 2009

Using ThreadDump to solve production performance issues

One of the cool features with JDK 1.6 is that you can take a thread dump of a running VM. We were intermittently seeing spikes in our production servers and server would become slow for users whenever we saw a spike. we setup a cron job to take threaddump at regular interval and we nailed the issue. Most thread dumps were 300 KB but on was 25 MB and that ringed some bells. Looking at thread dump told use there were 3300 threads executing the same Runnable Task. Further investigation told us that we were using Executors.newCachedThreadPool to create a thread pool in Spring. This would create a new thread if not available for each submitted job. So it created 3300 threads, more CPU was spent on switching thread context than really doing the job. Using Executors.newFixedThreadPool with a size of 15 solved the issue :).

Monday, October 26, 2009

Aggregating DWR interface scripts

My company has a website and running Yslow on it reported that the no of HTTP requests were in the range of 120-130. Accessing the site from UK was pretty slow. Now we used CSS sprites to reduce the no of css images and we were already using JS and CSS aggregation. There were still 10-12 DWR interface scripts and as browser stops rendering while its downloading and rendering js files. I was looking for a solution for aggregate DWR generated interfaces. I searched a lot and than landed onto JAWR. As we are using build time aggregation for static JS I am using JAWR only for generated interface JS. Here are the things I did.

Add jawr lib to WEB-INF/classes

Note JAWR servlet should start after DWR servlet   

# Common properties
#dont forget the below property.
#I forgot it and struggled for 6 hours after reading JAWR code to figure this out
======================JSP changes==============================
<%@ taglib prefix="jwr" uri="http://jawr.net/tags" %>
<jwr:script src="/jawrBundle/agg_dwr.js"/>

Friday, October 16, 2009

Ant exec Mysql

to execute a mysql command like "mysql my_db -ufoo -pbar <server/resource/sql/mysql/foo/create_tables.sql" from mysql use the input attribute to pass standard input

        <exec executable="mysql" dir="${basedir}/${build}" input="${basedir}/resource/sql/mysql/foo/seed_data.sql">
            <arg value="${sql.db_name}" />
            <arg value="-u${sql.db_username}" />
            <arg value="-p${sql.db_password}" />

Note this is after Ant 1.6 before Ant 1.6 use the task. The only thing I dont like about it is that you have to set the classpath for the driver.

Friday, October 9, 2009

CGLibProxy example

JDK proxy can't extend classes, you would need to Create a CGLib proxy. But I would recommend using this as the last resort when all your hopes with JDK proxy have ran out.
Below is a sample code to create a CGLib proxy.

Don't judge on the code as I had to remove lots of code before posting copyrighted code.

User trace= (User) Enhancer.create(User.class, new MethodInterceptor(){
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
long start = System.currentTimeMillis();
return method.invoke(user, args);
} finally {
logger.debug(" TimeLog: Time taken in "+ (System.currentTimeMillis() - start));

Wednesday, October 7, 2009

Blogging xml code in Blogger

its weird that Blogger do not have a <pre> or <code> tag. I used http://centricle.com/tools/html-entities/ to encode the xml with html entities

Ant Grep alternative

if you are using ant filterset to replace properties and you want to figureout if some of the properties are set or not than below target can help you in doing that.

<target name="checkTokenReplacement" description="verifies that all tokens are replaced properly and there is not a token with _@ or ENV. in it.">
<pathconvert property="errorsFiles">
<fileset dir="${dirToScan}">
<include name="${filePattern}">
<contains text="_@">
<fileset dir="${dirToScan}">
<include name="${filePattern}">
<contains text="ENV.">
<condition property="errorsOccured">
<length string="${errorsFiles}" when="greater" length="0">
<fail message="Following files ${errorsFiles} contain _@ or ENV. or oracle/jython errors." if="errorsOccured">