File: howto.load-balancing.html

package info (click to toggle)
jserv 1.1.2-2
  • links: PTS
  • area: contrib
  • in suites: woody
  • size: 4,584 kB
  • ctags: 3,019
  • sloc: sh: 7,715; java: 6,635; ansic: 5,013; makefile: 814; perl: 39; xml: 32
file content (944 lines) | stat: -rw-r--r-- 44,981 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
   <meta name="Author" content="Jean-Luc Rochat">
   <meta name="GENERATOR" content="vi">
   <title>How to : Scalability - Load-Balancing - Fault-tolerance with Apache JServ 1.1</title>
</head>
<body bgcolor="#FFFFFF">

<p align="center"><a href="http://java.apache.org/" target="_top"><img SRC="images/java-apache-project.gif" BORDER="0" WIDTH="609"
HEIGHT="100" ALT="The Java Apache Project"></a></p>

<center>
<h1>
How to : Scalability - Load-Balancing - Fault tolerance</h1></center>

<center>
<h1>
with <a href="http://java.apache.org">Apache JServ</a> 1.1</h1></center>

<p><br>
<h4>
document version: 1.2.1 (03 Feb 2000)</h4>

<h3>
Summary</h3>

<ol>
<li>
<a href="#Introduction">Introduction</a></li>

<li>
<a href="#Changes from previous versions">Changes from previous versions</a></li>

<li>
<a href="#Features">Features</a></li>

<ol>
<li>
<a href="#Scalability">Scalability</a></li>

<ul>
<li>
<a href="#Apache">Apache Scalability</a></li>

<li>
<a href="#JServ">JServ Scalability</a></li>
</ul>

<li>
<a href="#Openess">Openess</a></li>

<li>
<a href="#Security">Security</a></li>

<li>
<a href="#balancing">Load-balancing</a></li>

<li>
<a href="#Session">Session handling</a></li>

<ul>
<li>
<a href="#Howsessionswork">How sessions work</a></li>
</ul>

<li>
<a href="#Faulttolerance">Fault tolerance</a></li>

<ul>
<li>
<a href="#noSPF">No Single point of failure</a></li>

<li>
<a href="#Scenario1">Apache fault tolerance</a></li>

<li>
<a href="#Scenario2">JServ fault tolerance</a></li>
</ul>

<li>
<a href="#Manageability">Manageability</a></li>
</ol>

<li>
<a href="#Configuration">Configuration</a></li>

<li>
<a href="#Internal">Internals</a></li>

<ol>
<li>
<a href="#Internal">Load-balancing algorithm</a></li>

<li>
<a href="#Watchdogprocess">Watchdog process</a></li>

<li>
<a href="#Sharedmemory">Shared memory</a></li>
</ol>

<li>
<a href="#Internalstate - Admistration tasks">Internal state - Admistration
tasks</a></li>

<li>
<a href="#Largesites">Large sites</a></li>

<li>
<a href="#Knownproblems">Known problems</a></li>

<li>
<a href="#FAQ">FAQ</a></li>

<li>
<a href="#Tips">Tips</a></li>

<li>
<a href="#Authors">Authors</a></li>

<br></NL>
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<h2>
<a NAME="Introduction"></a>1. Introduction</h2>
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.
<br>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.
<p>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.
<a href="http://java.apache.org">Apache
JServ</a> addresses this requirement and lets you distribute your application
load over as many hosts as needed.
<p>At the same time, applications and user transactions are based on HTTP
sessions, and <a href="http://java.apache.org">Apache JServ</a> ensures
that the system will take care of them. Of course the whole system has
to be fault-tolerant.
<p>And of course all for free ... ;-)
<p>This document describes how to use <a href="http://java.apache.org">Apache
JServ</a> load-balancing and fault tolerance features.
<p>Thank you for using <a href="http://java.apache.org">Apache JServ</a>.
<br>&nbsp;
<br>&nbsp;
<h2>
<a NAME="Changes from previous versions"></a>2. Changes from previous versions</h2>
<br>This is just a partial list, within our current scope.
<br>1.1 Fixes security bugs present in all 1.0: a potential Denial of Service when using load-balancing !
<br>1.1 Fixes numerous bugs present in all 1.0: a potential file descriptor leak when using load-balancing !
<br>1.1 Offers enhanced configuration feedback on /jserv/ status page with load-balancing.
<br>1.1 Contributed sh and perl scripts to allow immediate or graceful shutdown of JServs in shared memory (still experimental).
<br>1.1 Load-balancing can work above ajpv11 AND the new ajpv12 at the same time.
<br>1.1 Load-balancing can also work with URL rewritten Sessions Ids.
<br>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.
<br>1.1 JServ's default protocol is now ajpv12. (update your config files).
<br>1.0, 1.1 Unix : Full Load balancing & fail-over support.
<br>1.0, 1.1 Unix : Fail-over optimized support based on shared memory & internal watchdog process (using the appropriate <a href="#Configuration">ApJServShmFile</a> directive).
<br>1.0, 1.1 Win32 : Full Load balancing & basic fail-over support
<br>1.0, 1.1 Win32 : Fail-over optimized support not supported.
<br>1.0b3 and above use new <a href="#Configuration">configuration</a>
parameters for load-balancing.
<br>&nbsp;
<h2>
<a NAME="Features"></a>3. Features</h2>

