Performance problem in Apache Camel’s conversion mechanism

Performance testing a complex application is never particularly easy. In the best cases, it’s tedious and mildly frustrating. It’s easy to spend hours or days diagnosing why you’re not getting the expected throughput. This occurred just last week during some load and performance testing of an application making heavy use of Apache Camel. We found a number of blocked threads in the Tomcat executor pool which clearly limited the application’s throughput.

After firing up YourKit, probably my second-favorite Java development utility to IDEA, the problem became readily apparent. The Camel route passed a payload from CXF as a MessageContentsList to a custom Processor implementation which called the following:

DecisionRequest req = exchange.getIn().getBody(DecisionRequest.class);

Since a conversion from MessageContentsList to DecisionRequest was required, Camel looks up the necessary converter in the BaseTypeConverterRegistry’s getOrFindTypeConverter(…) method. Here’s the version of that method in Apache Camel 2.9.0:

    protected <T> TypeConverter getOrFindTypeConverter(Class<?> toType, Object value) {
        Class<?> fromType = null;
        if (value != null) {
            fromType = value.getClass();
        }
        TypeMapping key = new TypeMapping(toType, fromType);
        TypeConverter converter;
        synchronized (typeMappings) {
            converter = typeMappings.get(key);
            if (converter == null) {
                converter = lookup(toType, fromType);
                if (converter != null) {
                    typeMappings.put(key, converter);
                }
            }
        }
        return converter;
    }

By synchronizing access to the collection of typeMappings, threads were forced to block until they could access the collection. The easiest workaround was to avoid using Camel’s conversion mechanism and implement a custom converter in the processor.

Luckily, the Apache Camel team was quick to recognize and resolve the problem. The version of this method in Apache Camel 2.9.1 and 2.10 removes this block.

Share

Do you have something to say?

Your email is never published nor shared.
Required fields are marked *