You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Kernel freak <ke...@gmail.com> on 2015/12/08 14:07:39 UTC

Creating another Tomcat copy in hot stand-by when original goes down.

Hello friends,

I am working on a Debian server in which I would like to setup 2 instances
of Apache tomcat which will be load balanced by an Apache HTTP server(Do I
require a http server? ). In-case one copy of Apache tomcat goes down, the
other one will automatically comes online.

While I was creating a configuration for one of our server, I know how to
relay requests based upon URL to Apache Tomcat, these are the 2 things I
don't know.

1) Will this work with https? Reason I ask is, there are many pages which
are served under https and the configuration which I have and shown below
seems to be calling with http instead of https.

2) How to trigger the 2nd copy of tomcat.

Here is what I have till  now in Apache web server :

// Below is the redirection for tomcat webapps.
<VirtualHost *:80>
ServerName www.domain_tomcat.de
ServerAlias domain_tomcat.de
ProxyRequests on
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>

// I was thinking instead of routing to maintenance.html, I would start the
other app, but that sounds quite hackish. I thought there might be a better
way.
 ErrorDocument 503 /maintenance.html
 ErrorDocument 404 /maintenance.html
 ErrorDocument 500 /maintenance.html

ProxyPass /maintenance.html !

// As you can see below, I am redirecting with http, which is my first
point, will it automatically redirect to https, as tomcat webapp is using
Spring-security and it has specific paths for which it must use https.
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/

<Location / >
Order allow,deny
Allow from all
</Location>
</VirtualHost>

My tomcat config is rather simple :


<Connector port="8080" proxyPort="80" redirectPort="443"
protocol="org.apache.coyote.http11.Http11NioProtocol" compression="force"
compressionMinSize="1024"
               connectionTimeout="20000"  maxPostSize="5242880"
               URIEncoding="utf-8"
 compressableMimeType="text/html,text/xml,text/plain,text/css,text/
javascript,application/x-javascript,application/javascript"/>


 <Connector port="443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
maxPostSize="5242880" SSLEnabled="true" maxThreads="200" compr$
              compressionMinSize="1024" scheme="https" secure="true"
clientAuth="false"  sslProtocol="TLS"
               keystoreFile="keystore.jks" keystorePass="PASSWORD"
URIEncoding="utf-8"
 compressableMimeType="text/html,text/xml,text/plain,text/css,text/
javascript,application/x-javascript,application/javascript"/>

I can setup a similar instance of Tomcat in another location if desired.
But how can I handle the switching between them when one goes down. Kindly
let me know. Thank you. :-)

Re: Creating another Tomcat copy in hot stand-by when original goes down.

Posted by "André Warnier (tomcat)" <aw...@ice-sa.com>.
On 08.12.2015 14:07, Kernel freak wrote:
> Hello friends,
>
> I am working on a Debian server in which I would like to setup 2 instances
> of Apache tomcat which will be load balanced by an Apache HTTP server(Do I
> require a http server? ). In-case one copy of Apache tomcat goes down, the
> other one will automatically comes online.
>
> While I was creating a configuration for one of our server, I know how to
> relay requests based upon URL to Apache Tomcat, these are the 2 things I
> don't know.
>
> 1) Will this work with https? Reason I ask is, there are many pages which
> are served under https and the configuration which I have and shown below
> seems to be calling with http instead of https.
>
> 2) How to trigger the 2nd copy of tomcat.
>
[snip]

Hi. To answer this "top-down" :

1) to do "load-balance" 2 tomcats, there are many ways, and you do not necessarily have to 
use Apache httpd as a front-end, there are other solutions.
But the Apache httpd solution is probably the easiest to set up, and it's free.

2) picture the following setup :

user browser <-- HTTP or HTTPS --> Apache httpd <-- HTTP/HTTPS/AJP --> tomcat1
                                     + Connector <-- HTTP/HTTPS/AJP --> tomcat2

