CQ5 (now Adobe Experience Manager) is a web content management system (WCMS) originally developed by Swiss company Day Software. Day was later acquired by Adobe, and its core product became Adobe’s primary WCMS offering. CQ5 helps companies to build, manage and deliver their digital contents across different channels at scale, especially when there’s a large content library to handle.
When we first approached CQ5 (Adobe Experience Manager) for instrumentation, we tried to understand it from a developer perspective – what are the architecture and use cases of CQ5?
Before we get into what could go wrong, let’s look at how it’s supposed to work. There are 4 main components in the CQ5 stack:
- CQ5 Application – The “business logic” core of CQ5. It consists of various components such as CQ WCM, CQ Workflow Engine. It also provide administrative UIs for developers to build, manage and publish digital contents such as web pages, images and videos.
- Apache Sling – A REST based web application framework. Sling operates in a rather different model compared to other web application frameworks. A typical application framework usually maps URLs to Java servlets, then the resolved servlets would decide what and how resources should be loaded and processed. For Sling, it’s actually the other way around – URLs are first resolved to resources provided by the underlying JCR (Java Content Repository), based on the loaded resource, servlets/scripts are looked up and used to process the resources loaded.
- JCR (Jackrabbit) – A flavor of Java Content Repository. JCR specifies ways to access contents (any digital content – images, scripts, binary, etc.) stored in a Tree structure. Each tree node represents a content item. Apache Jackrabbit, the default JCR provider used in Apache Sling, is one of the open source implementations of JCR. By default Sling configures the persistence manager Derby DB for Jackrabbit.
- Felix OSGi – The extension framework. Various components can be deployed as OSGi bundles to extend the functionality of a CQ5 install in a dynamic and modular fashion.
Typically, CQ5 is deployed in one of two ways.
As a web application server
CQ5 can be deployed so that it actually serves web pages based on the content in the repository. It handles common HTTP protocols and performs various operations accordingly such as loading digital resources, rendering pages, calling back-end processing. This setup is the simplest deployment, because you don’t need anything extra.
As a content repository
In more complex setups, CQ5 can serve digital content to other clients directly, such as Jackalope from PHP. The underlying JackRabbit (JCR implementation) supports WebDAV, an extension of HTTP. Other clients can access resources stored in CQ5 using HTTP/WebDAV operation such as GET and SEARCH. This can allow scaling layers to be built on top of CQ5, separating the need to store a lot of content from the need to serve it to millions of people.
Once the architecture and use cases were identified, we could build instrumentation to analyze the CQ5 process flow which matters to developers. In particular, Apache Sling and JCR layers are good candidates.
Apache Sling instrumentation
Since Apache Sling uses a “resource centric” model, there are 3 pieces of interesting information:
- Resource resolution – what is the actual resource loaded for the component?
- Servlet/scripts resolution – which servlet/script is selected to process the resource? Sling has its own selection logic based on target resource type, request selector, request extension and request method name.
- Servlet/scripts processing on the resource loaded – how much time it’s taken to process the resource with the servlet logic?
Our answer is to capture all of the information within our “sling” layer with different profiles for each of the step: 1. resource resolution, 2. servlet/script resolution and 3. servlet/script execution
For CQ5 stack as Content Repository Server, most of the heavy lifting happens in the JCR (Jackrabbit) layer.
There are 3 ways to access the data via JCR:
- Get resource by its path
- Tree node traversal
We decided to capture JCR Queries in our instrumentation as query operations’ performance can vary greatly depending on the queries, which are good candidates for optimizations.
Once the slow JCR query is identified, developers can check for optimization. Several JCR(Jackrabbit) query performance optimization strategies include:
- Optimize the query, narrow down the scope earlier. Use checks that could narrow down the result, such as adding node type restrictions or criteria on properties (timestamps check). Also be careful with using JOIN in JCR (jcr-sql2) as it could be slow.
- Adjust cacheSize and resultFetchSize in JackRabbit – http://wiki.apache.org/jackrabbit/Search
Either way you set it up, CQ5 is a powerful tool to manage content for a complex site, while still allowing a lot of flexibility in scaling multiple elements up to handle high traffic.