0

I have set up an Apache Tomcat Cluster with an Apache HTTP server and load balancing on CentOS 6.6 the following way:

+ 1 VM running HTTP server & 1 Tomcat instance (used for deployment, not answering requests)
+ 1 VM running 2 Tomcat instances on different ports


Important things first:
+ watchEnabled: on master = "true", on slaves = "false"
+ HTTP connector only for master node, not defined on slaves
+ port for AJP connector different on every instance
+ tcpListenerPort for NioReceiver different on every instance
+ jvmRoute value equals respective hostname on all instances
+ path to watchDir / tempDir different, deployDir = webapps on every instance
+ port for shutdown different on every instance
+ firewalld/iptables turned off on all nodes (testing environment)
+ YES, I have read lots of things about this topic (official documentation, tutorials, etc...) already.

server.xml (only the important part)

<Server port="8004" shutdown="SHUTDOWN"> <Service name="Catalina"> <!-- HTTP connector on port 8081 --> <Connector connectionTimeout="20000" port="8081" protocol="HTTP/1.1" redirectPort="8443"/> <!-- Define an AJP 1.3 Connector on port 8012 --> <Connector port="8012" protocol="AJP/1.3" redirectPort="8443"/> <!-- Engine definition for clustering --> <Engine defaultHost="localhost" jvmRoute="acd10-master" name="Catalina"> <Realm className="org.apache.catalina.realm.MemoryRealm"/> <Host appBase="webapps" autoDeploy="true" name="192.168.2.139" undeployOldVersions="true" unpackWARs="true"> <Cluster channelSendOptions="6" className="org.apache.catalina.ha.tcp.SimpleTcpCluster" useDirtyFlag="true"> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/> <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/> <Channel className="org.apache.catalina.tribes.group.GroupChannel"> <Membership address="228.0.0.4" className="org.apache.catalina.tribes.membership.McastService" dropTime="3000" frequency="500" port="45564"/> <Receiver address="auto" className="org.apache.catalina.tribes.transport.nio.NioReceiver" maxThreads="6" port="4005" timeout="100"/> <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> </Sender> <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/> <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/> <Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/> </Channel> <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" deployDir="/usr/local/tomcat7/webapps/" tempDir="/usr/local/tomcat7/war-temp/" watchDir="/usr/local/tomcat7/war-watch/" watchEnabled="true"/> </Cluster> </Host> </Engine> </Service> </Server> 



mod_proxy.conf

<VirtualHost *:80> DocumentRoot /var/www/html ProxyRequests Off ProxyPreserveHost On <Proxy *> Order deny,allow Allow from all </Proxy> <Proxy balancer://testcluster> BalancerMember ajp://192.168.2.166:8010/ route=acd11-node01 BalancerMember ajp://192.168.2.166:8011/ route=acd11-node02 ProxySet lbmethod=byrequests </Proxy> # Exclude balancer-manager app to make it available on master ProxyPass /balancer-manager ! ProxyPass / balancer://testcluster/ stickysession=JSESSIONID|jsessionid ProxyPassReverse / balancer://testcluster/ stickysession=JSESSIONID|jsessionid <Location /balancer-manager> SetHandler balancer-manager </Location> </VirtualHost> 



EDIT:

Apache error log (what it gives me after startup):