tomcat1 and tomcat2 are always active, both.  You do not start one when the other fails.
They are normally both active, and they share the load (the httpd Connector does that for 
you).
If one tomcat fails, the Connector under Apache httpd will notice that, and will start 
forwarding the requests only to the still-working tomcat.
When the failed tomcat comes back on-line, the Connector notices again, and starts 
balancing the requests again to both tomcats.
If both tomcats fail, you get an error at the httpd level.

3) for the httpd-level "Connector" between httpd and tomcat, you have 3 choices :
    a) mod_proxy + mod_proxy_http
    b) mod_proxy + mod_proxy_ajp
    c) mod_jk
Each one of those can do load-balancing, but their configuration is different.

4) If Apache httpd and the tomcats communicate through a network that is considered as 
secure, then the most efficient configuration would be :

                 Connection A                       Connection B
user browser <-- HTTP or HTTPS --> Apache httpd <-- HTTP/AJP --> tomcat1
                                     + Connector <-- HTTP/AJP --> tomcat2

The usual way of describing this is "terminating HTTPS at the httpd level".
In other words, do not use HTTPS between httpd and tomcat (connection B), because it would 
unnecessarily force an additional encryption/decryption.
All the additional HTTPS information that may be needed at the tomcat level, to know that 
the original user connection with httpd (connection A) was under HTTPS, will be anyway 
forwarded by the Connector, to Tomcat (as HTTP request headers).
(So tomcat can always know if the original browser to httpd connection A was secure or not.)

5)
- The (mod_proxy + mod_proxy_http) Connector, forwards the original (HTTP/HTTPS) client 
requests to Tomcat, using the HTTP protocol (and format).
So at the receiving end, in Tomcat, you need a matching HTTP Connector.

- the (mod_proxy + mod_proxy_ajp) Connector, and the mod_jk Connector, forward the 
original (HTTP/HTTPS) client requests to Tomcat, using a protocol/format that is not HTTP, 
but which essentially carries the same information (it is the AJP protocol/format).
So at the receiving end you need a matching AJP Connector.

- when the request is received by Tomcat using either one of the Tomcat Connectors, it is 
the job of the Tomcat-side Connector to "translate" this request into an internal Tomcat 
"request object", which is always the same.  So from the point of view of your tomcat 
webapps, it does not matter through which Connector the request was received, it always 
looks the same.

- one difference between proxying through HTTP and proxying through AJP, is that the AJP 
protocol does not have a corresponding "AJPS" encrypted version.
In other words, you should probably not use either (mod_proxy + mod_proxy_ajp) or mod_jk, 
if your httpd and tomcats communicate over a non-secure channel (such as over an Internet 
connection). (You could still do that over an SSH tunnel, but that complicates things).

- another difference is that the AJP protocol can carry to tomcat, a user-id that has been 
authenticated at the httpd level.  The HTTP protocol does not do that by itself.
(In short, if you authenticate users at the httpd level, and want Tomcat to use this and 
avoid authenticating the user again, then use the AJP protocol).

Does this give you enough material to figure out the rest of your questions ?




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Creating another Tomcat copy in hot stand-by when original goes down.

Posted by Christopher Schultz <ch...@christopherschultz.net>.
Akshay,

On 12/9/15 5:33 AM, Kernel freak wrote:
> @Andre : Yes, the material is quite enough, I am using a AJP connector and
> as Spring-security automatically rewrites/redirects to https, that is not
> the problem I am having. The problem is that even if *one* Tomcat is going
> down, the whole setup is dying, Not the point of this task. I want to keep
> one alive and it should keep working.

>From your configuration, you were pretty clearly using mod_proxy_http,
so you weren't using AJP at all.

> @Chris : I have no option other then Apache httpd as I see it now, I have
> already configured some stuff, which I will be posting below. What I want
> is to load-balance between both the Tomcat's, but if one goes down, the
> other one should still work. I have already put the JSESSIONID(consumed by
> Spring-security), in the config. The problem I am having right now is that
> even if *one* tomcat goes down, then I get a 503, service not available.
> What am I doing wrong?

I don't know. Using mod_jk, if one node goes down the others pick-up the
slack. I have much less experience with mod_proxy_*.

