-
Introduction
-
Changes from previous versions
-
Features
-
Scalability
-
Openess
-
Security
-
Load-balancing
-
Session handling
-
Fault tolerance
-
Manageability
-
Configuration
-
Internals
-
Load-balancing algorithm
-
Watchdog process
-
Shared memory
-
Internal state - Admistration
tasks
-
Large sites
-
Known problems
-
FAQ
-
Tips
-
Authors
1. Introduction
Scalability, load-balancing, fault-tolerance are key issues for internet
content providers : As the market becomes more mature, the need for static
pages websites decreases, and the dynamic content generation, personnalized,
and transactionnal becomes a must.
We strongly believe that Java is a key technology on the server
side, because of its rapid prototyping and validation phases, which give
a time-to-market bonus to those that are using it.
However, as the Java Virtual Machines become faster over years, people
tend to ask for always more personnalized and dynamic contents, and this
type of application requires always more and more CPU power.
Apache
JServ addresses this requirement and lets you distribute your application
load over as many hosts as needed.
At the same time, applications and user transactions are based on HTTP
sessions, and Apache JServ ensures
that the system will take care of them. Of course the whole system has
to be fault-tolerant.
And of course all for free ... ;-)
This document describes how to use Apache
JServ load-balancing and fault tolerance features.
Thank you for using Apache JServ.
2. Changes from previous versions
This is just a partial list, within our current scope.
1.1 Fixes security bugs present in all 1.0: a potential Denial of Service when using load-balancing !
1.1 Fixes numerous bugs present in all 1.0: a potential file descriptor leak when using load-balancing !
1.1 Offers enhanced configuration feedback on /jserv/ status page with load-balancing.
1.1 Contributed sh and perl scripts to allow immediate or graceful shutdown of JServs in shared memory (still experimental).
1.1 Load-balancing can work above ajpv11 AND the new ajpv12 at the same time.
1.1 Load-balancing can also work with URL rewritten Sessions Ids.
1.1 JServ is now bound to 1 IP address : Syntax: bindaddress=[ipaddress] or [localhost] (Default: localhost).
This is possibly a cause of non working installations.
1.1 JServ's default protocol is now ajpv12. (update your config files).
1.0, 1.1 Unix : Full Load balancing & fail-over support.
1.0, 1.1 Unix : Fail-over optimized support based on shared memory & internal watchdog process (using the appropriate ApJServShmFile directive).
1.0, 1.1 Win32 : Full Load balancing & basic fail-over support
1.0, 1.1 Win32 : Fail-over optimized support not supported.
1.0b3 and above use new configuration
parameters for load-balancing.
3. Features
3.1. Scalability
As the server side application are growing, it becomes more and more difficult
to use the 2 Tier model (Web Server + ServerAPI), or worse the CGI model.
Apache
JServ is a 100%Java multithreaded servlet engine which uses a n tier
model, and scales of course better. It is scalable from very little sites
(my home site is running on a Pentium 120 MHz w/48MB RAM, Apache + JServ
running /Linux), to very large sites running lots of powerful machines.
Between these 2 opposites, the Apache
JServ architecture lets you also choose between one 64-CPU machine,
and 64 low-cost PCs, with it's built-in load-balancing capabilities : It
can distribute the incoming load between lots of servlet engines.
The key is the use of AJP protocol, which is a socket based protocol,
and permits several hosts running the 2 parts : Apache+mod_jserv on one
side, the servlet engine on the other side.
Just as example : scalable from :
-
1 PC, running 1 Apache + 1 JServ (from 1 to z zones) (my home PC)
To (OK, let's take one realistic example) :
-
10 hosts running Apache. (load-balancing with round-robin DNS / or dedicated
hardware)
-
33+ JServs running on top of :
-
15 PC running Linux JDK1.2
-
5 Sun E450
-
10 PC NT JDK1.1.6
-
3 AS400
-
+ ... (What fits your needs)
3.1.1. Scaling Apache HTTP/HTTPS servers :
Every standard Apache server can start 1..256 httpd processes (This limit
can be increased at compilation time).
This means that one Apache server can serve at the same time a maximum
of 256 client requests.
For websites that have to serve thousands of concurrent request, there
is a need for running multiple occurences of the same server, and to use
a load-balancing mechanism to distribute the incoming load over the different
Apache instances.
The different instances of Apache server can be running on the same
host, each of them using a different IPaddr/TCP port couple, or on different
hosts.
The load-balancing mechanism can be either a simple round robin DNS,
either a dedicated hardware. This is a deployment decision, and doesn't
have impacts on Apache and JServ. We do not rely on this load-balancing
level for keeping care of our applicative sessions.
Some of these Apache servers can be SSL enabled, and SSL sessions have
of course to be maintained through the load-balancing system. Dedicated
hardwares usually take care of this.
As we can see our Apache servers as gateways for our JServ servlet
engines, we can easily imagine that all these apache servers will be seen
by clients as a "cluster" of hosts, with a unique hostname, and so will
always receive session cookies set for this "cluster" hostname. This will
allow keeping HTTP sessions over SSL/not SSL URLs.
We will see later that these different Apache servers have to share
a common knowledge about JServ identification (routing & TCP infos).
3.1.2. Scaling JServ servers :
Jserv is a 100% pure Java program, where every servlet is running in it's
own thread. With a very large number of concurrent requests, it seems reasonnable
to run multiple instances of JServ for the following reasons :
-
No JVM is today able of running thousands of (doing something really useful)
threads at the same time.
AFAIK.
-
Some Java classes have synchronized methods. Increasing the number of JServs
increases the parallelism.
-
Redundancy increases system safety. If one JVM crashes, or if one servlet
produces an System.exit(), or anything bad happens, others Apache JServ
will be still alive.
Servlet zones can be distributed on different JServs. This increases
security, as these Jservs can be started with different userid.
-
every JServ can be started with it's own CLASSPATH.
-
every JServ can be started with it's own JDK version, or JRE option (-nojit,
- verbosegc, ...).
One JServ is able to run on one 64*CPU machine, and any number (64, 128,
other) of JServs can run on 64 low-cost PCs.
And yes, you can run more than one JServ on one machine, as each of
them needs only a IPaddr/TCP port couple. Can be interesting for above
reasons.
We currently have one limit in the Apache plug-in (mod_jserv) for the
max number of JServs it can address. This limit is fixed at compile time
(can be increased), and is just here for reserving space in share memory.
(limit = 25 rigth now).
3.2. Openess
While Jserv is a 100% Java code, it can run on any system that has
a JVM. So you can have at the same time some of your JServs running on
top of OS/2, and others on Linux, Solaris, NT, ...
Apache itself can be running on a different hardware/Operating system,
and just sending request to JServs using Apache Java Protocol (AJP) over
TCP/IP.
Apache is known for running efficiently over freeware OSes like *BSD
or Linux.
3.3. Security
-
You can run Apache & JServ on same/different hosts with different userids
and rights.
-
You can separate different zones on different JServs.
-
JServ can be run behind a firewall (AJP protocol uses only one TCP port)
-
JServ uses an ACL and allows AJP requests only from ACL'ed hosts.
-
The communication can be authenticated with a secret key between Apache
& JServ.
-
Apache+SSLeay allows 128bits SSL encryption with https URLs.(between the
browser and the http server).
-
Server redundancy (duplicating both Apache & JServ) increases the service
availability.
-
Apache + JServ does not rely on any external component. There is no single
point of failure (SPF).
3.4 Load-balancing
-
Level 0 :
1 host with Apache, 1 host with JServ. The JServ is hosting all servlet
zones.
This is the current default mode for Apache JServ (no load-balancing).
JServ can be started in automatic mode.
-
Level 1 :
1 host with Apache, n hosts with JServ. Every JServ is hosting its
own servlet zone.This is a possible mode in 1.0 versions. You have to specify
one JServ/zone. Apache cannot start the different JServ in automatic mode
: you have to set the Manual mode to true.
-
Level 2 :
1 host with Apache, m*n hosts with JServ.
Every zone can have the incoming load distributed on several JServs.
You have to use the new "balance" parameters. (see Configuration).
For every zone you have to define a set of JServ hosts that are identical
(same servlet classes), and affect a logical weight for every host in that
set.
The traffic will be balanced between the JServs in the set, using a
simple but efficient algorithm based on host weight + random.
Every httpd process (inside one Apache server) will randomly(modulo
weight) choose a default target for each zone, and send new requests (sessions
not yet created) to this target. The underlying Operating system guaranties
(at least on U**xes) that equivalent processes gently share the CPU ressources,
and get elected at their turn.
-
Level 3 :
p*hosts with Apache, m*n hosts with JServ. Same as Level 2, but all
our p Apache servers have to use same configuration files to keep sessions
alive across all of them (really mandatory: use the same routing
parameters).
3.5. Session handling
Once established, a session is bound to one particular JServ. It is possible
to ensure that the next request (in the same http session) will be sent
to the right JServ, wherever the request came from (means : any Apache
used). Cookies are used to identify sessions, and cookies contains the
identifier of the JServ who did set it.
This ensures that sessions are fault-tolerant to Apache failure.
3.5.1 How sessions work
Sessions are based on session cookie set by servlets.
Every time a request comes for a balanced ServletMountPoint, mod_jserv
chooses (see algorithm above) which JServ will be used.
mod_jserv adds the cookie trailer (the ApJServRoute = eg: JS3 for PC3)
to the environment variables sent to JServ.
JServ appends this cookie trailer to the end of session cookie, before
sending it back to the client browser.
Next hit, some httpd (same host as precedent or not) will get the request,
examine headers, find the session cookie, determine which JServ owns
the cookie trailer, and then sendthe request to thez correct servlet engine.
If more than one server runs Apache for a given domain (round-robin
DNS), all the Apache MUST have the same routing parameters.
3.6 Fault tolerance
3.6.1 No single point of failure
If you have more than one Apache host, one of them can stop, and the system
will still work (modulo SSL sessions for https servers).
It is up to you to provide a load-balancing/fail-over mechanism (round-robin
DNS or dedicated hardware) to be able to use fail-over on Apache. (But
we ensure that user sessions will survive a Apache crash).
If you have more than one JServ host, one of them can stop, and the
system will still work. (modulo broken sessions).
Any Apache is able to route a request to any JServ. (session are
maintained, does not rely on any of the following elements : load-balancer
hardware, or Apache server).
As long as you have one Apache and one JServ running, the system can
work.
Fault-tolerance is implicit if load-balancing is enabled for this zone.
All our httpd processed share a memory zone, which contains the last
known status for every JServ.
As soon as a JServ is marked "unavailable" by one httpd process, the
information is accessible by other processes on the same host. This prevents
repetitive connect failures or even TCP connect timeouts.
The request & following requests will be redirected to others JServ
in the same "set" of JServs.
A watchdog program will run silently, and try to connect to this JServ
until success. Once succeeded, the JServ will be accessed again by httpd
processes.
The session is broken if a request is redirected to another JServ.
The existing one is considered invalid, as sessions can not travel across
the network (not in Servlet API specs).
3.6.2. Scenario 1: Apache fault-tolerance
We have 2 Apache servers on 2 different hosts.
1 - first step
a. Web client requests a page from www.jserv.com, port 80
b. www.jserv.com is a load-balancing system which actually resolves
the request to go to server Httpd server 111.222.333.10, port 3000.
c. The Apache Httpd server listening on 111.222.333.10, port 3000 chooses
(at random) a Jserv machine, 192.168.0.51, port 8885, to handle the request.
d. The Jserv machine at 192.168.0.51, port 8885 responds to the request
with the content of the page along with a cookie with name JServSessionID
and value "xxxx-JS1".
2 - second step
a. Web client requests another page from www.jserv.com, port 80
b. www.jserv.com resolves to 111.222.333.20, port 3000 (a different
machine from last hit time).
c. The Apache server recognizes the JServSessionID cookie and looks
at the Jserv identifier, "JS1" at the end of the cookie.
d. The Apache server sees that JS1 is the identifier for 192.168.0.51,
port 8885, and passes the request to that same server.
3.6.3. Scenario 2 : JServ load-balancing &
fault tolerance
1 - first step : JServ load-balancing
a. client A requests a servlet (A1)
b. the httpd server chooses a target JServ1 (A'1)
c. result: a cookie is set for JS1.
d. client B requests a servlet (B1)
e. the httpd server chooses a target JServ2 (B1')
f. result: a cookie is set for JS2.
2 - second step : session handling
a. client B requests a servlet (and send the previously set cookie
JS2) (B2)
b. the httpd server recognizes the cookie JS2
c. the request is passed to JServ2 (B2')
JServ1 now dies in a horrible death ...
3 - third step : JServ fault tolerance
a. client A requests a servlet (and send the previously set cookie
JS1) (A2).
b. the httpd server recognizes the cookie JS1.
c. the request is passed to JServ1, resulting in a failure (A2')
(the httpd process marks JServ1 "dead" in shared memory).
d. the http server finds a backup and sends the request to JServ3 (A2'')
e. result of A2'': If a session is needed, a new one is created and a cookie JS3 is set. (JS1 cookie erased).
3.7. Manageability
All information about JServ state is accessible and updatable in the shared
You can stop one of your JServs for maintenance reasons, without denying
access to your customers, as the requests will be sent to the other JServs
inside the set.
An administrator can update the status of one particular JServ in shared
memory, and mark it SHUTDOWN, so our httpd processes will notice it, and
redirect the incoming requests to other JServs.
Monitoring tasks can read the JServ status in shared memory, and send
reports. (can even be protected CGI programs).
4. Configuration
Nothing special to do on the Java side. NO new parameter in properties
file.
Administrator installs JServ and then chooses to use load-balancing
or not from the Apache side.
1 - defining hosts and routing parameters (in red)
Requests with cookies containing .JS2 will be routed to PC2 using protocol ajpv11
on port 8888 host 192.168.0.52.
NB: PC2 and PC3 are using ajpv11. PC1 and SPARK are using ajpv12.
Ajpv12 is the new (since v1.1) default protocol and using 2 protocols at the same time is maybe source of errors.
2 - defining hosts weight (in orange)
ApJServBalance set1
SPARK 4
Default weight is = 1. This one (SPARK) is a 4*CPU engine.
3 - defining set (here called set1) of equivalent JServs (in
green)
Set "set1" contains PC1 + PC2 + PC3 + SPARK
4 - defining load-balanced servlet mount point (in
blue)
Requests for /servlet will be load-balanced on set "set1".
SPARK should receive 4 times(average) more requests than others.
If one of the JServs fails; requests will be redirected to other members
in set "set1".
5 - defining the shared memory file (in pink)
Defines the path of the file that will be used as shared memory between
processes (needs read+write+create rights for the JServ's userid).
This can be an absolute or relative file path.
ApJServShmFile log/jserv_shm
<IfModule mod_jserv.c>
####################################################
#
Apache JServ Configuration File
#
####################################################
# Note: this file should be appended to httpd.conf
ApJServManual on
ApJServMount /oldservlet ajpv12://192.168.0.1:7777/zone2
// old style config
ApJServMount /servlet balance://set1/zone1
ApJServBalance set1 PC1
ApJServBalance set1 PC2
ApJServBalance set1 PC3
ApJServBalance set1 SPARK
4
ApJServHost PC1 ajpv12://192.168.0.51:7777
ApJServHost PC2 ajpv11://192.168.0.52:8888
ApJServHost PC3 ajpv11://192.168.0.53:9999
ApJServHost SPARK ajpv12://192.168.0.54:7777
ApJServRoute JS1 PC1
ApJServRoute JS2 PC2
ApJServRoute JS3 PC3
ApJServRoute sp1 SPARK
ApJServShmFile log/jserv_shm
ApJServSecretKey DISABLED
</IfModule>
5. Internal
5.1 Load-balancing algorithm
All the job is done by mod_jserv.
When Apache (re)starts, the configuration file (httpd.conf) is parsed.
For each set (of servlet engines), a circular list of engines is created.
Every engine is inserted exactly n times, where n is the weight as described
above.
In our example, the circular list contains :
PC1 - PC2 - PC3 - SPARK - SPARK - SPARK - SPARK
for each HTTP request coming for a balanced Servlet mount point:
do
if is the first HTTP request for a balanced Servlet mount point
then
process_mount_default_target = randomly chosen in set
endif
if a session cookie is found
then
the process finds the JServ which owns the session (using ApJServRoute parameters)
if the JServ is not dead/stopped (in shared memory)
then
the process sends the request to this JServ.
if the JServ replies
then
return
else
mark the JServ dead (in shared memory)
endif
endif
endif
# here we have either got a request without session cookie
# or a broken session. In this last case, we send te request
# to another target in the list without saying it to the client.
# (the application will have to notice the broken session anyway)
if process_target != process_mount_default_target AND
our process_mount_default_target is alive (in shared memory)
then
process_target = process_mount_default_target
endif
while (process_target exists)
do
if process_target is alive (in shared memory)
then
the process sends the request to this JServ.
if the JServ replies
then
return
else
mark the JServ dead (in shared memory)
endif
endif
process_target = next in set
done
done
5.2. Watchdog process
At Apache startup a process is created. This process is a httpd process,
which doesn't listen to HTTP requests. This process wakes up every 10
sec, reads the shared memory, and tries to connect to dead JServs. When
a dead JServ replies, it is marked running in shared memory.
while true
do
sleep(10)
if this process is not the default watchdog (in shared memory )
break
endif
for each JServ present in shared memory list
do
if JServ.state = down
connect JServ
if failed
continue
else
mark it alive in shared memory
endif
endif
done
done
5.3. Shared memory
It is used to communicate between httpd processes.
Every httpd process opens a regular file on the disk (open read+write),
and then mmaps it. This makes the file appear as regular memory.
As many processes can do the same at the same moment, modifications
in this memory zone are immediately seen by other processes.
This is a very convenient way to share information about server state
between httpd processes, and avoids a lot of infructuous connexions when
a JServ is down.
This shared memory can be read/written by any process (according to
file permissions), and we can just imagine CGI programs, SNMP proxies,
inetd started programs than can run and access this shared memory, mainly
for admistration/monitoring tasks.
The information stored in this shared memory is NOT MT-safe, not MP-safe
: accesses are NOT synchronized.
Why ? Well, the fault-tolerance part doesn't need it (really not).
This would be just annoying if we wanted to share counters (nb of hits
by example : the LB algorithm could use it to distribute the load, but
this would work only for 1 Apache/N JServs. Well, random+weight is not
a so bad choice, and easier to implement ;-)
This file is not human readable/writable. use a C/Perl program to access
it. (structure is in jserv.h).
6. Internal state - Admistration
tasks
Every JServ is described in shared memory. One parameter is the server
state. This state can be :
-
UP (internally '+') : means this JServ is running.
-
DOWN (internally '-') : means JServ doesn't answer. (Watchdog is allowed
to change the state back to UP)
-
SHUTDOWN_IMMEDIATE (internally 'X') : JServ is stopped by administator,
no traffic allowed.
-
SHUTDOWN_GRACEFUL (internally '/') : JServ is stopped by administrator,
no new traffic allowed, but existing sessions still allowed. (example:
will be stopped in 10 minutes).
Before an non urgent administration task, the administrator changes
the state from UP to SHUTDOWN_GRACEFUL, and then wait some minutes, before changing again the state to SHUTDOWN_IMMEDIATE and perform the task. How long should he wait is depending of your application.
Once set to SHUTDOWN*, the watchdog doen't attempt to reconnect and set it up again.
Before an urgent administration task, the administrator changes
the state from UP to SHUTDOWN_IMMEDIATE, and then performs the task. This ensures that no request
will be routed to this JServ.
If the web site has 10 Apache, he has to modify the shared memory file on each of them.
After performing an administration task, the administrator changes
the state from SHUTDOWN_IMMEDIATE to UP back.
How to read/modify the shared memory file ?
This file contains binary and readable datas. One needs a home-made program (write it in C, or Perl), maybe we'll provide one example later. emacs or vi, or even Win32 Notepad are not well suited for this task.
You have to write your own tool, if you want to access/modify this shared memory. It is not more complicated than reading a regular file, and you can use the src/modules/jserv/jserv_mmap.c as an example.
New ! scripts have been contributed (experimental, do it at your own risks) on the web site : search the FAQ (search key= "shared memory").
Thanks to Mark Cox.
New ! The internal state of every JServ is also displayed in the /jserv/ status page on your website : somewhere like http://localhost/jserv/ .
The status is present & updated in shared memory only after opening a connection on the servlet engine !
7. Large sites
It is possible to create very large sites with Apache+JServ without problems
and still no single point of failure. The basic idea is to create different sets
of JServs per Apache, rather than having n (number of JServs) possible choices for every Apache. This is just a limitation to the built-in load-balancing capabilities.
Let's say that Apache1 will have 5 JServs in its set : JServ1, JServ2,
JServ3, JServ4, JServ5.
Apache2 will have 5 other JServs in its own set (for the same zone):
JServ11, JServ12, JServ13, JServ14, JServ15.
We assume that you have a Round Robin DNS that distributes statically
the load for hostname www.jserv.org on 2 IP addresses PLUS a fail-over
equipment (some exist that can do both).
-
A client connects and obtains IP1 from the DNS for www.jserv.com.
-
The sequest is sent to Apache1.
-
Apache1 uses its load-balancing algorithm and chooses a JServ from its
set. (Let's say JServ1)
-
JServ1 sets a (JServSessionId=xxxx.JS1) cookie to the client's browser.
-
Following requests from this client, (session establihed) coming to Apache1
are routed to JServ1.
-
Apache1 dies.
-
Hopefully (thanks to our load-balancing equipment) the request comes on
Apache2.
-
The cookie is recognized (JServSessionId=xxxx.JS1) and Apache2 sends the
request to JServ1.
-
Every Apache never sends requests outside its own set, except for established
sessions.
####################################################
#
Apache JServ Configuration File
for Apache A
#
####################################################
# Note: this file should be appended to httpd.conf
ApJServManual on
ApJServMount /servlet balance://set1/zone1
# my own set of JServs for servlet zone "zone1"
ApJServBalance set1 JServ1
ApJServBalance set1 JServ2
ApJServBalance set1 JServ3
ApJServBalance set1 JServ4
ApJServBalance set1 JServ5
ApJServHost JServ1 ajpv12://192.168.0.51:7777
ApJServHost JServ2 ajpv12://192.168.0.52:8888
ApJServHost JServ3 ajpv12://192.168.0.53:9999
ApJServHost JServ4 ajpv12://192.168.0.54:7777
ApJServHost JServ5 ajpv12://192.168.0.55:7777
ApJServHost JServ11 ajpv12://192.168.0.61:7777
ApJServHost JServ12 ajpv12://192.168.0.62:7777
ApJServHost JServ13 ajpv12://192.168.0.63:7777
ApJServHost JServ14 ajpv12://192.168.0.64:7777
ApJServHost JServ15 ajpv12://192.168.0.65:7777
ApJServRoute JS1 JServ1
ApJServRoute JS2 JServ2
ApJServRoute JS3 JServ3
ApJServRoute JS4 JServ4
ApJServRoute JS5 JServ5
ApJServRoute JS11 JServ11
ApJServRoute JS11 JServ12
ApJServRoute JS11 JServ13
ApJServRoute JS11 JServ14
ApJServRoute JS11 JServ15
ApJServShmFile log/jserv_shm
ApJServSecretKey DISABLED
</IfModule>
####################################################
#
Apache JServ Configuration File
for Apache B
#
####################################################
# Note: this file should be appended to httpd.conf
ApJServManual on
ApJServMount /servlet balance://set1/zone1
# my own set of JServs for servlet zone "zone1"
ApJServBalance set1 JServ11
ApJServBalance set1 JServ12
ApJServBalance set1 JServ13
ApJServBalance set1 JServ14
ApJServBalance set1 JServ15
ApJServHost JServ1 ajpv12://192.168.0.51:7777
ApJServHost JServ2 ajpv12://192.168.0.52:8888
ApJServHost JServ3 ajpv12://192.168.0.53:9999
ApJServHost JServ4 ajpv12://192.168.0.54:7777
ApJServHost JServ5 ajpv12://192.168.0.55:7777
ApJServHost JServ11 ajpv12://192.168.0.61:7777
ApJServHost JServ12 ajpv12://192.168.0.62:7777
ApJServHost JServ13 ajpv12://192.168.0.63:7777
ApJServHost JServ14 ajpv12://192.168.0.64:7777
ApJServHost JServ15 ajpv12://192.168.0.65:7777
ApJServRoute JS1 JServ1
ApJServRoute JS2 JServ2
ApJServRoute JS3 JServ3
ApJServRoute JS4 JServ4
ApJServRoute JS5 JServ5
ApJServRoute JS11 JServ11
ApJServRoute JS11 JServ12
ApJServRoute JS11 JServ13
ApJServRoute JS11 JServ14
ApJServRoute JS11 JServ15
ApJServShmFile log/jserv_shm
ApJServSecretKey DISABLED
</IfModule>
8. Known problems
Avoid using big weights for servlet engines, as they are inserted exactly
this number of times in the set list. (weight=800 for a 2*400MHz CPU is
not a good idea).
The maximum number of active JServs is limited to 25. To increase it,
just increase the NB_MAX_JSERVS in jserv.h and recompile.
Oops ! forgot this one : The full functionnality is working on U**xes
(tested on Solaris/Linux). But the NT port is only partial : no watchdog
for the moment. Volunteers to work on this ?
Today we have load-balancing + but NO shared memory on NT.
The Watchdog process is created (forked) at server startup by the main
program (Unix only), so it inherits (too much IMHO) its characteristics : runs with
Apache's main process userid.
(must be root for TCP ports < 1024). This is potentially dangerous,
and even if exploits can be difficult to create (as this process does'nt
listen HTTP requests), it has to be fixed ASAP.
9. FAQ
Q: I can't understand how the load is distributed on different JServs.
A: How are the request dispatched to different httpd processes by the
system ? Every process has a preferred target, chosen randomly, and the
operating system dispatches requests to our processes. So, one can understand
this, but not predict where the next request will go !
Q: One of the JServs get twice the load of others
A: Yes, due to the randomly chosen target, some of the JServs can be
used as default more often.
In order to get a correct distribution, you need to run lots of httpd
processes. This is designed for big sites, so ...
Q: My ApJServShmFile is corrupted
A: Remove it. Start Apache.
10. Tips
Desactivating load-balancing
You can choose not to use load-balancing for part or all your system.
In the above configuration example we
had :
ApJServMount /svlet1 ajpv12://192.168.0.1:7777/sv
<<<<< this one is NOT load balanced
ApJServMount /servlet balance://set1/zone1
<<<<< this one IS.
using load-balancing without shared memory nor watchdog
It is possible to use load-balancing without shared memory & watchdog.
Just comment the ApJServShmFile
line
(from httpd.conf):
######ApJServShmFile log/jserv_shm
Still using the load-balancing
syntax :
ApJServMount /servlet balance://set1/zone1
.../...
and the shared memory will NOT be used between httpd processes, and
you'll get NO watchdog to detect JServs that get alive again.
Removing all load-balancing code
Just comment the line :
#define LOAD_BALANCE in src/modules/jserv/jserv.h
and recompile JServ+Apache :
make clean; make; make install
11. Authors
Bernard Bernstein <bernard@corp.talkcity.com>
Jean-Luc Rochat <jlrochat@jnix.com>
Copyright (c) 2000 The
Java Apache Project.
$Id: howto.load-balancing.html,v 1.0 1999/04/20 16:05:12
Jean-Luc
Rochat Exp $
All rights reserved.