Hide last authors
Thomas Mortagne 4.1 1 {{warning}}
Vincent Massol 28.2 2 This tutorial is a simple way to setup a XWiki clustering for testing purpose. There is many ways to setup JGroups depending on your need.
Thomas Mortagne 4.1 3 {{/warning}}
Thomas Mortagne 1.1 4
Thomas Mortagne 27.1 5 {{toc/}}
Thomas Mortagne 1.1 7 The goal of a cluster of XWiki instance is to provide several XWiki in different servers accessing the same database server to be able to do load balancing.
Thomas Mortagne 5.1 9 = Install two instances of XWiki on the same MySQL database =
Thomas Mortagne 1.1 10
11 Here we will use the XWiki standard distribution but instead of using the embedded hsqldb database we will use a MySql database. For this you need to:
Thomas Mortagne 4.1 13 * modify the ##hibernate.cfg.xml## file to change hsqldb configuration by a proper MySQL configuration
14 * copy your database driver JAR in WEB-INF/lib or in some shared lib directory
Vincent Massol 29.6 16 See [[the installation instructions>>xwiki:Documentation.AdminGuide.Installation]] for more details on how to install XWiki.
Thomas Mortagne 1.1 17
Thomas Mortagne 3.1 18 At this point you almost have a XWiki cluster: you have two instances of XWiki which are using the same datas. But there is a remaining "detail": the problem is that for performance reason XWiki is using lots of different caches which mean that even if one instance of XWiki modify a document it's possible the other XWiki instance will not see it and keep showing the document from its cache.
Thomas Mortagne 1.1 19
Thomas Mortagne 5.1 20 = Configure event distribution =
Thomas Mortagne 3.1 21
Jerome 3.2 22 To handle this we will use the network event distribution system. When anything happens in a XWiki instances it generate a local event which is used to update caches. Here we will make theses events send to other XWiki instances as well and emulate local events. This way all the code updating its cache each time something changed in a particular document for example will also be notified if it has been done by another instance of XWiki.
Thomas Mortagne 1.1 23
Thomas Mortagne 5.1 24 == Enable remote observation ==
Thomas Mortagne 1.1 25
26 First you need to enable remote observation system.
Thomas Mortagne 4.1 28 For this go to xwiki.properties file and set the property ##observation.remote.enabled## to ##true##.
Thomas Mortagne 1.1 29
Thomas Mortagne 5.1 30 == Set the channels ==
Thomas Mortagne 1.1 31
32 Then you need to indicate to remote observation manager which communications channels it should start when XWiki starts.
Thomas Mortagne 4.1 34 For this you need to list in property ##observation.remote.channels## the names of the channels.
Thomas Mortagne 1.1 35
Thomas Mortagne 26.1 36 Here we set ##udp## in both instances to use embedded JGroups udp.xml configuration file which auto discover cluster members. In general you should always start by looking at the example configurations files in jgroups jar. Most of them are even configurable with system properties so you don't even have to copy and modify them.
Thomas Mortagne 1.1 37
Thomas Mortagne 28.1 38 This tutorial is working with two instances on the same host but it's possible udp does not work if whatever router or switch behind the members of the cluster does not allow multicast. In that case you might want to try using ##tcp## instead (see tcp.xml in JGroups jar).
Thomas Mortagne 5.1 40 = Start XWiki instance on different ports =
Thomas Mortagne 1.1 41
42 For this tutorial we run two instance of XWiki in the same server. So we need each instance to use different ports.
44 To run a XWik instance if a custom port you can provide it in parameter of the script start_xwiki.sh.
46 Here we start the first instance with:
Thomas Mortagne 4.1 47
48 {{code}}
Vincent Massol 22.1 49 sh start_xwiki.sh -p 8080 -sp 8070
Thomas Mortagne 4.1 50 {{/code}}
Thomas Mortagne 1.1 51
52 and the second one with:
Thomas Mortagne 4.1 53
54 {{code}}
Vincent Massol 22.1 55 sh start_xwiki.sh -p 8081 -sp 8071
56 {{/code}}
58 {{info}}
59 On XWiki versions < 6.2, you should use:
61 {{code}}
62 sh start_xwiki.sh 8080 8070
63 {{/code}}
65 and
67 {{code}}
Thomas Mortagne 1.1 68 sh start_xwiki.sh 8081 8071
Thomas Mortagne 4.1 69 {{/code}}
Vincent Massol 22.1 70 {{/info}}
Thomas Mortagne 1.1 71
72 The second port is the port used to stop jetty server, it's not mandatory to run XWiki but it's better to have differents ports if you don't want to have to kill the java process instead of using the stop_xwiki.sh script ;)
Thomas Mortagne 5.1 73
Thomas Mortagne 16.1 74 Sometimes you have to force the bind address, you can do it using ##-Djgroups.bind_addr=localhost##
Thomas Mortagne 12.1 75
Jerome 7.1 76 = Check the clustering setup =
Thomas Mortagne 5.1 77
78 * Load a page in both instances
79 * Modify a page in one instance
80 * Reload it in the other instance
81 * It should have taken into account the modification made on the other instance
Jerome 7.1 82
83 = Add load balancing with apache2 ##mod_proxy_balancer## =
85 You probably want to do load-balancing in front of the clustered XWiki instances. This section provides sample configurations to do that.
Jerome 7.2 87 Replace if you have one your apache proxy configuration by the following one, or set it as proxy of your apache site configuration if you don't have one yet :
Jerome 7.1 88
Thomas Mortagne 20.1 89 {{code language="apacheconf"}}
Jerome 7.1 90 ProxyRequests Off
91 ProxyPreserveHost On
93 <Proxy balancer://mycluster>
94 BalancerMember ajp:// route=jvm1
95 BalancerMember ajp:// route=jvm2
96 ProxySet stickysession=JSESSIONID
97 </Proxy>
98 ProxyPass /xwiki balancer://mycluster/xwiki
99 {{/code}}
Paul Libbrecht 17.1 101 You need also to precise the name of the JVM route for each member of the balancer. On Tomcat, in ##conf/server.xml##, edit the ##Engine## node as follow :
Thomas Mortagne 21.1 102 {{code language="apacheconf"}} <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">{{/code}}
Jerome 7.1 103
Paul Libbrecht 17.1 104 On GlassFish and Tomcat and probably others, you can set the system property jvmRoute to the same value.
Jerome 7.1 106 Where you replace ##jvm1## by the name of the route you have precised in the Apache configuration.
Paul Libbrecht 17.1 108 This setting will complement the JSESSIONID with a suffix made by this jvmRoute: thus any session will contain the node name and this will instruct Apache to choose that route the next time a request comes. Thus, the browser will remain hooked to that server as long as the session remains.
110 == Testing the clustered setup ==
Thomas Mortagne 25.1 111
Jerome 7.1 112 To test the load-balancing setup, you can edit the ##version.properties## file of your wiki to add a suffix to be able to recognize each member of the cluster. For example ##version=2.6.33077-node1## for the first node of a cluster of XWiki 2.6 nodes. Then, connect to the wiki via the URL that points to the load-balancer with a first browser, and look at which node is being used. Just after connect with a second browser (to have a different session), and make sure the node used is the other one (since mod_proxy_rewrite affects balancing members sequentially.
Thomas Mortagne 8.1 113
Paul Libbrecht 17.1 114 You can also verify the JSESSIONID cookie value which will end with the route name.
Thomas Mortagne 8.1 115
Paul Libbrecht 17.1 116 Finally, to test that clustering works you can either:
118 * set-up a dedicated virtual host to each cluster node so that you can check that, for example, a changed document, is changed on every node
119 * force the route by adding the URL parameter JSESSIOND=jvm1: this will make sure that this route is used which, in turn, will set the cookie to a session-identifier suffixed with jvm1.
121 = Monitoring and Troubleshooting =
123 The error log of Apache reports an amount of details about the choice of load-balancing if the log-level is sufficient.
125 The balancer-manager is also precious:
Thomas Mortagne 21.1 127 {{code language="apacheconf"}}
Paul Libbrecht 17.1 128 <Location /balancer-manager>
129 SetHandler balancer-manager
130 AuthType digest
131 AuthName "XWiki Cluster Management"
132 AuthType Digest
133 AuthDigestDomain http://example.com
134 AuthDigestFile /path/to/file.htdigest
135 Require valid-user
136 </Location>
Paul Libbrecht 18.1 137 {{/code}}
Paul Libbrecht 17.1 138
139 Using this configuration, properly specialized, provides a small interface at /balancer-manager where you can see the cluster nodes which are active, their load, and where you can disable them to take them offline for a bit.
Vincent Massol 9.1 141 == Debugging ==
Thomas Mortagne 8.1 142
Vincent Massol 9.1 143 See [[Debugging Section>>extensions:Extension.Observation Module Remote#HDebugging]] in the Observation Reference documentation.
Paul Libbrecht 19.1 144
145 You can also easily include the following HTML to force your browser to change from one node of the cluster to the other. This is extremely important to verify that clustering works:
Thomas Mortagne 21.1 148 {{code language="html"}}
Paul Libbrecht 19.1 149 <a href="$doc.name"
150 onclick="d = new Date(); d.setDate(d.getDate()+7); document.cookie='JSESSIONID=xxx.$hostname; ' + d.toUTCString()" ##
151 >$hostname</a>
152 {{/code}}
154 (where you replace $hostname (twice) and $doc.name appropriately.

Get Connected