> Also, is there any way to detect which Tomcat is being used by the user
> right now?

On which end? You want to check from the client end? If you look at the
session id, it will have the jvmroute in it, appended onto the end. Your
session id will be something like "37680235094857.node1".

> Here are the changes I made :
> 
> For apache2 in sites-enabled/000-default  :
> 
> 
> <Proxy balancer://mycluster>
>     BalancerMember ajp://localhost:8010 route=jvmroute-first
> connectiontimeout=10
>     BalancerMember http://localhost:8011 route=jvmroute-second
> connectiontimeout=10

Why are you using AJP for one connection and HTTP for the other? That's
going to get confusing.

>    ProxySet stickysession=JSESSIONID
> 
>    Order Deny,Allow
>    Deny from none
>    Allow from all
> 
> </Proxy>

Other than the protocol games, this looks good so far.

> <VirtualHost *:80>
> ProxyPass / balancer://mycluster/
> ProxyPassReverse / balancer://mycluster/
> </VirtualHost>
> 
> 
> 
> First Apache tomcat instance :
> 
> <Connector port="8080" proxyPort="80" protocol="HTTP/1.1"
> compression="force" compressionMinSize="1024"
>                connectionTimeout="20000"
>                redirectPort="443" URIEncoding="utf-8"
>  compressableMimeType="text/html,text/xml,text/plain,text/css,text/
> javascript,application/x-javascript,application/javascript"/>
> 
> 
> <Connector port="443" protocol="HTTP/1.1" SSLEnabled="true"
> maxThreads="200" compression="force"
>               compressionMinSize="1024" scheme="https" secure="true"
> clientAuth="false"  sslProtocol="TLS"
>                 keystoreFile="domain.keystore" keystorePass="password"
> URIEncoding="utf-8"
>  compressableMimeType="text/html,text/xml,text/plain,text/css,text/
> javascript,application/x-javascript,application/javascript"
> />
> Connector port="8010" protocol="AJP/1.3" redirectPort="443"
> URIEncoding="utf-8"
>  compressableMimeType="text/html,text/xml,text/plain,text/css,text/
> javascript,application/x-javascript,application/javascript"
> />
>   <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvmroute-first">
>  // No modifications inside
> </Engine>
> 
> Second tomcat instance :
> 
> <Connector port="8081" proxyPort="80" protocol="HTTP/1.1"
> compression="force" compressionMinSize="1024"
>                connectionTimeout="20000"
>                redirectPort="443" URIEncoding="utf-8"
>  compressableMimeType="text/html,text/xml,text/plain,text/css,text/
> javascript,application/x-javascript,application/javascript"/>
> 
> 
> <Connector port="443" protocol="HTTP/1.1" SSLEnabled="true"
> maxThreads="200" compression="force"
>               compressionMinSize="1024" scheme="https" secure="true"
> clientAuth="false"  sslProtocol="TLS"
>                 keystoreFile="keystore" keystorePass="password"
> URIEncoding="utf-8"
>  compressableMimeType="text/html,text/xml,text/plain,text/css,text/
> javascript,application/x-javascript,application/javascript"
> />
>   <Connector port="8011" protocol="AJP/1.3" redirectPort="443"
> URIEncoding="utf-8"
>  compressableMimeType="text/html,text/xml,text/plain,text/css,text/
> javascript,application/x-javascript,application/javascript"
> />
>     <Engine name="Catalina" defaultHost="localhost"
> jvmRoute="jvmroute-second">
>     // No modifications inside
>     </Engine>
> 
> So if I shut down one tomcat, then I cannot access the site. What is the
> mistake I am making. Kindly let me know. Thank you.

Consider configuring the balancer manager within httpd to see what's
going on:
http://httpd.apache.org/docs/current/mod/mod_proxy_balancer.html#balancer_manager

-chris


-chris

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Creating another Tomcat copy in hot stand-by when original goes down.

Posted by Kernel freak <ke...@gmail.com>.
Hi everyone,

