In Chapter 2, Load Balancing and Clustering Best Practices, we configured the software load balancer using the Apache Web Server. We discussed that around 20 percent to 30 percent of the load of the system will be handled by the Apache Web Server. It is very important to follow performance best practices in Apache Web Server configuration to get the best performance. In this section, we will learn performance best practices related to the Apache Web Server configuration.
In Chapter 1, Architectural Best Practices, we discussed about delivering static content using the Apache Web Server. Delivering static resources of the Liferay Portal through the Apache Web Server can improve the response time enormously. When static resources are delivered through the Apache Web Server, no Application Server overhead is added and ultimately, it improves the response time and performance. We learned how to configure the software load balancer using the mod_jk
module of Apache Web Server in Chapter 2, Load Balancing and Clustering Best Practices. Let's learn how to extend this configuration and deliver static content directly through the Apache Web Server.
liferay-node-01
to the <APACHE_HOME>/htdocs
directory of the Apache Web Server:node-01liferay-portal-6.1.1-ce-ga2 tomcat-7.0.27webappsROOThtml
node-01liferay-portal-6.1.1-ce-ga2 tomcat-7.0.27webappsROOTlayouttpl
node-01liferay-portal-6.1.1-ce-ga2 tomcat-7.0.27webappsROOTwap
node-01liferay-portal-6.1.1-ce-ga2 tomcat-7.0.27webapps*
(except the root directory)mod_jk.conf
file located in the <APACHE_HOME>/conf
directory, and add the following line of code after the JkMount /* loadblancer
line:JkUnMount /*.js loadbalancer JkUnMount /*.png loadbalancer JkUnMount /*.jpg loadbalancer JkUnMount /*.gif loadbalancer JkUnMount /*.ico loadbalancer JkUnMount /*.swf loadbalancer
In the given steps, we copied all the content from the Liferay Portal node to the public directory of the Apache Web Server. We then disabled delivering static resources through the load balancer. That in turn delivers all unmounted static resources from the Apache Web Server's htdocs
directory. CSS files are also static files. They can be served from the Apache Web Server. We intentionally did not configure the Apache Web Server to serve CSS files because Liferay Portal 6.1 CSS files can have dynamic code. Liferay Portal 6.1 uses the SASS framework to parse dynamic code of CSS files when they are requested. If you are using an earlier version of Liferay, we can also serve CSS files through the Apache Web Server.
If we configure static resource delivery through the Apache Web Server, we need to make sure that we synchronize static resources from the Liferay Portal node to the Apache Web Server after every deployment. It is recommended to make this process automatic by creating shell scripts.
One of the UI best practices is to reduce the number of HTTP requests for static resources. This can be done by merging static resources like JavaScript. Liferay provides a built-in feature that merges most common JavaScript files dynamically. Liferay defines the most common JavaScript files used by an unauthenticated user using the javascript.barebone.files
property. Similarly, it defines the most common JavaScript files used by an authenticated user using the javascript.everything.files
property. Liferay combines these JS files into one file and stores in the Application Server's temp
directory. Each and every page loads either the barebone or everything JS bundle. They load these JS files by calling everything.jsp
and barebone.jsp
. As Liferay combines lots of JS into one file, it will be useful if we can serve these large JS files directly through the Web Server. We can do that by performing the following steps:
barebone.jsp
and everything.jsp
from the browser and save them into the local system.barebone.jsp
can be accessed by using http://<Apache Web Server IP>/html/js/barebone.jsp?minifierType=js&minifierBundleId=javascript.barebone.files
and everything.jsp
can be accessed by using http://<Apache Web Server IP>/html/js/everything.jsp?minifierType=js&minifierBundleId=javascript.everything.files
.
barebone.jsp
and everything.jsp
to the <APACHE_HOME>/htdocs /html/js/
directory.mod_jk.conf
file located in the <APACHE_HOME>/conf
directory, and add the following line of code after the JkMount /* loadblancer
line:JkUnMount /html/js/barebone.jsp loadbalancer JkUnMount /html/js/everything.jsp loadbalancer
In these steps, we placed the generated barebone.jsp
and everything.jsp
responses on the Apache Web Server in the same context path. We also configured the Apache Web Server to deliver everything.jsp
and barebone.jsp
directly from the Apache Web Server public directory. These two files are required to be synchronized whenever any of the JS listed in the javascript.barebone.files
or javascript.everything.files
property. Even if either of the two properties is changed in the portal-ext.properties
file, it is required to copy the latest version of everything.jsp
and barebone.jsp
on the Apache Web Server.
In the servlet filter configuration section, we talked about disabling the GZip filter
of the Liferay Portal server to improve performance. We talked about taking care of GZip compression, although the Apache Web Server gives better performance. Most of the browsers support compressed resources. It will improve the network data transfer if we can compress the HTTP response before sending it to the browser. Browsers will then decompress the response before rendering.
GZip is a famous compression algorithm supported by almost all the browsers. The Apache Web Server can be configured to compress the HTTP response using the GZip compression algorithm. Let's learn this by applying it to our setup.
mod_deflate.conf
, in the <APACHE_HOME>/conf
directory, and add the following content to it:LoadModule deflate_module modules/mod_deflate.so SetOutputFilter DEFLATE SetEnvIfNoCase Request_URI .(?:gif|jpe?g|png)$ no-gzip dont-vary SetEnvIfNoCase Request_URI .(?:exe|t?gz|zip|bz2|sit|rar)$ no-gzip dont-vary
httpd.conf
file located in the <APACHE_HOME>/conf
directory and add the following lines at the bottom:Include mod_deflate.conf
The Apache Web Server ships with a mod_deflate
module, which can compress all the responses. In the preceding steps, we first enabled the mod_deflate
module by adding the LoadModule
statement. We then enabled the output filter to compress all the responses using the mod_deflate
module. We also provided the configuration to skip some of the resources, such as GIF, JPEG, and so on because they are already in a compressed format. We should skip all such resources that are already in compressed format.
Every browser caches static resources in their cache. This cache is controlled by the Cache-Control
request header attribute. It is a good idea to set a longer cache expiration period for static resources, so that the browser will download them only when they are removed from the browser cache on cache expiration. The Apache Web Server provides a way to configure cache expiration for any resource.
As we use the Apache Web Server in front of Liferay Portal, we can configure a Cache-Control
attribute using the Apache Web Server. Let's learn how to configure Cache-Control
using the Apache Web Server configuration.
mod_expires.conf
, in the <APACHE_HOME>/conf
directory, and add the following content to it:# Turn on Expires and set default to 0 ExpiresActive On ExpiresDefault A0 # Set up caching on media files for 1 year (forever?) <FilesMatch ".(flv|ico|pdf|avi|mov|ppt|doc|mp3|wmv|wav)$"> ExpiresDefault A29030400 Header append Cache-Control "public" </FilesMatch> # Set up caching on media files for 1 week <FilesMatch ".(gif|jpg|jpeg|png|swf)$"> ExpiresDefault A604800 Header append Cache-Control "public" </FilesMatch> # Set up 2 Hour caching on commonly updated files <FilesMatch ".(xml|txt|html|js|css)$"> ExpiresDefault A7200 Header append Cache-Control "proxy-revalidate" </FilesMatch> # Force no caching for dynamic files <FilesMatch ".(php|cgi|pl|htm)$"> ExpiresActive Off Header set Cache-Control "private, no-cache, no-store, proxy-revalidate, no-transform" Header set Pragma "no-cache" </FilesMatch>
httpd.conf
file located in the <APACHE_HOME>/conf
directory and add the following line at the bottom:Include mod_expires.conf
In the preceding steps, we did not include the LoadModule
directive for the mod_expire
module in the mod_expires.conf
file because it is normally done in the default httpd.conf
file. If we do not find the LoadModule
directive for the mod_expire
module in httpd.conf
, we need to add the same in the mod_expire.properties
file. We then configured cache expiration values for various types of resources. For example, we configured cache expiration to 1 week
for images. If the Portal is stable and we are not making frequent changes to the Portal, it is advisable to set the expiration period longer. So, it is advisable to review the expiration period according to the nature of the Portal.
Apache Web Server's multiprocessing module is responsible for accepting requests on the network port on the server. MPM is also responsible for dispatching requests to children for processing. In order to fine-tune the Apache Web Server, MPM must be configured correctly. The Apache Web Server ships with different MPM options. It is important to select the right MPM. Here is the list of different MPM options:
For our solution, it is recommended to use the Worker MPM. Every MPM provides a way to configure the size of the processes or threads pool. It is very important to configure these parameters properly to get the best performance. Here is the sample configuration setting that needs to be added in httpd.conf
of the Apache Web Server:
<IfModule worker.c> ServerLimit 16 StartServers 2 MaxClients 150 MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 25 </IfModule>
To know which MPM is used by the Apache Web Server, the following command can be used:
httpd –l
This command can be run on an Apache Web Server. It returns a list of modules in which the Apache binary is compiled. If we find prefork.c
in the result, it means that the Apache Web Server is using the Prefork MPM.
In the preceding configuration, the most important configuration parameter is MaxClients
. This parameter defines the maximum number of concurrent requests that can be handled by the Apache Web Server at a time. The MaxClients
value must be configured lower than or equal to the maxThreads
value of the Tomcat's AJP connector. If the value of the MaxClients
parameter is higher than maxThreads
of the AJP connector, it is possible that the Liferay Portal server hangs up or some requests are dropped off. The Worker MPM is a multi-threaded MPM. So, each process starts multiple threads. The ThreadsPerChild
parameter configures the maximum number of threads that can run within one process. The ServerLimit
parameter is used to limit the maximum number of process that can be started by the server. The value of the ServerLimit
parameter must be higher than MaxClients
or ThreadsPerChild
. It is advisable to configure these values carefully with respect to the physical memory on the Apache Web Server. During the load test, these values should be tuned along with the Tomcat server's thread pool configuration.
3.144.30.62