<ul>
<h3>
<a NAME="Scalability"></a>3.1. Scalability</h3>
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.
<a href="http://java.apache.org">Apache
JServ</a> 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.
<br>Between these 2 opposites, the <a href="http://java.apache.org">Apache
JServ</a> 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.
<br>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.
<p>Just as example : scalable from :
<ul>
<li>
1 PC, running 1 Apache + 1 JServ (from 1 to z zones) (my home PC)</li>
</ul>

<p><br>To (OK, let's take one realistic example) :
<br>&nbsp;
<ul>
<li>
10 hosts running Apache. (load-balancing with round-robin DNS / or dedicated
hardware)</li>

<li>
33+ JServs running on top of :</li>

<ul>
<li>
15 PC running Linux JDK1.2</li>

<li>
5 Sun E450</li>

<li>
10 PC NT JDK1.1.6</li>

<li>
3 AS400</li>

<li>
+ ... (What fits your needs)</li>
</ul>
</ul>

<h4>
<a NAME="Apache"></a>3.1.1. Scaling Apache HTTP/HTTPS servers :</h4>
Every standard Apache server can start 1..256 httpd processes (This limit
can be increased at compilation time).
<br>This means that one Apache server can serve at the same time a maximum
of 256 client requests.
<br>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.
<br>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.
<br>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.
<br>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.
<br>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.
<br>We will see later that these different Apache servers have to share
a common knowledge about JServ identification (routing &amp; TCP infos).
<br>&nbsp;
<h4>
<a NAME="JServ"></a>3.1.2. Scaling JServ servers :</h4>
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 :
<ul>
<li>
No JVM is today able of running thousands of (doing something really useful)
threads at the same time.</li>

<br>AFAIK.
<li>
Some Java classes have synchronized methods. Increasing the number of JServs
increases the parallelism.</li>

<li>
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.</li>
</ul>

<p><br>Servlet zones can be distributed on different JServs. This increases
security, as these Jservs can be started with different userid.
<ul>
<li>
every JServ can be started with it's own CLASSPATH.</li>

<li>
every JServ can be started with it's own JDK version, or JRE option (-nojit,
- verbosegc, ...).</li>
</ul>
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.
<br>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.
<br>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).
<br>&nbsp;
<h3>
<a NAME="Openess"></a>3.2. Openess</h3>
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, ...
<br>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.
<br>Apache is known for running efficiently over freeware OSes like *BSD
or Linux.
<br>&nbsp;
<h3>
<a NAME="Security"></a>3.3. Security</h3>

<ul>
<li>
You can run Apache &amp; JServ on same/different hosts with different userids
and rights.</li>

<li>
You can separate different zones on different JServs.</li>

<li>
JServ can be run behind a firewall (AJP protocol uses only one TCP port)</li>

<li>
JServ uses an ACL and allows AJP requests only from ACL'ed hosts.</li>

<li>
The communication can be authenticated with a secret key between Apache
&amp; JServ.</li>

<li>
Apache+SSLeay allows 128bits SSL encryption with https URLs.(between the
browser and the http server).</li>

<li>
Server redundancy (duplicating both Apache &amp; JServ) increases the service
availability.</li>