@Andre : Yes, the material is quite enough, I am using a AJP connector and
as Spring-security automatically rewrites/redirects to https, that is not
the problem I am having. The problem is that even if *one* Tomcat is going
down, the whole setup is dying, Not the point of this task. I want to keep
one alive and it should keep working.

@Chris : I have no option other then Apache httpd as I see it now, I have
already configured some stuff, which I will be posting below. What I want
is to load-balance between both the Tomcat's, but if one goes down, the
other one should still work. I have already put the JSESSIONID(consumed by
Spring-security), in the config. The problem I am having right now is that
even if *one* tomcat goes down, then I get a 503, service not available.
What am I doing wrong?

Also, is there any way to detect which Tomcat is being used by the user
right now?

Here are the changes I made :


For apache2 in sites-enabled/000-default  :


<Proxy balancer://mycluster>
    BalancerMember ajp://localhost:8010 route=jvmroute-first
connectiontimeout=10
    BalancerMember http://localhost:8011 route=jvmroute-second
connectiontimeout=10

   ProxySet stickysession=JSESSIONID

   Order Deny,Allow
   Deny from none
   Allow from all

</Proxy>

<VirtualHost *:80>
ProxyPass / balancer://mycluster/
ProxyPassReverse / balancer://mycluster/
</VirtualHost>



First Apache tomcat instance :

<Connector port="8080" proxyPort="80" protocol="HTTP/1.1"
compression="force" compressionMinSize="1024"
               connectionTimeout="20000"
               redirectPort="443" URIEncoding="utf-8"
 compressableMimeType="text/html,text/xml,text/plain,text/css,text/
javascript,application/x-javascript,application/javascript"/>


<Connector port="443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="200" compression="force"
              compressionMinSize="1024" scheme="https" secure="true"
clientAuth="false"  sslProtocol="TLS"
                keystoreFile="domain.keystore" keystorePass="password"
URIEncoding="utf-8"
 compressableMimeType="text/html,text/xml,text/plain,text/css,text/
javascript,application/x-javascript,application/javascript"
/>
Connector port="8010" protocol="AJP/1.3" redirectPort="443"
URIEncoding="utf-8"
 compressableMimeType="text/html,text/xml,text/plain,text/css,text/
javascript,application/x-javascript,application/javascript"
/>
  <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvmroute-first">
 // No modifications inside
</Engine>

Second tomcat instance :

<Connector port="8081" proxyPort="80" protocol="HTTP/1.1"
compression="force" compressionMinSize="1024"
               connectionTimeout="20000"
               redirectPort="443" URIEncoding="utf-8"
 compressableMimeType="text/html,text/xml,text/plain,text/css,text/
javascript,application/x-javascript,application/javascript"/>


<Connector port="443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="200" compression="force"
              compressionMinSize="1024" scheme="https" secure="true"
clientAuth="false"  sslProtocol="TLS"
                keystoreFile="keystore" keystorePass="password"
URIEncoding="utf-8"
 compressableMimeType="text/html,text/xml,text/plain,text/css,text/
javascript,application/x-javascript,application/javascript"
/>
  <Connector port="8011" protocol="AJP/1.3" redirectPort="443"
URIEncoding="utf-8"
 compressableMimeType="text/html,text/xml,text/plain,text/css,text/
javascript,application/x-javascript,application/javascript"
/>
    <Engine name="Catalina" defaultHost="localhost"
jvmRoute="jvmroute-second">
    // No modifications inside
    </Engine>



So if I shut down one tomcat, then I cannot access the site. What is the
mistake I am making. Kindly let me know. Thank you.


On Wed, Dec 9, 2015 at 1:29 AM, Christopher Schultz <
chris@christopherschultz.net> wrote:

