はじめに
Cloudflare で gRPC を通すテスト、第4回です。
- プロキシ + Full TLS 化
- ファイアウォール
- レートリミット
- ロードバランシング <<====
ロードバランシング
gRPC リクエストのオリジンへの誘導をプログラムしようと思います。
ロードバランシングを使います。
Cloudflare のトラフィックシーケンスでは最後に出てきます。
テスト構成
gRPC クライアントとサーバの位置関係は下記のとおりです。
gRPC | 国 |
---|---|
クライアント | |
サーバー | |
URL | https://grpc.example.com:443/helloworld.Greeter/SayHello |
設定フロー
公式の設定ガイドに従います。
負荷分散
ダッシュボードでは下記の項目が選択可能となっています。
ロードバランサーを作成する
API
モニターやプールを関連つけたロードバランサーの設定
モニターを管理する
API
サービスの死活監視を行う、ヘルスモニターの設定
(今回は TCP Port 443 に対する TCP コネクションでサービスの生死を確認)
プールを管理する
API
gRPC オリジンサーバの集まりである、プールの設定
(今回は国ごとにプールを作成)
下記のようなウィザードに従い、作成します。
1. ホスト名
ホスト名を入力し、オレンジ雲に倒して HTTP Proxyとします。
グレー雲の場合は HTTP Proxy はせず、DNS によるロードバランシングとなります。
2. オリジンプール
プール (オリジンサーバーのグループ) を指定します。
今回はプールが 3 つ、各プールに属するオリジンは 1 つ。
プール | オリジン台数 | オリジン IP/Host |
---|---|---|
gcp_australia | 1 | 35.xxx.xxx.xxx |
gcp_brazil | 1 | 34.xxx.xxx.xxx |
gcp_japan | 1 | 34.xxx.xxx.xxx |
編集
をクリックして設定されている内容を見てみます。
オリジンステアリング
プールの中に複数のオリジンがいる場合の分散方法になります。今回はプール内のオリジンは 1 なので動作には影響しません。
オリジン名
識別子です。
オリジンアドレス
オリジンのホスト名あるいは IP アドレスを指定します。
緯度、経度
プールの位置。
プロキシミティ ステアリング を試すので、こちらも指定しておきます。
監視
ヘルスモニターを紐つけます。
TCP の 443 ポートを監視する設定に関連ついています。
ダウンしていたら、そのプールには振らない、などでサービスの可用性を高めることができます。
ヘルスチェックリージョン
監視をするクラウドフレアの地域。
ダイナミックステアリング を試すので、gRPC クライアントのいる Western North America を指定。
Western North America から各プールにヘルスチェックを行った際の応答 RTT がステアリングの判断材料として利用されます。
3. モニター
プールにモニターが紐ついていることがわかります。
4. トラフィックステアリング
プールの選択方法を選択します。
まずは オフ でフェイルオーバ順とします。
5. カスタムルール
柔軟な ルールの上書き が可能です。今回は使用しません。
6. レビュー
ウィザードで実施した設定をレビューします。
問題なければ保存します。
7. サマリー画面
3 プールとも 正常
に稼働していることがわかります。
ステアリング別の動作確認
gRPC クライアントからは 5 秒に 1 つリクエストを送っています。
ロードバランシングの状況は負荷分散分析
画面で確認できます。
オリジンのステータスとその履歴も参照可能です。
ステアリングの方法ごとに、リクエストの分散状況を見ていきます。
オフ
オフ では、フェイルオーバー順に利用されます。
(上の 2. オリジンプール
に記載の通り)
リストの先頭である のみに誘導されています。
この状態で が応答不能になると、
リストの次に位置する が選択されます。
が生き返ると、再度選択されます。
ランダム
ランダムを選択します。重み付けは均等にしています。
重み通りに均等に分散されています。
ダイナミック
ダイナミックを選択します。
gRPC クライアントが接続するデータセンター ( ) からのヘルスチェックの応答 (RTT) が速いプールが選択されます。
が選択され、 は選択されていません。
RTT は Exponentially Weighted Moving Average (EWMA) というのを利用しているとのこと。
Dynamic Steering creates Round Trip Time (RTT) profiles based on an exponential weighted moving average (EWMA) of RTT to determine the fastest pool. If there is no current RTT data for your pool in a region or colocation center, Cloudflare directs traffic to the pools in failover order.
RTT は API で確認可能です。
$ for POOL_ID in `curl -s -X GET -H "Authorization: Bearer $TOKEN" "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/load_balancers" | jq -r ".result[]|select(.name |contains(\"$HOSTNAME\"))|.default_pools[]"`; do curl -s -X GET -H "Authorization: Bearer $TOKEN" "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/load_balancers/pools/$POOL_ID/health" |jq '.result.pop_health'; done
{
"WNAM": {
"healthy": true,
"origins": [
{
"35.xxx.xxx.xxx": { <<== JP
"healthy": true,
"rtt": "158.2ms",
"failure_reason": "No failures"
}
}
]
}
}
{
"WNAM": {
"healthy": true,
"origins": [
{
"34.xxx.xxx.xxx": { <<== BR
"healthy": true,
"rtt": "172.7ms",
"failure_reason": "No failures"
}
}
]
}
}
{
"WNAM": {
"healthy": true,
"origins": [
{
"34.xxx.xxx.xxx": { <<== AU
"healthy": true,
"rtt": "169.6ms",
"failure_reason": "No failures"
}
}
]
}
}
ロードバランサーのプール (POOL ID) を探す
$ curl -s -X GET -H "Authorization: Bearer $TOKEN" "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/load_balancers"
各プールのヘルスモニタ状況を得る
$ curl -s -X GET -H "Authorization: Bearer $TOKEN" "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/load_balancers/pools/$POOL_ID/health"
ジオ
ジオを選択します。
のクライアントを のプール (一番遠い) に誘導してみます。
クライアントの国を選択します。
誘導したいプールを選択します。
を選びます。
にスタティックに誘導されています。
プロキシミティ
プロキシミティを選択します。
あらかじめプールの場所 (緯度・経度) は設定しておきます。
ダッシュボードでの地図で選ぶことも可能です (上記 2. オリジンプール
)。
レスポンス比較
ステアリング | 応答時間 95 パーセンタイル | 50 パーセンタイル | プール |
---|---|---|---|
ランダム | 0.634 | 0.279 | |
ダイナミック | 0.344 | 0.271 | |
プロキシミティ | 0.262 | 0.213 |
今回の場合は だけを選択したプロキシミティの応答速度が良かったようです。
応答時間は gRPC クライアントで tshark パケットキャプチャ分析 (Duration) を利用
$ sudo tshark -r /tmp/grpc.proximity.pcap -q -z conv,tcp 2>/dev/null| head
================================================================================
TCP Conversations
Filter:<No Filter>
| <- | | -> | | Total | Relative | Duration |
| Frames Bytes | | Frames Bytes | | Frames Bytes | Start | |
10.138.0.2:35496 <-> 104.xxx.xxx.xxx:443 15 7058 20 1968 35 9026 763.815464586 0.2134
10.138.0.2:51948 <-> 104.xxx.xxx.xxx:443 15 7060 20 1968 35 9028 1897.589741747 0.2520
:
Duration のみ抽出し、小さい順にソート
sudo tshark -r /tmp/grpc.dynamic.pcap -q -z conv,tcp 2>/dev/null| awk '/^1/ {print $11}'|sort > grpc.perf.dynamic.txt
パーセンタイル算出は R を利用
$ R
> x <- scan("grpc.perf.dynamic.txt")
Read 681 items
> x
[1] 0.1903 0.1942 0.1957 0.1975 0.1992 0.2021 0.2027 0.2044 0.2052 0.2053
:
[681] 1.1017
>
> summary(x)
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.1903 0.2629 0.2717 0.2822 0.2821 1.1017
> quantile(x, c(0,0.5,0.95))
0% 50% 95%
0.1903 0.2717 0.3449
>
まとめ
以上で gRPC クライアントを複数拠点の gRPC サーバに誘導し、パフォーマンスと可用性を高めることができました。サービス展開時の参考になればと思います。
なお、ロードバランシングについては、他にも様々な機能がありますが、そちらは別の機会にでも。
こちらで Cloudflare で gRPC を通すテスト は一旦終了とします。