Moleculer 內建了幾種負載平衡策略,如果服務在多個節點實例運作, ServiceRegistry
可以使用這些策略來從活躍的節點中選擇某個節點。
如果想要使用內建的負載平衡策略,可以在 registry
內設定 strategy
,可以是一個字串名稱或是客製化的 Strategy
類別。
RoundRobin
是採用 Round-Robin DNS
的方式,以循環的方式逐個輪替[2] 。
範例:
moleculer.config.js
module.exports = {
registry: {
strategy: "RoundRobin"
}
};
Random
策略會隨機選擇一個可用的節點。
範例:
moleculer.config.js
module.exports = {
registry: {
strategy: "Random"
}
};
CpuUsage
策略會選擇 CPU 使用率最低的節點。但由於節點清單可能非常大,因此該策略會在列表中隨機取樣,並選擇 CPU 使用率最低的節點,而不是對整個節點清單去選擇最低的節點。
範例:
名稱 | 類型 | 預設值 | 說明 |
---|---|---|---|
sampleCount |
<Number> | 3 |
取樣點的數量。若要關閉採樣請設為 0 。 |
lowCpuUsage |
<Number> | 10 |
低 CPU 使用率百分比(%)。CPU 的使用率如果低於此百分比則立即選擇此節點。 |
moleculer.config.js
module.exports = {
registry: {
strategy: "CpuUsage",
strategyOptions: {
sampleCount: 3,
lowCpuUsage: 10
}
}
};
Latency
策略會定時發送 ping 來測試節點延遲時間,再選擇網路延遲最低的節點。由於節點清單可能非常大,因此該策略會在列表中隨機取樣,而不是對整個節點清單去選擇最低的節點。
範例:
名稱 | 類型 | 預設值 | 說明 |
---|---|---|---|
sampleCount |
<Number> | 5 |
取樣點的數量。若要關閉採樣請設為 0 。 |
lowLatency |
<Number> | 10 |
低延遲(毫秒)。延遲時間如果低於該值則立即選擇此節點。 |
collectCount |
<Number> | 5 |
單個節點保留的取樣資料總數,供計算平均延遲使用。 |
pingInterval |
<Number> | 10 |
定時發送 Ping 的間隔時間。如果你的節點清單非常大,建議增加間隔時間。 |
moleculer.config.js
module.exports = {
registry: {
strategy: "Latency",
strategyOptions: {
sampleCount: 15,
lowLatency: 20,
collectCount: 10,
pingInterval: 15
}
}
};
Shard
策略是基於 Consistent Hashing 演算法,它可以根據 params
或 meta
context 的鍵值來請求路由到節點。換句話說就是相同鍵值的請求,將會被路由到相同的節點上。
範例:以 params
context 的 name
進行分片。
moleculer.config.js
module.exports = {
registry: {
strategy: "Shard",
strategyOptions: {
shardKey: "name"
}
}
};
範例:以 meta
context 的 user.id
進行分片
注意,以
meta
context 進行分片時,必須在前面加上#
符號 ,實際執行時會忽略#
。
moleculer.config.js
module.exports = {
registry: {
strategy: "Shard",
strategyOptions: {
shardKey: "#user.id"
}
}
};
範例:選項設定方式
名稱 | 類型 | 預設值 | 說明 |
---|---|---|---|
shardKey |
<String> | null |
分片的鍵名稱。 |
vnodes |
<Number> | 10 |
虛擬節點數量。 |
ringSize |
<Number> | 2^32 |
環的大小。 |
cacheSize |
<Number> | 1000 |
快取大小。 |
moleculer.config.js
module.exports = {
registry: {
strategy: "Shard",
strategyOptions: {
shardKey: "#user.id",
vnodes: 10,
ringSize: 1000,
cacheSize: 1000
}
}
};
你可以在 Actions 或事件設定負載平衡策略來覆蓋全域的負載平衡策略。
範例:對 hello
Action 設定 Shard
策略來覆蓋全域的 RoundRobin
策略。
moleculer.config.js
module.exports = {
registry: {
strategy: "RoundRobin"
}
};
greeter.service.js
module.exports = {
name: "greeter",
actions: {
hello: {
params: {
name: "string"
},
strategy: "Shard",
strategyOptions: {
shardKey: "name"
},
handler(ctx) {
return `Hello ${ctx.params.name}`;
}
}
}
};
你也可以自己建立客製化策略,創建一個策略類別繼承自 BaseStrategy
,官方建議參考隨機策略的原始碼[4] 來實作 select
方法。
範例:建立客製化策略
my-strategy.js
const BaseStrategy = require("moleculer").Strategies.Base;
class MyStrategy extends BaseStrategy {
select(list, ctx) { /*...*/ }
}
module.exports = MyStrategy;
範例:使用客製化策略
moleculer.config.js
const MyStrategy = require("./my-strategy");
const Strategies = require("moleculer").Strategies
// 註冊一個客製化策略
Strategies.register("myCustomStrategy", MyStrategy)
module.exports = {
registry: {
// 由於客製化策略已被註冊,可以直接填入字串名稱
strategy: "myCustomStrategy"
}
};
ServiceBroker 會優先嘗試使用本地的服務實例(如果存在)來減少網路延遲。如果目標服務在本地的 Broker 為可用,則配置的策略將會被跳過, Broker
將始終優先採用本地服務。你可以在選項中設定 preferLocal: false
以關閉此邏輯。
moleculer.config.js
module.exports = {
registry: {
preferLocal: false
}
};
[1] Load balancing, https://moleculer.services/docs/0.14/balancing.html
[2] Round-robin DNS, https://en.wikipedia.org/wiki/Round-robin_DNS
[3] Consistent Hashing, https://www.toptal.com/big-data/consistent-hashing
[4] Random strategy, https://github.com/moleculerjs/moleculer/blob/master/src/strategies/random.js