> Akshay,
>
> On 12/8/15 8:07 AM, Kernel freak wrote:
> > I am working on a Debian server in which I would like to setup 2
> instances
> > of Apache tomcat which will be load balanced by an Apache HTTP server(Do
> I
> > require a http server? ). In-case one copy of Apache tomcat goes down,
> the
> > other one will automatically comes online.
>
> You won't require Apache httpd, but you will need some kind of proxying
> server. Nginx and haproxy will work. Squid, Varnish, etc. will
> presumably all work as well. This community has expertise with Apache
> httpd -> Tomcat as well as some others. I personally have only ever used
> Apache httpd (and likely haproxy, though I don't actually know what AWS
> ELB is using. In either case, I don't configure it directly, so it
> doesn't matter).
>
> > While I was creating a configuration for one of our server, I know how to
> > relay requests based upon URL to Apache Tomcat, these are the 2 things I
> > don't know.
> >
> > 1) Will this work with https? Reason I ask is, there are many pages which
> > are served under https and the configuration which I have and shown below
> > seems to be calling with http instead of https.
> >
> > 2) How to trigger the 2nd copy of tomcat.
> >
> > Here is what I have till  now in Apache web server :
> >
> > // Below is the redirection for tomcat webapps.
> > <VirtualHost *:80>
> > ServerName www.domain_tomcat.de
> > ServerAlias domain_tomcat.de
> > ProxyRequests on
>
> I don't think you want this *at all*. "ProxyRequests" is for
> forward-proxying, like providing a MITM for outgoing HTTP traffic.
>
> > ProxyPreserveHost On
> > <Proxy *>
> > Order deny,allow
> > Allow from all
> > </Proxy>
> >
> > // I was thinking instead of routing to maintenance.html, I would start
> the
> > other app, but that sounds quite hackish. I thought there might be a
> better
> > way.
> >  ErrorDocument 503 /maintenance.html
> >  ErrorDocument 404 /maintenance.html
> >  ErrorDocument 500 /maintenance.html
> >
> > ProxyPass /maintenance.html !
> >
> > // As you can see below, I am redirecting with http, which is my first
> > point, will it automatically redirect to https, as tomcat webapp is using
> > Spring-security and it has specific paths for which it must use https.
> > ProxyPass / http://localhost:8080/
> > ProxyPassReverse / http://localhost:8080/
>
> If your VirtualHost supports HTTPS, then you can still use
> http://localhost:8080 as your target. You just need to make sure that
> you send-over all the appropriate headers to the back-end server, and
> enable the various Valves on the Tomcat side to handle the proxying of
> this information:
>
> http://tomcat.apache.org/tomcat-8.0-doc/config/valve.html#Proxies_Support
>
> > <Location / >
> > Order allow,deny
> > Allow from all
> > </Location>
> > </VirtualHost>
> >
> > My tomcat config is rather simple :
> >
> > <Connector port="8080" proxyPort="80" redirectPort="443"
> > protocol="org.apache.coyote.http11.Http11NioProtocol" compression="force"
> > compressionMinSize="1024"
> >                connectionTimeout="20000"  maxPostSize="5242880"
> >                URIEncoding="utf-8"
> >  compressableMimeType="text/html,text/xml,text/plain,text/css,text/
> > javascript,application/x-javascript,application/javascript"/>
> >
> >
> >  <Connector port="443"
> > protocol="org.apache.coyote.http11.Http11NioProtocol"
> > maxPostSize="5242880" SSLEnabled="true" maxThreads="200" compr$
> >               compressionMinSize="1024" scheme="https" secure="true"
> > clientAuth="false"  sslProtocol="TLS"
> >                keystoreFile="keystore.jks" keystorePass="PASSWORD"
> > URIEncoding="utf-8"
> >  compressableMimeType="text/html,text/xml,text/plain,text/css,text/
> > javascript,application/x-javascript,application/javascript"/>
> >
> > I can setup a similar instance of Tomcat in another location if desired.
> > But how can I handle the switching between them when one goes down.
> Kindly
> > let me know. Thank you. :-)
>
> Do you actually want a hot-standby, or do you want to load-balance
> amongst the servers that are available? Often, it's better to use both
> servers at once and have one of them take all of the load, than to
> completely switch from one to another.
>
> -chris
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>

Re: Creating another Tomcat copy in hot stand-by when original goes down.

