ポーリング アルゴリズム: 受信したリクエストをバックエンド サーバーに順番に転送します。現在のサーバーへの実際の接続数や現在のシステム負荷を考慮せずに、すべてのサーバーを平等に扱います。 以下に簡単な投票システムを示します。 - パブリッククラスラウンドロビン{
- 静的 整数位置 = 0;
- 公共 静的リスト<String> initServerList() {
- List<String> サーバー = 新しい ArrayList<>();
- サーバーを追加します( "192.168.10.00" );
- サーバーを追加します( "192.168.10.01" );
- サーバーを追加します( "192.168.10.02" );
- サーバーを追加します( "192.168.10.03" );
- サーバーを追加します( "192.168.10.04" );
- サーバーを追加します( "192.168.10.05" );
- サーバーを追加します( "192.168.10.06" );
- サーバーを返す。
- }
- 公共 静的文字列 getServerUrl() {
- //サーバーのオンラインとオフラインによって発生する同時実行の問題を回避するために、新しいリスト割り当てを作成します
- リスト<String> serverList = 新しい ArrayList<>();
- サーバーリストにAllを追加します(initServerList());
- 文字列サーバー = null ;
- 同期(位置){
- if(位置 >= serverList.size ()) {
- 位置 = 0;
- }
- サーバー = serverList.get(位置);
- 位置++;
- }
- サーバーを返す。
- }
- 公共 静的void main(String[] args) {
- (真)の間{
- System.out.println (getServerUrl()) ;
- }
- }
- }
実際の生産環境では、次のような多くの要素を考慮する必要があります。 [[238078]] 新しく追加されたサーバー IP をどのように処理しますか? これは比較的簡単で、initServerList() に追加するだけです。 サービス停止が発生した場合はどうすればよいですか? たとえば、192.168.10.01 が配置されているサーバーがダウンしていて、そのサーバーにリクエストが転送された場合、エラーが報告されます。このとき、サービスを必要とする消費者はフォールト トレランスを考慮します。この場合、たとえば、再度リクエストを送信すると、192.168.10.02 マシンに転送されますが、これは正常です。 この方法の最大の欠点は、悲観的ロック同期を使用するため、システムの同時パフォーマンスに影響が出ることです。 各マシンの構成は異なり、シングルコアCPU、2Gメモリのものもあれば、8コアCPU、32Gメモリのものもある。この場合、上記のポーリング方法を使用すると不公平になり、構成が弱いマシンに大きな負担がかかります。 これを導入することができます 重み付けラウンドロビン: 各サーバーに重み値が与えられます。重みが高いサーバーにはより多くのリクエストが割り当てられ、重みが低いサーバーにはより少ないリクエストが割り当てられます。 実装のアイデアも非常にシンプルです。重みに応じてサービス リストを再構築し、ポーリングします。前の画像: コードの実装は次のとおりです。 - パブリッククラスWeightRoundRobin {
- 静的 整数位置 = 0;
- 公共 静的マップ<文字列、整数> initServicesMap() {
- Map<String, Integer > servicesMap = new HashMap<>();
- servicesMap.put( "192.168.10.00" , 1);
- servicesMap.put( "192.168.10.02" , 3);
- servicesMap.put( "192.168.10.03" , 3);
- servicesMap.put( "192.168.10.04" , 5);
- servicesMap.put( "192.168.10.05" , 5);
- servicesMap.put( "192.168.10.06" , 5);
- servicesMapを返します。
- }
- 公共 静的文字列 getServerUrl() {
- //サーバーのオンラインとオフラインによって発生する同時実行の問題を回避するために、新しいリスト割り当てを作成します
- Map<String, Integer > initMap = new HashMap<>();
- initMap = initServicesMap();
- <String>を設定します。servicesSet = new HashSet<>();
- servicesSet.addAll(initMap.keySet());
- イテレータ<String> servicesIterator = servicesSet.iterator();
- リスト<String> servicesList = 新しい ArrayList<>();
- (servicesIterator.hasNext()) の間 {
- 文字列 server = servicesIterator.next ();
- 整数の重み = initMap.get(server);
- if(重み > 0) {
- ( int i=0; i<weight; i++)の場合{
- servicesList.add (サーバー);
- }
- }
- }
- 文字列サーバー = null ;
- 同期(位置){
- if(位置 >= servicesList.size ()) {
- 位置 = 0;
- }
- サーバー = servicesList.get(位置);
- 位置++;
- }
- サーバーを返す。
- }
- 公共 静的void main(String[] args) {
- (真)の間{
- System.out.println (getServerUrl()) ;
- }
- }
- }
ランダム化アルゴリズム: 名前が示すように、N 個のサーバー IP アドレスがあります。リクエストが届くと、ランダムにサーバーに転送されます。確率の観点から見ると、リクエストの数が増えると、各サーバーに割り当てられるリクエストは最終的にほぼ等しくなります。これにより、ポーリング アルゴリズムよりも悲観的なロックが 1 つ少なくなり、同時実行パフォーマンスが大幅に向上します。 実装も非常に簡単です。 次のように: - パブリッククラスRandomDemo {
- 公共 静的リスト<String> initServerList() {
- List<String> サーバー = 新しい ArrayList<>();
- サーバーを追加します( "192.168.10.00" );
- サーバーを追加します( "192.168.10.01" );
- サーバーを追加します( "192.168.10.02" );
- サーバーを追加します( "192.168.10.03" );
- サーバーを追加します( "192.168.10.04" );
- サーバーを追加します( "192.168.10.05" );
- サーバーを追加します( "192.168.10.06" );
- サーバーを返す。
- }
- 公共 静的文字列 getServerUrl() {
- //サーバーのオンラインとオフラインによって発生する同時実行の問題を回避するために、新しいリスト割り当てを作成します
- リスト<String> serverList = 新しい ArrayList<>();
- serverList に All を追加します。
- int位置 = 新しい Random().nextInt(serverList.size ( ));
- serverList.get(position)を返します。
- }
- 公共 静的void main(String[] args) {
- (真)の間{
- System.out.println (getServerUrl()) ;
- }
- }
- }
しかし、単純なポーリング アルゴリズムと同じ問題があります。 パフォーマンスが異なるサーバーを平等に扱うのは実際には不公平です。構成が低いため、要求も少なくなるはずです。 それでおしまい 重み付けランダム アルゴリズムの実装の考え方は、重み付けポーリング アルゴリズムの実装の考え方と同じで、構成の異なるサーバーに異なる重み値を設定します。コードの実装は重み付けポーリングのアイデアと同じです。重み値を満たすサービス セットを構築した後、ランダム選択が実行されます。ここでは記述せず、各自で記述してください。 送信元アドレスハッシュ (hashCode) 方式: クライアントの要求 IP に基づいてハッシュ計算を実行して値を取得し、その値をサーバーリストの数で剰余計算して、要求によってアクセスされたサーバーリストのシリアル番号を取得します。この方法の利点の 1 つは、サーバー リストが変更されていない場合、クライアントは常に固定サーバーにアクセスするため、クライアントとサーバーの間でステートフル セッションを構築できることです。 コード実装: - パブリッククラスHashDemo {
- 公共 静的リスト<String> initServerList() {
- List<String> サーバー = 新しい ArrayList<>();
- サーバーを追加します( "192.168.10.00" );
- サーバーを追加します( "192.168.10.01" );
- サーバーを追加します( "192.168.10.02" );
- サーバーを追加します( "192.168.10.03" );
- サーバーを追加します( "192.168.10.04" );
- サーバーを追加します( "192.168.10.05" );
- サーバーを追加します( "192.168.10.06" );
- サーバーを返す。
- }
- 公共 静的文字列 getServerUrl() {
- //サーバーのオンラインとオフラインによって発生する同時実行の問題を回避するために、新しいリスト割り当てを作成します
- リスト<String> serverList = 新しい ArrayList<>();
- serverList に All を追加します。
- int requestIpHashCode = "192.168.10.06.109" .hashCode();
- int位置 = requestIpHashCode % serverList.size ( ) ;
- serverList.get(position)を返します。
- }
- 公共 静的void main(String[] args) {
- (真)の間{
- System.out.println (getServerUrl()) ;
- }
- }
- }
【編集者のおすすめ】 - ソフトウェア定義データセンター (SDDC) を完全に実現するにはどうすればよいでしょうか?
- 【おすすめ】負荷分散って難しい?これを読んで全て理解できました
- Linux のヒント: パスワード不要のログインを実装し、サーバーの運用とメンテナンスの時間を節約する方法
- ゲートウェイなしでLoRaネットワークを実現するにはどうすればいいですか?
- 負荷分散を試してみたいのですが、これらをご存知ですか?
|