概要
の中でconfig.route.v3.RouteActionに重み付き負荷分散(weighted load balancing)の設定がありました。
これを利用することで
- カナリアリリース
- リクエストのサンプリング
- 一部だけ詳細なログやstatsを出す
- Mountebankのようなリクエストをレコードしてリプレイできるモックサーバに流す
といったことが容易に実現できます。
今回はこの機能を試してみます。
環境
- v1.24.0
Weighted load balancing
設定
Listener
設定は簡単で、weighted_clusters.clustersに対象とするclusterとリクエストを振り分けする重みの設定を行うだけです。
以前はtotal_weightで重みの合計を指定する必要がありましたが、現在はdeprecatedとなり自動で行ってくれます。
route_config: name: local_route virtual_hosts: - name: local_service domains: ["*"] routes: - name: default match: { prefix: "/" } route: weighted_clusters: clusters: - name: base weight: 80 - name: canary weight: 20 timeout: 30s
今回は8:2でリクエストを分散するようにしています。
Cluster
今回は簡単のためclusterの名前は別ですが中身のエンドポイントは同じになってます。
実際のカナリアリリースではエンドポイントをカナリア用のサーバに向けます。
clusters: - name: base connect_timeout: 1s type: STRICT_DNS lb_policy: ROUND_ROBIN load_assignment: cluster_name: base endpoints: - lb_endpoints: - endpoint: address: socket_address: address: httpbin.org port_value: 80 - name: canary connect_timeout: 1s type: STRICT_DNS lb_policy: ROUND_ROBIN load_assignment: cluster_name: canary endpoints: - lb_endpoints: - endpoint: address: socket_address: address: httpbin.org port_value: 80
動作検証
k6を用いて10rpsを定常的にかけてみます。
import http from "k6/http";
import { check } from "k6";
export const options = {
scenarios: {
open_model: {
executor: "constant-arrival-rate",
rate: 10,
timeUnit: "1s",
duration: "2m",
preAllocatedVUs: 20,
},
},
};
export default function () {
const res = http.get("http://localhost:8080/get");
check(res, {
"is status 200": (r) => r.status === 200,
});
}
結果
期待通り8:2でリクエストが分散されました。

サンプルコード
今回のサンプルコードはこちら
まとめ
Envoyの重み付き負荷分散を試してみました。