Posted by Christopher Schultz <ch...@christopherschultz.net>.
Akshay,

On 12/8/15 8:07 AM, Kernel freak wrote:
> I am working on a Debian server in which I would like to setup 2 instances
> of Apache tomcat which will be load balanced by an Apache HTTP server(Do I
> require a http server? ). In-case one copy of Apache tomcat goes down, the
> other one will automatically comes online.

You won't require Apache httpd, but you will need some kind of proxying
server. Nginx and haproxy will work. Squid, Varnish, etc. will
presumably all work as well. This community has expertise with Apache
httpd -> Tomcat as well as some others. I personally have only ever used
Apache httpd (and likely haproxy, though I don't actually know what AWS
ELB is using. In either case, I don't configure it directly, so it
doesn't matter).

> While I was creating a configuration for one of our server, I know how to
> relay requests based upon URL to Apache Tomcat, these are the 2 things I
> don't know.
> 
> 1) Will this work with https? Reason I ask is, there are many pages which
> are served under https and the configuration which I have and shown below
> seems to be calling with http instead of https.
> 
> 2) How to trigger the 2nd copy of tomcat.
> 
> Here is what I have till  now in Apache web server :
> 
> // Below is the redirection for tomcat webapps.
> <VirtualHost *:80>
> ServerName www.domain_tomcat.de
> ServerAlias domain_tomcat.de
> ProxyRequests on

I don't think you want this *at all*. "ProxyRequests" is for
forward-proxying, like providing a MITM for outgoing HTTP traffic.

> ProxyPreserveHost On
> <Proxy *>
> Order deny,allow
> Allow from all
> </Proxy>
> 
> // I was thinking instead of routing to maintenance.html, I would start the
> other app, but that sounds quite hackish. I thought there might be a better
> way.
>  ErrorDocument 503 /maintenance.html
>  ErrorDocument 404 /maintenance.html
>  ErrorDocument 500 /maintenance.html
> 
> ProxyPass /maintenance.html !
> 
> // As you can see below, I am redirecting with http, which is my first
> point, will it automatically redirect to https, as tomcat webapp is using
> Spring-security and it has specific paths for which it must use https.
> ProxyPass / http://localhost:8080/
> ProxyPassReverse / http://localhost:8080/

If your VirtualHost supports HTTPS, then you can still use
http://localhost:8080 as your target. You just need to make sure that
you send-over all the appropriate headers to the back-end server, and
enable the various Valves on the Tomcat side to handle the proxying of
this information:

http://tomcat.apache.org/tomcat-8.0-doc/config/valve.html#Proxies_Support

> <Location / >
> Order allow,deny
> Allow from all
> </Location>
> </VirtualHost>
> 
> My tomcat config is rather simple :
> 
> <Connector port="8080" proxyPort="80" redirectPort="443"
> protocol="org.apache.coyote.http11.Http11NioProtocol" compression="force"
> compressionMinSize="1024"
>                connectionTimeout="20000"  maxPostSize="5242880"
>                URIEncoding="utf-8"
>  compressableMimeType="text/html,text/xml,text/plain,text/css,text/
> javascript,application/x-javascript,application/javascript"/>
> 
> 
>  <Connector port="443"
> protocol="org.apache.coyote.http11.Http11NioProtocol"
> maxPostSize="5242880" SSLEnabled="true" maxThreads="200" compr$
>               compressionMinSize="1024" scheme="https" secure="true"
> clientAuth="false"  sslProtocol="TLS"
>                keystoreFile="keystore.jks" keystorePass="PASSWORD"
> URIEncoding="utf-8"
>  compressableMimeType="text/html,text/xml,text/plain,text/css,text/
> javascript,application/x-javascript,application/javascript"/>
> 
> I can setup a similar instance of Tomcat in another location if desired.
> But how can I handle the switching between them when one goes down. Kindly
> let me know. Thank you. :-)

Do you actually want a hot-standby, or do you want to load-balance
amongst the servers that are available? Often, it's better to use both
servers at once and have one of them take all of the load, than to
completely switch from one to another.

-chris

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org