Load Balancing with Alkacon Clustering OCEE
Contents |
Overview
Alkacon sells a non open-source module for OpenCMS that allows you to cluster multiple application servers running on one database without having to worry about the problems of caching and publishing data between the 2+ nodes.
Setup
The setup for the OCEE Cluster Package by Alkacon is of course well documented in the distribution Alkacon provides.
In basic lines, for an existing installation it consists in:
- Importing the required ocee modules.
- Copying sample new configuration files into /WEB-INF/config and configuring them (depending on your requirements, but at least ocee-license.xml)
- Editing existing configuration files to use the righ Alkacon OCEE classes (opencms.xml, opencms-system.xml, opencms.properties)
(Follow same steps for the second server of the cluster)
Preventing a workplace login on a slave server (without using apache redirects)
OCEE Clustering does not support writes from multiple nodes. A master - slave topology is the only working mode: You will need a single master that serves the workplace of OpenCms.
Normally you will set up OCEE Cluster together with two databases and OCEE Replication. In that mode OCEE Replication will not replicate the OpenCms workplace. Once you perform a full replication with it everything will be deleted (including the workplace) and the workplace will not be available on the slave.
However you might use
- a Single shared database
- some replication on database product level (like mysql replication)
and therefore a login on the slave would be possible but unwanted. Unwanted when using in all cases:
Single shared database (no replication) If you allow logins to master and slave OpenCms workplace you might run into concurrent write / delete / create and caching issues. Duplicate resource UUIDS might happen or more likely: Same named files are created on both nodes but with a differen Structure UUID. Don't try this.
Custom database replication that supports two-way synchronization The same problems as in the first case may occur in this setup in case you let users log in to the workplace on both nodes.
Custom database replication with master-slave replication If you let users log in to the OpenCms workplace on master and slave then modifications on the slave
- will not be seen on the frontend pages served from master
- might be overwritten by changes on the master.
- replication might run into "duplicate UUID" Exceptions in case content with same path has been created on slave and later on master.
It is possible to let OpenCms redirect from slave instances to the master instances when users try to request the login on slaves. This works because the following code.
org.opencms.workplace.CmsLogin.java#displayDialog():
if ((OpenCms.getSiteManager().getSites().size() > 1) && !OpenCms.getSiteManager().isWorkplaceRequest(getRequest())) { // this is a multi site-configuration, but not a request to the configured Workplace site StringBuffer loginLink = new StringBuffer(); loginLink.append(OpenCms.getSiteManager().getWorkplaceSiteMatcher().toString()); loginLink.append(getFormLink()); // send a redirect to the workplace site getResponse().sendRedirect(loginLink.toString()); ...
From this the following prerequisites follow to have the redirect working:
- You have to configure more than one site in /WEB-INF/config/opencms-system.xml
- Your workplace node on slaves has to point to the workplace of the master server.
Normally on the slave it would not make sense to configure another site. This most often is intended to serve more than one website from a single OpenCms instance. However in the case that you just serve a single website form your cluster just use the url of the master node as a site entry in your config on the slave too. This does not make much sense but is only good to allow the redirect to work.
Demo configuration of /WEB-INF/config/opencms-system.xml
<sites> <workplace-server>http://master.mydomain.com:8080</workplace-server> <default-uri>/sites/default/</default-uri> <!-- Explanation: Only, if we define more than 1 site the workplace site will be matched and a redirect to the workplace will be done in case a login on the slave is attempted. --> <site server="http://master.mydomain.com:8080" uri="/sites/default/"/> <site server="http://slave.mydomain.com:8080" uri="/sites/default/"/> </sites>
Tip: You can also limit workplace access to master via mod_jk configuration (it is highly probable you will use mod_jk for load balancing the cluster): vhosst config mounts worker: <source lang="bash"> ... JkMount /opencms/opencms/system/login/* admin_worker JkMount /opencms/opencms/system/workplace/* admin_worker ... </source> and in mod_jk_worker.properties a worker which is not load balanced but points to the single master.
Issues
This section shows known issues getting OCEE to work. It is divided into application servers considering issues in one AS may not be reproducible in a different one.
JBoss
Description
When installing on JBoss Application Server, you may find an issue that avoids OCEE from getting servers status and therefore making the servers from the cluster seem not available. Symptoms are:
- Active workplace server reports as unavailable (that means it can't reach itself)
- Non-active workplace servers indicate they have been disabled due to the use of the same MAC address (null)
Alternatively, you may find in the logfiles something similar to
Error while getting instance information org.opencms.main.OpenCms.getSystemInfo().getServerName() bsh.InterpreterError: Error loading classmanager: java.lang.ClassCastException: bsh.classpath.ClassManagerImpl at bsh.BshClassManager.createClassManager(Unknown Source) at bsh.Interpreter.<init>(Unknown Source) at bsh.Interpreter.<init>(Unknown Source) at bsh.Interpreter.<init>(Unknown Source) at org.opencms.ocee.cluster.CmsClusterEventHandler.handleClusterGetInstanceInfo(CmsClusterEventHandler.java:527) at org.opencms.ocee.cluster.CmsClusterEventHandler.cmsEvent(CmsClusterEventHandler.java:220) at org.opencms.main.CmsEventManager.fireEventHandler(CmsEventManager.java:203) at org.opencms.main.CmsEventManager.fireEvent(CmsEventManager.java:127) at org.opencms.main.CmsEventManager.fireEvent(CmsEventManager.java:148) at org.opencms.main.OpenCms.fireCmsEvent(OpenCms.java:169) at org.opencms.ocee.cluster.CmsClusterRequestHandler.handle(CmsClusterRequestHandler.java:355) at org.opencms.main.OpenCmsServlet.invokeHandler(OpenCmsServlet.java:269) at org.opencms.main.OpenCmsServlet.doGet(OpenCmsServlet.java:149) at org.opencms.main.OpenCmsServlet.doPost(OpenCmsServlet.java:164) at javax.servlet.http.HttpServlet.service(HttpServlet.java:710) at javax.servlet.http.HttpServlet.service(HttpServlet.java:803) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:182) at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:262) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:446) at java.lang.Thread.run(Thread.java:595)
Solution
As reported by Alkacon OpenCms Support Team, JBoss may provide versions of BeanShell jars that collide with the provided (as for version 2.1) bsh-core-2.0b4.jar. Solution is to remove (or safely rename without a .jar extension) the mentioned bsh-core-2.0b4.jar file and restarting the servers.
Pricing
At the moment of this document (April 2009), the pricing for Alkacon's OCEE Package is as follows:
Type | Price with basic support | Price with medium support | Price with advanced support* |
---|---|---|---|
Alkacon OCEE Server Enhancement Package | 1.500€ | 2.500€ | 3.500€ |
Alkacon OCEE Cluster Package | 2.500€ | 3.500€ | 6.500€ |
For the best reference of what each type of OCEE package includes, and what each support includes, visit Alkacon's OCEE Page (see #External Links) or download this file.