Bug 44147

Summary: Multiple load balancing workers problem
Product: Tomcat Connectors Reporter: Zealot <zealot0630>
Component: CommonAssignee: Tomcat Developers Mailing List <dev>
Severity: major    
Priority: P2    
Version: unspecified   
Target Milestone: ---   
Hardware: All   
OS: All   
Attachments: The patch to fix this problem

Description Zealot 2007-12-27 22:09:19 UTC
If there are 2 workers, and first has 10 members, second has 2 members.

in ./native/common/jk_lb_worker.c:find_best_byvalue
Consider the following scenario.
1.first worker has handled 6 requests, next_offset=6.
2.now there comes a request redirecting to second worker, next_offset jumps to 1.
3.next request redirect to first worker will be assigned to the second member,
the other member will never be used.
Comment 1 Zealot 2007-12-27 22:11:24 UTC
Created attachment 21325 [details]
The patch to fix this problem
Comment 2 Rainer Jung 2007-12-31 11:38:46 UTC
Thank you for reporting the problem. Your patch has been applied in a slightly
modified form and will be released as part of version 1.2.27:


Since we released 1.2.26 only a week ago, it might take 2-4 months until 1.2.27.

Please note: the problem you describe is not a serious one. Although the code
was not really correct, it will be hard to observe this problem in reality. The
algorithm will always search through all available members of a load balancer in
order to find the member with the least load. next_offset is *only* really
useful when one uses the busyness algorithm for balancing (which is not the

If one uses busyness, and the load is low, it is likely, that several workers
have the same load value (=busyness), most likely the value 0. Let's assume for
simplicity, that all members always have busyness 0. Without next_offset, we
would then always choose the first member of a balancer. That would be OK,
because whenever we have to choose a member, there would be no load at all. But
still it would be counterintuitive to always choose the same member with a load
balancer. So next_offset rotates the starting point of the search loop in order
to make the decision between members of the same load status a little more balanced.

It would be even more correct, to put next_offset into the shared memory data of
the lb, to make it shared between all processes. I decided to *not* do that,
because there is a tradeoff between the additional overhead of a shared memory
volatile on the one hand and slightly better balancing for busyness+prefork+low
load on the other hand.