Professional Documents
Culture Documents
Top Twelve Ways To Speed Up Your Liferay Deployment PDF
Top Twelve Ways To Speed Up Your Liferay Deployment PDF
UP YOUR LIFERAY
DEPLOYMENT
Copyright © 2000 2009 Liferay, Inc.
All Rights Reserved.
No material may be reproduced electronically or in print, duplicated,
copied, sold, resold, or otherwise exploited for any commercial purpose
without express written consent of Liferay, Inc.
Rich Sezov
Knowledge Manager
Liferay, Inc.
Liferay Portal: Open Source and
Tweakable
As an infrastructure portal, Liferay Portal can support over 3300 concurrent users
on a single server with mean login times under ½ a second and maximum
throughput of 79+ logins per second.
In collaboration and social networking scenarios, each physical server supports
over 1300 concurrent users at average transaction times of under 800ms.
Liferay Portal’s WCM scales to beyond 150,000 concurrent users on a single
Liferay Portal server with average transaction times under 50ms and 35% CPU
utilization.
Given sufficient database resources and efficient load balancing, Liferay Portal
can scale linearly as one adds additional servers to a cluster.
How do I get Liferay to do that?!?
Top Twelve Ways to Speed Up Your Liferay Deployment
Number 12:
SSO CAS Filter: Are you using CAS for Single Sign-On? If not, you don't need this
filter running.
SSO NTLM Filter: Are your users authenticating via NTLM (NT LAN Manager)? If not,
you don't need this filter running.
SSO OpenSSO Filter: Are you using OpenSSO for Single Sign-On? If not, you don't
need this filter running.
Virtual Host Filter: Are you mapping domain names to communities or
organizations? If not, turn this filter off.
Sharepoint Filter: Are you using Liferay's Sharepoint functionality for saving
documents directly to the portal? If not, this filter is not for you. Turn it off.
How do you turn off a servlet filter?
Use EMM386 to put all the TSRs into high memory to free
up—oh, never mind, wrong decade.
Number 10: Tune your JVM parameters.
Again, there is nothing set in stone for this: you will have to go through the
cycle of tune and profile, tune and profile until you get the parameters right.
Java memory looks something like this:
Young Generation
Eden From To
Java Heap
Old Generation
Permanent Generation
Garbage Collection
Old Generation
Permanent Generation
When all of this is done, the space is compacted, so the memory is contiguous.
Serial vs. Parallel Garbage Collection
JAVA_OPTS="$JAVA_OPTS -XX:NewSize=700m
-XX:MaxNewSize=700m -Xms2048m -Xmx2048m
-XX:MaxPermSize=128m -XX:+UseParNewGC -XX:
+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled
-XX:SurvivorRatio=20 -XX:ParallelGCThreads=8"
Number 9:
<cache
name="com.liferay.portlet.messageboards.model.impl.MBMessageImpl"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="600"
overflowToDisk="true"
>
<cacheEventListenerFactory
class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicatePuts=false,replicateUpdatesViaCopy=false"
propertySeparator=","
/>
<bootstrapCacheLoaderFactory
class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"
/>
</cache>
Tuning the Cache
There are many, many other settings which can be used to tune the cache.
You can, as an example, change the cache algorithm if it seems to be caching
the wrong things.
If we were to go over them all, we'd never get through to the rest of the top
twelve; speaking of which....
Number 8:
Whenever Liferay calls Lucene to index some content, it may create any number
of files to do so.
Depending on the content, these files can be large files or lots of small files.
Every now and then, Liferay optimizes the index for reading by combining
smaller files into larger files.
You can change this behavior based on your use case.
The property is lucene.optimize.interval
If you are doing a lot of publishing and loading of data, make the number very
high, like 1000.
If you are doing mostly reads, make it low, like the default value of 100.
Of course, the best thing is to move search out to a separate environment, such
as Solr.
Number 7:
Step 1: Install the Solr web application on a separate environment from your
Liferay environment.
Step 2: Grab the Solr plugin from Liferay and extract it to your file system.
Step 3: Edit the file docroot/WEB-INF/src/META-INF/solr-spring.xml.
Step 4: Change the URL in the following Spring bean configuration to point to
your newly installed Solr box and the save the file:
<bean id="solrServer" class="com.liferay.portal.search.solr.server.BasicAuthSolrServer">
<constructor-arg type="java.lang.String" value="http://localhost:8080/solr" />
</bean>
One of the ways Liferay is able to support so many databases is that it does not
use any single database's method of determining sequences for primary keys.
Instead, Liferay includes its own counter utility which can be optimized.
The default value: counter.increment=100 will cause Liferay to go to the database
to update the counter only once for every 100 primary keys it needs to create.
Each time the counter increments itself, it keeps track of the current set of
available keys in an in-memory, cluster aware object.
You could set this to a higher number to reduce the number of database calls for
primary keys within Liferay.
Number 5:
Step 3: Set your server proxy to exclude from the proxy the path to the theme.
This will vary from web server to web server. For Apache and mod_proxy, you
would add this to your configuration file:
ProxyPass /themes !
With this configuration, Liferay will deploy your theme to the path specified,
which will be served up by your web server.
Number 3:
Instead of standard <img src> tags, use the <liferay-ui:icon> tag as shown above.
What does this do?
jdbc.read.driverClassName=com.mysql.jdbc.Driver
jdbc.read.url=jdbc:mysql://dbread.com/lportal?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=false
jdbc.read.username=
jdbc.read.password=
jdbc.write.driverClassName=com.mysql.jdbc.Driver
jdbc.write.url=jdbc:mysql://dbwrite.com/lportal?useUnicode=true&characterEncoding=UTF-8&useFastDateParsing=fal
jdbc.write.username=
jdbc.write.password=
Make sure the spring config is included in your portal-ext.properties file (see
next slide)
Read Writer Database
spring.configs=\
META-INF/base-spring.xml,\ You will now have a dedicated data
\
META-INF/hibernate-spring.xml,\ source where write requests will go.
META-INF/infrastructure-spring.xml,\
META-INF/management-spring.xml,\ With replication enabled, updates to
\
META-INF/util-spring.xml,\ all nodes can be done much faster
\
META-INF/editor-spring.xml,\ by your database software.
META-INF/jcr-spring.xml,\
META-INF/messaging-spring.xml,\ You can have one configuration of
META-INF/scheduler-spring.xml,\
META-INF/search-spring.xml,\ your database optimized for reads.
\
META-INF/counter-spring.xml,\
META-INF/document-library-spring.xml,\
You can have one configuration of
META-INF/lock-spring.xml,\ your database optimized for writes.
META-INF/mail-spring.xml,\
META-INF/portal-spring.xml,\
META-INF/portlet-container-spring.xml,\
META-INF/wsrp-spring.xml,\
\
META-INF/mirage-spring.xml,\
\
META-INF/dynamic-data-source-spring.xml,\
#META-INF/shard-data-source-spring.xml,\
\
META-INF/ext-spring.xml
Trick #2: Database Sharding
spring.configs=\
META-INF/base-spring.xml,\ And, of course, enable it in your
\
META-INF/hibernate-spring.xml,\ spring configs.
META-INF/infrastructure-spring.xml,\
META-INF/management-spring.xml,\
\
META-INF/util-spring.xml,\
\
META-INF/editor-spring.xml,\
META-INF/jcr-spring.xml,\
META-INF/messaging-spring.xml,\
META-INF/scheduler-spring.xml,\
META-INF/search-spring.xml,\
\
META-INF/counter-spring.xml,\
META-INF/document-library-spring.xml,\
META-INF/lock-spring.xml,\
META-INF/mail-spring.xml,\
META-INF/portal-spring.xml,\
META-INF/portlet-container-spring.xml,\
META-INF/wsrp-spring.xml,\
\
META-INF/mirage-spring.xml,\
\
#META-INF/dynamic-data-source-spring.xml,\
META-INF/shard-data-source-spring.xml,\
\
Number 1:
</script>
</html>
<script language=javascript>
if(window.yzq_p==null)
document.write("<scr"+"ipt language=javascript src=http://l.yimg.com/d/lib/bc/bc_2.0.4.js></scr"+"ipt>");
</script>
Positioning Changes Things
Bingo!
</script>
</html>
<script language=javascript>
if(window.yzq_p==null)
document.write("<scr"+"ipt language=javascript src=http://l.yimg.com/d/lib/bc/bc_2.0.4.js></scr"+"ipt>");
</script>
They have JavaScript after the HTML tag. That's not according to spec, but all the
browsers support it, and it improves performance.
JavaScript in Portlets
If you have JavaScript in your portlets, you can control where Liferay positions it
via the liferay-portlet.xml file.
<footer-portlet-javascript>/html/portlet/message_boards/javascript.js</footer-portlet-javascript>