# How to : Scalability - Load-Balancing - Fault tolerance

# with Apache JServ 1.1

#### document version: 1.2.1 (03 Feb 2000)

### Summary

1. Introduction
2. Changes from previous versions
3. Features

1. Scalability

- Apache Scalability
- JServ Scalability

2. Openess
3. Security
4. Load-balancing
5. Session handling

- How sessions work

6. Fault tolerance

- No Single point of failure
- Apache fault tolerance
- JServ fault tolerance

7. Manageability

4. Configuration
5. Internals

1. Load-balancing algorithm
2. Watchdog process
3. Shared memory

6. Internal state - Admistration tasks
7. Large sites
8. Known problems
9. FAQ
10. Tips
11. 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.