A Node.js module for load balancing based on the Weighted Round Robin (WRR) algorithm, implemented as a simulation of the Nginx WRR algorithm.
Consider three nodes {a, b, c} with respective weights {a=5, b=1, c=1}. If we send 7 requests, node a will be assigned 5 times, node b will be assigned once, and node c will also be assigned once.
Nginx Weighted Round Robin Algorithm:
Conceptual explanation, where each node has three weight variables:
weight
: Defined weight, which is the weight assigned to each node in the configuration or initialization.effectiveWeight
: Effective weight, initially set toweight
.currentWeight
: Current weight of the node, initially set to 0.
Algorithm logic:
- Iterate through all nodes and calculate the sum of
effectiveWeight
for all nodes, which istotalWeight
. currentWeight = currentWeight + effectiveWeight
. Select the node with the highestcurrentWeight
as the chosen node.currentWeight
of the selected node is reduced bytotalWeight
.
This module provides two types of weighted round-robin tables for load balancing. One is a forward order table, where nodes with higher weights receive more assignments. The other is a reverse order table, where nodes with lower weights receive more assignments.
npm install wrr-plus
// or
yarn add wrr-plus
// or
pnpm add wrr-plus
Example:
const { WeightedRoundRobin } = require('wrr-plus')
const wrr = new WeightedRoundRobin({
max: 200,
min: 10
})
for(let i = 1; i <= 50; i++) {
const key = `172.26.2.${i}`
const value = {
server: key,
weight: parseInt(Math.random()*100) || 1 // add value must contain weight for weight calculation
}
wrr.add(key, value) // add wrr kv node
}
wrr.getRoundRobin() // get forward order round-robin table
wrr.getRoundRobin('server') // get forward order round-robin table and only return the value of 'server' from each entry
wrr.getRoundRobin('server', { reverse: true }) // get reverse order round-robin table and only return the value of 'server' from each entry
wrr.getRoundRobin('server', { reverse: true, max: 200, min: 50 }) // get reverse order round-robin table, limit the length, and only return the value of 'server' from each entry
wrr.get('172.26.2.1') // get a specific kv node from wrr
wrr.remove('172.26.2.2') // remove a specific kv node from wrr
wrr.size() // get the number of kv nodes in wrr
wrr.reset() // reinitialize wrr, invalidating all previously added kv nodes
Additional parameter explanations for getRoundRobin(item, options)
:
{
reverse: false, // Select between forward and reverse order round-robin tables. Set to true for forward order table and false for reverse order table. If not specified, the configuration from instantiation will be used.
max: 100, // Maximum length of the round-robin table. If the number of nodes exceeds this value, the number of nodes will be used as the maximum length. If not specified, the configuration from instantiation will be used.
min: 20, // Minimum length of the round-robin table. If not specified, the configuration from instantiation will be used.
}
Additional parameter explanations for new WeightedRoundRobin(options)
:
{
reverse: false, // Select between forward and reverse order round-robin tables. Set to true for forward order table and false for reverse order table. Default is false.
max: 100, // Maximum length of the round-robin table. Note: If the number of nodes exceeds this value, the number of nodes will be used as the maximum length.
min: 20, // Minimum length of the round-robin table.
// Filter out exceptional nodes from the round-robin table
filter: {
enable: false, // Enable node filtering. Default is false.
number: 3, // Trigger filtering if the number of nodes exceeds 3. Default is 3.
totalWeight: 100, // Trigger filtering if the total weight of all nodes exceeds 100. Default is 100.
ratio: 0.6 // Filter out a node if its weight accounts for 60% of the total weight. Default is 0.6, with a range of 0.1 to 1.0.
}
}
- The
options
ingetRoundRobin()
takes priority over theoptions
innew WeightedRoundRobin()
. - If the number of nodes exceeds the default maximum length of the round-robin table, the number of nodes will be automatically selected as the maximum length.
Open sourced under the MIT license.