In parts 1 and 2 of this series, I discussed how to optimize XML Metadata Extraction in your Alfresco WCM environment, and how (and why) to disable permissions checking, respectively. Besides those two optimizations, there are several other things that you can do to tweak an Alfresco System Receiver (ASR) for better performance, which I will discuss now.
First, optimize your JVM settings! By default, Alfresco ships with a maximum heap size of 512MB of RAM. As such, under high load, an ASR can max out a heap of that size and thus serve content a bit more slowly. So you definitely want to increase the maximum heap size to as high as you can. Also, depending on how you set up your minimum and maximum heap sizes, you may want to adjust the size of newly allocated heap space using the -XX:NewSize command line option. There are a few other things you can adjust as well regarding your JVM like enabling hotspot pre-compilation, and the size of the stack, amongst others. See the JVM Tuning page on the Alfresco wiki for more details. Ultimately for my testing on my Macbook Pro running Alfresco on Windows XP via VMWare Fusion, I used the following settings (in alfresco.bat):
set JAVA_OPTS=-Xms768m -Xmx1536m -Xss1m -XX:MaxPermSize=128m -Xcomp -Xbatch -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:NewSize=384m -XX:CMSInitiatingOccupancyFraction=80 -server
Speaking of virtualization, that reminds me. Don’t virtualize! For best performance, use the actual hardware! Virtualization adds overhead. I have not yet tested ASR performance without virtualization to be able to prove the impact that it has, but I will, and when I do, you can be sure that I’ll update this post, so come back sometime soon!
Anyway, now that you’ve tuned the JVM, what about the database? Increasing the size of the database connection pool will enable your ASR to handle more concurrent users. Therefore, in custom-repository.properties in your extension directory (Alfresco 3.x) or in alfresco-global.properties (Alfresco 3.2+), you can set the following:
In addition to increasing the database thread pool, you should increase the tomcat thread pool as well. This can be done by modifying the following line in alfresco/tomcat/conf/server.xml:
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
Now that we’ve tuned some parts of the server, let’s turn off some things we don’t need. For example, you should remove the share web application (share.war) that is installed with Alfresco by default, as well as Web Studio (studio.war) and the mobile web application (mobile.war) if you’re running Alfresco Community. Be sure to remove (or just move elsewhere) all of the unneeded .war files as well as their exploded directories. The only application you need on an ASR is alfresco.war. Additionally, you may want to download a clean copy of alfresco.war (making sure you have the correct version for your installation), and be sure NOT to apply the SharePoint Protocol AMP file to it. No sense running another listener that no one will ever use! Also, you typically want to lock down an ASR so that content is only accessed by your web application via the web scripts you’ve authored to expose your web content. Therefore, you don’t need to be running virtual filesystems such as CIFS for shared drives, and FTP. This can be done very simply, by setting the following in custom-repository.properties (3.1) or alfresco-global.properties (3.2):
Another very useful exercise is to optimize your web scripts. For example, if you have a page in your web application that has three content areas managed by Alfresco, don’t have the web application call three separate web scripts, each of which returns only content related to that area. Network hops are expensive, so they should be minimized to just one hop per page type. In this scenario, performance would likely be improved by having the web application call a single web script per page type which returns all of the content to be displayed by that page at that time.
That leads to the next point: build caching into your web application, or as a layer between your web application and Alfresco, and be sure to determine and implement a cache update strategy. If the web application can simply hit a cache that is local to it while the cache is updated asynchronously via some other process, the web application will fly as compared to making calls to the ASR every single time a user views a page.
To conclude, here’s a handy list of steps you can take to optimize ASR performance, from my estimation of decreasing impact:
- Turn permissions checking off
- Optimize your web scripts per page type on your web site
- Don’t virtualize
- Tune your JVM for performance
- Increase the database connection pool
- Increase the tomcat thread pool
- Remove/disable things you don’t need
- CIFS Server
- FTP Server
- Web Studio
- SharePoint Protocol (SPP) support
- Configure XML metadata extraction so that it occurs on your authoring server, not the ASR
If you have additional suggestions, please share, I’d love to hear them!