RustでClient-side Load Balancingする
RustでClient-side Load Balancingを実現するための方法について書きました。
Client-Side Load Balancing
Client-side Load Balancingとはクライアントがリクエスト先のサービスインスタンスの位置を把握し、クライアント自体が負荷分散することです。Client-Side Load Balancingを実現するソフトウェアとしてはNetflixのRibbonが有名でしょう。※1
ラウンドロビン方式での実装
負荷分散の方法としては最も素朴であろうラウンドロビン方式で実装しました。http://instance01.example.com
、http://instance02.example.com
、http://instance03.example.com
に対して、均等にトラフィックを振り分ける例です。
まずは、URLの一覧から順番に1つずつURLを取得してみます。
実行すると、以下のように出力されます。
"http://instance01.example.com"
"http://instance02.example.com"
"http://instance03.example.com"
"http://instance01.example.com"
"http://instance02.example.com"
"http://instance03.example.com"
"http://instance01.example.com"
"http://instance02.example.com"
"http://instance03.example.com"
"http://instance01.example.com"
http://instance01.example.com
、http://instance02.example.com
、http://instance03.example.com
の順に繰り返し表示されているので、意図通りです。
これらをreqwestなどのHTTP Clientに渡せば、ラウンドロビン方式でのLoad Balancingを実現できます。実装は以下のようになります。(エラーハンドリングは省略しています)
ここではreqwestのgetメソッドに next_url()
の結果を渡しています。
補足
AtomicUsizeやOrderingなどAtomicなものを使用しているのは、サーバーに対して並列にリクエストすることも想定しているためです。これらはスレッド間でも安全に共有できます。
参考
- https://doc.rust-lang.org/std/sync/atomic/struct.AtomicUsize.html
- https://doc.rust-lang.org/std/sync/atomic/enum.Ordering.html
※1 Ribbonはこのブログを書いている2019年9月21日時点ではメンテナンス中になっています