<li>
Apache + JServ does not rely on any external component. There is no single
point of failure (SPF).</li>
</ul>

<br>&nbsp;
<br>&nbsp;
<h3>
<a NAME="balancing"></a>3.4 Load-balancing</h3>

<ul>
<li>
Level 0 :</li>

<br>1 host with Apache, 1 host with JServ. The JServ is hosting all servlet
zones.
<br>This is the current default mode for Apache JServ (no load-balancing).
JServ can be started in <b>automatic</b> mode.
<li>
Level 1 :</li>

<br>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.
<li>
Level 2 :</li>

<br>1 host with Apache, m*n hosts with JServ.
<br>Every zone can have the incoming load distributed on several JServs.
You have to use the new "<b>balance</b>" parameters. (see <a href="#Configuration">Configuration</a>).
<br>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.
<br>The traffic will be balanced between the JServs in the set, using a
simple but efficient algorithm based on host weight + random.
<br>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.
<li>
Level 3 :</li>

<br>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 <a href="#Configuration">routing</a>
parameters).</ul>

<br>&nbsp;
<h3>
<a NAME="Session"></a>3.5. Session handling</h3>
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.
<br>This ensures that sessions are fault-tolerant to Apache failure.
<h4>
<a NAME="Howsessionswork"></a>3.5.1 How sessions work</h4>
Sessions are based on session cookie set by servlets.
<br>Every time a request comes for a balanced ServletMountPoint, mod_jserv
chooses (see algorithm above) which JServ will be used.
<br>mod_jserv adds the cookie trailer (the ApJServRoute = eg: JS3 for PC3)
to the environment variables sent to JServ.
<br>JServ appends this cookie trailer to the end of session cookie, before
sending it back to the client browser.
<br>Next hit, some httpd (same host as precedent or not) will get the request,
examine headers, find the session cookie,&nbsp; determine which JServ owns
the cookie trailer, and then sendthe request to thez correct servlet engine.
<br>If more than one server runs Apache for a given domain (round-robin
DNS), all the Apache MUST have the same routing parameters.
<br>&nbsp;
<h3>
<a NAME="Faulttolerance"></a><b>3.6 Fault tolerance</b></h3>

<h4>
<a NAME="noSPF"></a>3.6.1 No single point of failure</h4>
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).
<br>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).
<p>If you have more than one JServ host, one of them can stop, and the
system will still work. (modulo broken sessions).
<p>Any Apache is able to route a request to any JServ. (session are&nbsp;
maintained, does not rely on any of the following elements : load-balancer
hardware, or Apache server).
<br>As long as you have one Apache and one JServ running, the system can
work.
<p>Fault-tolerance is implicit if load-balancing is enabled for this zone.
<br>All our httpd processed share a memory zone, which contains the last
known status for every JServ.
<br>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.
<br>The request &amp; following requests will be redirected to others JServ
in the same "set" of JServs.
<br>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.
<br>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).
<br>&nbsp;
<h4>
<a NAME="Scenario1"></a>3.6.2. Scenario 1: Apache fault-tolerance</h4>