[Tue Jan 06 08:29:49.235859 2015] [mpm_prefork:notice] [pid 9655] AH00170: caught SIGWINCH, shutting down gracefully [Tue Jan 06 08:29:50.306520 2015] [core:notice] [pid 9727] SELinux policy enabled; httpd running as context system_u:system_r:httpd_t:s0 [Tue Jan 06 08:29:50.307867 2015] [suexec:notice] [pid 9727] AH01232: suEXEC mechanism enabled (wrapper: /usr/sbin/suexec) [Tue Jan 06 08:29:50.319218 2015] [so:warn] [pid 9727] AH01574: module proxy_module is already loaded, skipping [Tue Jan 06 08:29:50.319797 2015] [so:warn] [pid 9727] AH01574: module proxy_ajp_module is already loaded, skipping [Tue Jan 06 08:29:50.319827 2015] [so:warn] [pid 9727] AH01574: module proxy_balancer_module is already loaded, skipping [Tue Jan 06 08:29:50.320610 2015] [so:warn] [pid 9727] AH01574: module proxy_http_module is already loaded, skipping AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::50a0:e2ff:fe74:5294. Set the 'ServerName' directive globally to suppress this message [Tue Jan 06 08:29:50.328101 2015] [auth_digest:notice] [pid 9727] AH01757: generating secret for digest authentication ... [Tue Jan 06 08:29:50.329387 2015] [lbmethod_heartbeat:notice] [pid 9727] AH02282: No slotmem from mod_heartmonitor [Tue Jan 06 08:29:50.333216 2015] [mpm_prefork:notice] [pid 9727] AH00163: Apache/2.4.6 (CentOS) configured -- resuming normal operations [Tue Jan 06 08:29:50.333263 2015] [core:notice] [pid 9727] AH00094: Command line: '/usr/sbin/httpd -D FOREGROUND' 



What I try to achieve:
We have many enterprise web applications which we wanna load balance throughout a Tomcat farm.


What does work:
+ Tomcat clustering
+ Replication
+ FarmWarDeployer


What doesn't work:
Whenever I try to call an application that's been deployed throughout the cluster, it gives me 404 not found. Same for Tomcat root applications such as /manager/html or /host-manager. Only application that is working is /balancer-manager, obviously.

The httpd server is supposed to serve as a load balancer and proxy to the tomcats. It will have to deliver some static content but first and foremost, I need to get this thing up and running to load balance the JavaEE applications (servlets). AJP to the cluster nodes is a must have for me, since http access must not be allow (+ for some other reasons that are worth a totally different discussion).

Since everybody seems to set up the mod_proxy configuration in a different manner, I am looking for a straight forward solution that gives me something I can build on. If you need more information or more configuration details, let me know and I will provide you with those. I already have a second cluster configured using mod_jk and everything is working as intended, but the Stakeholders require this mod_proxy(_ajp) thing and it just grinds my gears.


Your help is much appreciated!

Best regards!

10
  • Is the 404 from Tomcat or Apache? Commented Jan 6, 2015 at 2:43
  • From Apache, it's shown in the HTTP request. Commented Jan 6, 2015 at 5:32
  • What is in your Apache error log? Commented Jan 6, 2015 at 16:18
  • Also, just to be sure - the web app does not redirect to https right? As that could give you a problem with the config above. Commented Jan 6, 2015 at 16:19
  • In your config above, your AJP connector is using port 8012. Your apache config points to 8011 and 8010. Another typo? Commented Jan 6, 2015 at 16:21

1 Answer 1

0

I haven't tried reproducing your configuration but when I looked at it this morning, it looks like the problem is simply a missing space and possibly the ProxyPassReverse not matching the ProxyPass (however the later wouldn't give you a 404 I think).

ProxyPass / balancer://testcluster/stickysession=JSESSIONID|jsessionid

ProxyPassReverse / balancer://testcluster/

should be:

ProxyPass / balancer://testcluster/ stickysession=JSESSIONID|jsessionid

ProxyPassReverse / balancer://testcluster/ stickysession=JSESSIONID|jsessionid

At least, that's how I have mine and I have no issue (but I don't use AJP, just regular http proxy).

Obviously this is assuming all the basic stuff are in place (site enabled, reload, http proxy mod installed and enabled, etc).

1
  • Thanks for your response. Unfortunately, this was just a typo in the post, original file looks good (regarding the missing space). Added stickysession=JSESSIONID|jsessionid to the PassProxyReverse, doesn't change anything. What I did find out tho is that if I call http://httpd_host:8081/manager/html, this gives me the manager app on the master node, but I don't want to type in the port number everytime. Still, if I call http://httpd_host:8081/app_context/app_url_pattern it gives me the app on the master node, but this node should not answer requests at all, and w/o a port it doesn't work Commented Jan 6, 2015 at 16:13

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.