<p><br>We have 2 Apache servers on 2 different hosts.
<br><b>1 - first step</b>
<br>a. Web client requests a page from www.jserv.com, port 80
<br>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.
<br>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.
<br>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".
<p><b>2 - second step</b>
<br>a. Web client requests another page from www.jserv.com, port 80
<br>b. www.jserv.com resolves to 111.222.333.20, port 3000 (a different
machine from last hit time).
<br>c. The Apache server recognizes the JServSessionID cookie and looks
at the Jserv identifier, "JS1" at the end of the cookie.
<br>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.
<br>&nbsp;
<br>&nbsp;</ul>
<img SRC="images/lbprod001.gif" height=480 width=640>
<ul>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<h4>
<a NAME="Scenario2"></a>3.6.3. Scenario 2 : JServ load-balancing &amp;
fault tolerance</h4>
<b>1 - first step : JServ</b> <b>load-balancing</b>
<br>a. client A requests a servlet (A1)
<br>b. the httpd server chooses a target JServ1 (A'1)
<br>c. result: a cookie is set for JS1.
<br>d. client B requests a servlet (B1)
<br>e. the httpd server chooses a target JServ2 (B1')
<br>f. result: a cookie is set for JS2.</ul>
<img SRC="images/lbfail001.gif" height=480 width=640>
<ul><b>2 - second step : session handling</b>
<br>a. client B requests a servlet (and send the previously set cookie
JS2) (B2)
<br>b. the httpd server recognizes the cookie JS2
<br>c. the request is passed to JServ2 (B2')</ul>

<p><br><img SRC="images/lbfail002.gif" height=480 width=640>
<ul>JServ1 now dies in a horrible death ...
<p><b>3 - third step : JServ fault tolerance</b>
<br>a. client A requests a servlet (and send the previously set cookie
JS1) (A2).
<br>b. the httpd server recognizes the cookie JS1.
<br>c. the request is passed to JServ1, resulting in a failure (A2')
<br>&nbsp; (the httpd process marks JServ1 "dead" in shared memory).
<br>d. the http server finds a backup and sends the request to JServ3 (A2'')
<br>e. result of A2'': If a session is needed, a new one is created and a cookie JS3 is set. (JS1 cookie erased).
<br>&nbsp;
<br>&nbsp;</ul>
<img SRC="images/lbfail003.gif" height=480 width=640>
<ul>&nbsp;
<br>&nbsp;
<h3>
<a NAME="Manageability"></a>3.7. Manageability</h3>
All information about JServ state is accessible and updatable in the shared
<br>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.
<br>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.
<br>Monitoring tasks can read the JServ status in shared memory, and send
reports. (can even be protected CGI programs).
<br>&nbsp;
<br>&nbsp;
</ul>
<h3>
<a NAME="Configuration"></a>4. Configuration
</h3>
<p><b>Nothing special to do on the Java side. NO new parameter in properties
file.</b>
<br><b>Administrator installs JServ and then chooses to use load-balancing
or not from the Apache side.</b>
<br>&nbsp;
<h4>
1 - defining hosts and routing parameters (<font color="#FF0000">in red</font>)</h4>
Requests with cookies containing .JS2 will be routed to PC2 using protocol ajpv11
on port 8888 host 192.168.0.52.<br> NB: PC2 and PC3 are using ajpv11. PC1 and SPARK are using ajpv12.
<br>Ajpv12 is the new (since v1.1) default protocol and using 2 protocols at the same time is maybe source of errors.
<br>&nbsp;
<h4>
2 - defining hosts weight (<font color="#FF6600">in orange</font>)</h4>

<p><br><i><font size=-1><font color="#000000">ApJServBalance set1&nbsp;
SPARK </font><font color="#FF6600">4</font></font></i>
<p>Default weight is = 1. This one (SPARK) is a 4*CPU engine.
<br>&nbsp;
<h4>
3 - defining set (here called set1) of equivalent JServs (<font color="#006600">in
green</font>)</h4>
Set "set1" contains PC1 + PC2 + PC3 + SPARK
<br>&nbsp;
<h4>
4 - defining load-balanced servlet mount point (<font color="#3333FF">in
blue</font>)</h4>
Requests for /servlet will be load-balanced on set "set1".
<br>SPARK should receive 4 times(average) more requests than others.
<p>If one of the JServs fails; requests will be redirected to other members
in set "set1".
<br>&nbsp;
<h4>
5 - defining the shared memory file (<font color="#CC33CC">in pink</font><font color="#000000">)</font></h4>
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).
<br>This can be an absolute or relative file path.
<p><i><font color="#CC33CC"><font size=-1>ApJServShmFile log/jserv_shm</font></font></i>
<br>&nbsp;
<p><i><font size=-1>&lt;IfModule mod_jserv.c></font></i>
<br><i><font size=-1>####################################################</font></i>
<br><i><font size=-1>#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<a href="http://java.apache.org">Apache JServ</a> Configuration File&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
#</font></i>
<br><i><font size=-1>####################################################</font></i>
<br><i><font size=-1># Note: this file should be appended to httpd.conf</font></i>
<br><i><font size=-1>ApJServManual on</font></i>
<p><i><font size=-1>ApJServMount /oldservlet ajpv12://192.168.0.1:7777/zone2</font></i>&nbsp;&nbsp;
// old style config
<p><i><font color="#3366FF"><font size=-1>ApJServMount /servlet balance://set1/zone1</font></font></i>
<p><i><font color="#006600"><font size=-1>ApJServBalance set1&nbsp; PC1</font></font></i>
<br><i><font color="#006600"><font size=-1>ApJServBalance set1&nbsp; PC2</font></font></i>
<br><i><font color="#006600"><font size=-1>ApJServBalance set1&nbsp; PC3</font></font></i>
<br><i><font size=-1><font color="#006600">ApJServBalance set1&nbsp; SPARK
</font><font color="#FF6600">4</font></font></i>
<p><i><font color="#CC0000"><font size=-1>ApJServHost PC1 ajpv12://192.168.0.51:7777</font></font></i>
<br><i><font color="#CC0000"><font size=-1>ApJServHost PC2 ajpv11://192.168.0.52:8888</font></font></i>
<br><i><font color="#CC0000"><font size=-1>ApJServHost PC3 ajpv11://192.168.0.53:9999</font></font></i>
<br><i><font color="#CC0000"><font size=-1>ApJServHost SPARK ajpv12://192.168.0.54:7777</font></font></i>
<p><i><font color="#CC0000"><font size=-1>ApJServRoute JS1 PC1</font></font></i>
<br><i><font color="#CC0000"><font size=-1>ApJServRoute JS2 PC2</font></font></i>
<br><i><font color="#CC0000"><font size=-1>ApJServRoute JS3 PC3</font></font></i>
<br><i><font color="#CC0000"><font size=-1>ApJServRoute sp1&nbsp; SPARK</font></font></i>
<p><i><font color="#CC33CC"><font size=-1>ApJServShmFile log/jserv_shm</font></font></i>
<p><i><font size=-1>ApJServSecretKey DISABLED</font></i>
<br><i><font size=-1>&lt;/IfModule></font></i>
<br>&nbsp;
<h3>
<a NAME="Internal"></a>5. Internal</h3>

<h4>
<a NAME="Sharedmemory"></a>5.1 Load-balancing algorithm</h4>
All the job is done by mod_jserv.
<p>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.
<br>In our example, the circular list contains :
<br>PC1 - PC2 - PC3 - SPARK - SPARK - SPARK - SPARK
<br>&nbsp;
<pre>for each HTTP request coming for a balanced Servlet mount point:
do

&nbsp;&nbsp;&nbsp; if is the first HTTP request for a balanced Servlet mount point
&nbsp;&nbsp;&nbsp; then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; process_mount_default_target = randomly chosen in set
&nbsp;&nbsp;&nbsp; endif

&nbsp;&nbsp;&nbsp; if a session cookie is found
&nbsp;&nbsp;&nbsp; then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the process finds the JServ which owns the session (using ApJServRoute parameters)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if the JServ is not dead/stopped (in shared memory)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the process sends the request to this JServ.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if the JServ replies
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mark the JServ dead (in shared memory)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; endif
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; endif
&nbsp;&nbsp;&nbsp; endif

&nbsp;&nbsp;&nbsp; # here we have either got a request without session cookie
&nbsp;&nbsp;&nbsp; # or a broken session. In this last case, we send te request&nbsp;
&nbsp;&nbsp;&nbsp; # to another target in the list without saying it to the client.
&nbsp;&nbsp;&nbsp; # (the application will have to notice the broken session anyway)

&nbsp;&nbsp;&nbsp; if process_target != process_mount_default_target AND&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; our process_mount_default_target is alive (in shared memory)
&nbsp;&nbsp;&nbsp; then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; process_target = process_mount_default_target
&nbsp;&nbsp;&nbsp; endif
&nbsp;&nbsp;&nbsp; while (process_target exists)
&nbsp;&nbsp;&nbsp; do
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if process_target is alive (in shared memory)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the process sends the request to this JServ.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if the JServ replies
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; then
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mark the JServ dead (in shared memory)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; endif
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; endif
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; process_target = next in set
&nbsp;&nbsp;&nbsp; done
done</pre>
&nbsp;
<h4>
<a NAME="Watchdogprocess"></a>5.2. Watchdog process</h4>
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.
<pre>while true
do
&nbsp;&nbsp;&nbsp; sleep(10)

&nbsp;&nbsp;&nbsp; if this process is not the default watchdog (in shared memory )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break
&nbsp;&nbsp;&nbsp; endif

&nbsp;&nbsp;&nbsp; for each JServ present in shared memory list
&nbsp;&nbsp;&nbsp; do
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if JServ.state = down
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; connect JServ
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if failed
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mark it alive in shared memory
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; endif
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; endif
&nbsp;&nbsp;&nbsp; done
done

</pre>
&nbsp;
<h4>
<a NAME="Sharedmemory"></a>5.3. Shared memory</h4>
It is used to communicate between httpd processes.
<br>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.
<br>As many processes can do the same at the same moment, modifications
in this memory zone are immediately seen by other processes.
<br>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.
<br>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.
<br>The information stored in this shared memory is NOT MT-safe, not MP-safe
: accesses are NOT synchronized.
<br>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 ;-)
<br>This file is not human readable/writable. use a C/Perl program to access
it. (structure is in jserv.h).
<p><img SRC="images/lbshm001.gif" height=480 width=640>
<ul>
<h3>
<a NAME="Internalstate - Admistration tasks"></a>6. Internal state - Admistration
tasks</h3>
Every JServ is described in shared memory. One parameter is the server
state. This state can be :
<ul>
<li>
UP (internally '+') : means this JServ is running.</li>

<li>
DOWN (internally '-') : means JServ doesn't answer. (Watchdog is allowed
to change the state back to UP)</li>

<li>
SHUTDOWN_IMMEDIATE (internally 'X') : JServ is stopped by administator,
no traffic allowed.</li>

<li>
SHUTDOWN_GRACEFUL (internally '/') : JServ is stopped by administrator,
no new traffic allowed, but existing sessions still allowed. (example:
will be stopped in 10 minutes).</li>
</ul>

<p>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. 
<p>Once set to SHUTDOWN*, the watchdog doen't attempt to reconnect and set it up again. 
<p>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.
<p>If the web site has 10 Apache, he has to modify the shared memory file on each of them.
<p><br>After performing an administration task, the administrator changes
the state from SHUTDOWN_IMMEDIATE to UP back.
<h4>How to read/modify  the shared memory file ?</h4>
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.
<br>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.
<br><b>New !</b> 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.
<br><b>New !</b> The internal state of every JServ is also displayed in the /jserv/ status page on your website : somewhere like <A href=http://localhost/jserv/>http://localhost/jserv/</A> .
The status is present & updated in shared memory only after opening a connection on the servlet engine !<br>&nbsp;
<h3>
<a NAME="Largesites"></a>7. Large sites</h3>
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.
<br>Let's say that Apache1 will have 5 JServs in its set : <i>JServ1, JServ2,
JServ3, JServ4, JServ5</i>.
<br>Apache2 will have 5 other JServs in its own set (for the same zone):
<i>JServ11, JServ12, JServ13, JServ14, JServ15</i>.
<br>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).
<ul>
<li>
A client connects and obtains IP1 from the DNS for www.jserv.com.</li>

<li>
The sequest is sent to Apache1.</li>

<li>
Apache1 uses its load-balancing algorithm and chooses a JServ from its
set. (Let's say JServ1)</li>

<li>
JServ1 sets a (JServSessionId=xxxx.JS1) cookie to the client's browser.</li>

<li>
Following requests from this client, (session establihed) coming to Apache1
are routed to JServ1.</li>

<li>
Apache1 dies.</li>

<li>
Hopefully (thanks to our load-balancing equipment) the request comes on
Apache2.</li>

<li>
The cookie is recognized (JServSessionId=xxxx.JS1) and Apache2 sends the
request to JServ1.</li>

<li>
Every Apache never sends requests outside its own set, except for established
sessions.</li>
</ul>
<img SRC="images/lbprod002.gif" height=480 width=640>
<br><i><font size=-1>####################################################</font></i>
<br><i><font size=-1>#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<a href="http://java.apache.org">Apache JServ</a> Configuration File&nbsp;
for Apache A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
#</font></i>
<br><i><font size=-1>####################################################</font></i>
<br><i><font size=-1># Note: this file should be appended to httpd.conf</font></i>
<br><i><font size=-1>ApJServManual on</font></i>
<p><i><font color="#000000"><font size=-1>ApJServMount /servlet balance://set1/zone1</font></font></i><i><font color="#3366FF"><font size=-1></font></font></i>
<p># my own set of JServs for servlet zone "zone1"
<br><i><font color="#006600"><font size=-1>ApJServBalance set1&nbsp; JServ1</font></font></i>
<br><i><font color="#006600"><font size=-1>ApJServBalance set1&nbsp; JServ2</font></font></i>
<br><i><font color="#006600"><font size=-1>ApJServBalance set1&nbsp; JServ3</font></font></i>
<br><i><font color="#006600"><font size=-1>ApJServBalance set1&nbsp; JServ4</font></font></i>
<br><i><font color="#006600"><font size=-1>ApJServBalance set1&nbsp; JServ5</font></font></i>
<p><i><font color="#000000"><font size=-1>ApJServHost JServ1 ajpv12://192.168.0.51:7777</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServHost JServ2 ajpv12://192.168.0.52:8888</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServHost JServ3 ajpv12://192.168.0.53:9999</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServHost JServ4 ajpv12://192.168.0.54:7777</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServHost JServ5 ajpv12://192.168.0.55:7777</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServHost JServ11 ajpv12://192.168.0.61:7777</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServHost JServ12 ajpv12://192.168.0.62:7777</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServHost JServ13 ajpv12://192.168.0.63:7777</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServHost JServ14 ajpv12://192.168.0.64:7777</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServHost JServ15 ajpv12://192.168.0.65:7777</font></font></i><font color="#000000"></font>
<p><i><font color="#000000"><font size=-1>ApJServRoute JS1 JServ1</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServRoute JS2 JServ2</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServRoute JS3 JServ3</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServRoute JS4 JServ4</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServRoute JS5 JServ5</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServRoute JS11 JServ11</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServRoute JS11 JServ12</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServRoute JS11 JServ13</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServRoute JS11 JServ14</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServRoute JS11 JServ15</font></font></i><font color="#000000"></font>
<p><i><font color="#000000"><font size=-1>ApJServShmFile log/jserv_shm</font></font></i><font color="#000000"></font>
<p><i><font color="#000000"><font size=-1>ApJServSecretKey DISABLED</font></font></i>
<br><i><font size=-1>&lt;/IfModule></font></i><i><font size=-1></font></i>
<p><i><font size=-1>####################################################</font></i>
<br><i><font size=-1>#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

<a href="http://java.apache.org">Apache JServ</a> Configuration File&nbsp;
for Apache B&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
#</font></i>
<br><i><font size=-1>####################################################</font></i>
<br><i><font size=-1># Note: this file should be appended to httpd.conf</font></i>
<br><i><font size=-1>ApJServManual on</font></i>
<p><i><font color="#000000"><font size=-1>ApJServMount /servlet balance://set1/zone1</font></font></i><i><font color="#3366FF"><font size=-1></font></font></i>
<p># my own set of JServs for servlet zone "zone1"
<br><i><font color="#006600"><font size=-1>ApJServBalance set1&nbsp; JServ11</font></font></i>
<br><i><font color="#006600"><font size=-1>ApJServBalance set1&nbsp; JServ12</font></font></i>
<br><i><font color="#006600"><font size=-1>ApJServBalance set1&nbsp; JServ13</font></font></i>
<br><i><font color="#006600"><font size=-1>ApJServBalance set1&nbsp; JServ14</font></font></i>
<br><i><font color="#006600"><font size=-1>ApJServBalance set1&nbsp; JServ15</font></font></i>
<p><i><font color="#000000"><font size=-1>ApJServHost JServ1 ajpv12://192.168.0.51:7777</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServHost JServ2 ajpv12://192.168.0.52:8888</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServHost JServ3 ajpv12://192.168.0.53:9999</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServHost JServ4 ajpv12://192.168.0.54:7777</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServHost JServ5 ajpv12://192.168.0.55:7777</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServHost JServ11 ajpv12://192.168.0.61:7777</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServHost JServ12 ajpv12://192.168.0.62:7777</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServHost JServ13 ajpv12://192.168.0.63:7777</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServHost JServ14 ajpv12://192.168.0.64:7777</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServHost JServ15 ajpv12://192.168.0.65:7777</font></font></i><font color="#000000"></font>
<p><i><font color="#000000"><font size=-1>ApJServRoute JS1 JServ1</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServRoute JS2 JServ2</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServRoute JS3 JServ3</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServRoute JS4 JServ4</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServRoute JS5 JServ5</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServRoute JS11 JServ11</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServRoute JS11 JServ12</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServRoute JS11 JServ13</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServRoute JS11 JServ14</font></font></i>
<br><i><font color="#000000"><font size=-1>ApJServRoute JS11 JServ15</font></font></i><font color="#000000"></font>
<p><i><font color="#000000"><font size=-1>ApJServShmFile log/jserv_shm</font></font></i><font color="#000000"></font>
<p><i><font color="#000000"><font size=-1>ApJServSecretKey DISABLED</font></font></i>
<br><i><font size=-1>&lt;/IfModule></font></i>
<h3>
<a NAME="Knownproblems"></a>8. Known problems</h3>
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).
<p>The maximum number of active JServs is limited to 25. To increase it,
just increase the NB_MAX_JSERVS in jserv.h and recompile.
<p>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 ?
<br>Today we have load-balancing + but NO shared memory on NT.
<p>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.
<br>(must be root for TCP ports &lt; 1024). This is potentially dangerous,
and even if exploits can be difficult to create (as this process does'nt
listen HTTP requests),&nbsp; it has to be fixed ASAP.
<h3>
<a NAME="FAQ"></a>9. FAQ</h3>
Q: I can't understand how the load is distributed on different JServs.
<br>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 !
<p>Q: One of the JServs get twice the load of others
<br>A: Yes, due to the randomly chosen target, some of the JServs can be
used as default more often.
<br>In order to get a correct distribution, you need to run lots of httpd
processes. This is designed for big sites, so ...
<p>Q: My ApJServShmFile is corrupted
<br>A: Remove it. Start Apache.
<br>&nbsp;
<br>&nbsp;
<h3>
<a NAME="Tips"></a>10. Tips</h3>
&nbsp;
<h4>
Desactivating load-balancing</h4>
You can choose not to use load-balancing for part or all your system.
<br>In the above <a href="#Configuration">configuration</a> example we
had :
<p><i><font size=-1>ApJServMount /svlet1 ajpv12://192.168.0.1:7777/sv&nbsp;&nbsp;&nbsp;
&lt;&lt;&lt;&lt;&lt; this one is NOT load balanced</font></i>
<br><i><font color="#3366FF"><font size=-1>ApJServMount /servlet balance://set1/zone1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;&lt;&lt;&lt;&lt; this one IS.</font></font></i>
<h4>
using load-balancing without shared memory nor watchdog</h4>
It is possible to use load-balancing without shared memory &amp; watchdog.
<br>Just comment the <i><font color="#CC33CC"><font size=-1>ApJServShmFile
</font></font></i>line
(from httpd.conf):
<p><i><font color="#CC33CC"><font size=-1>######ApJServShmFile log/jserv_shm</font></font></i>
<p><i><font color="#000000"><font size=-1>Still using the load-balancing
syntax :</font></font></i>
<p><i><font color="#3366FF"><font size=-1>ApJServMount /servlet balance://set1/zone1</font></font></i>
<br><i><font color="#3366FF"><font size=-1>.../...</font></font></i>
<p>and the shared memory will NOT be used between httpd processes, and
you'll get NO watchdog to detect JServs that get alive again.
<br>&nbsp;
<h4>
Removing all load-balancing code</h4>
Just comment the line :
<br>#define LOAD_BALANCE in src/modules/jserv/jserv.h
<br>and recompile JServ+Apache :
<br>make clean; make; make install
<h3>
<a NAME="Authors"></a>11. Authors</h3>
Bernard Bernstein &lt;bernard@corp.talkcity.com>
<br>Jean-Luc Rochat &lt;jlrochat@jnix.com>
<center>
<p><font size=-1>Copyright (c) 2000 <a href="http://java.apache.org/" target="_top">The
Java Apache Project</a>.</font>
<br><font size=-1>$Id: howto.load-balancing.html,v 1.0 1999/04/20 16:05:12
<a href="mailto://jlrochat@jnix.com">Jean-Luc
Rochat</a> Exp $</font>
<br><font size=-1>All rights reserved.</font></center>
</ul>
</ol>

</body>
</html>