この記事はWeChatの公開アカウント「Android Development and Programming」から転載したもので、著者はAndroid Development and Programmingです。この記事を転載する場合は、Android 開発プログラミング パブリック アカウントにお問い合わせください。 序文負荷分散とは何ですか? 複数のサーバーを対称的に構成したサーバーセットを指します。各サーバーは同等の地位を持ち、他のサーバーの支援なしに独立して外部にサービスを提供できます。何らかの負荷分散技術により、外部から送信されたリクエストは対称構造のサーバーに均等に分散され、リクエストを受信したサーバーはクライアントのリクエストに独立して応答します。負荷分散により、クライアント要求をサーバー アレイに均等に分散できるため、重要なデータへの高速アクセスが可能になり、多数の同時アクセス サービスの問題が解決されます。このクラスター テクノロジにより、最小限の投資で大規模なメインフレームに近いパフォーマンスを実現できます。 今日は以下のことについてお話します。 1. 負荷分散アルゴリズムの概要1. 投票方法 実際の接続数やサーバーの現在のシステム負荷に関係なく、各バックエンド サーバーを平等に扱い、リクエストをバックエンド サーバーに順番に分散します。 2. ランダム法 システムのランダム アルゴリズムにより、バックエンド サーバーのリスト サイズ値に基づいて、アクセスするサーバーの 1 つがランダムに選択されます。確率統計理論によれば、クライアントがサーバーを呼び出す回数が増えるにつれて、実際の効果は各バックエンドサーバーへの呼び出し量を均等に分散することにますます近づき、つまりポーリングの結果になります。 3. 送信元アドレスのハッシュ ソース アドレス ハッシュの考え方は、クライアントの IP アドレスを取得し、ハッシュ関数を通じて値を計算することです。この値は、サーバー リストのサイズに対してモジュロ演算を実行するために使用されます。結果は、クライアントがアクセスするサーバーのシリアル番号です。負荷分散には送信元アドレス ハッシュを使用します。同じ IP アドレスを持つクライアントの場合、バックエンド サーバー リストが変更されていない場合は、アクセスするたびに同じバックエンド サーバーにマップされます。 4. 加重ラウンドロビン バックエンド サーバーによってマシン構成や現在のシステム負荷が異なる場合があり、そのためストレス耐性も異なります。構成が高く負荷が低いマシンに高い重みを割り当てて、より多くのリクエストを処理できるようにします。構成が低く負荷が高いマシンに低い重みを割り当てて、システム負荷を軽減します。重み付けポーリングはこの問題を適切に処理し、重みに従って順番にバックエンドにリクエストを分散します。 5. 加重ランダム法 加重ラウンドロビン方式と同様に、加重ランダム方式でも、バックエンド マシンの構成とシステムの負荷に基づいて異なる重みが割り当てられます。違いは、順序ではなく重みに応じてバックエンド サーバーをランダムに要求することです。 2. 5つの負荷分散アルゴリズムを実装するコード1. 投票方法 - java.util.* をインポートします。
- java.util.concurrent.ConcurrentHashMap をインポートします。
- パブリッククラスTestRoundRobin{
- // 1. マップ、キー-ip、値-weightを定義する
- 静的Map<String, Integer > ipMap = new HashMap<>();
- 静的{
- ipMap.put( "192.168.13.1" ,1);
- ipMap.put( "192.168.13.2" ,1);
- ipMap.put( "192.168.13.3" ,1);
- }
- //整数 合計= 0;
- 整数pos = 0;
- パブリック文字列ラウンドロビン(){
- Map<String, Integer > ipServerMap = 新しい ConcurrentHashMap<>();
- ipServerMap.putAll(ipMap);
- // 2.キーを取り出してセットに入れる
- <文字列> ipset = ipServerMap.keySet()を設定します。
- // 3.セットをリストに入れ、リストをループして取り出す
- ArrayList<文字列> iplist=新しいArrayList<文字列>();
- iplist.addAll(ipset);
- 文字列 serverName = null ;
- // 4. ループ値を定義し、それが設定された値より大きい場合は0 から開始します。
- 同期(pos){
- (pos>= ipset.size ())の場合{
- 位置=0;
- }
- serverName=iplist.get(pos);
- // 投票 +1
- 位置++;
- }
- serverNameを返します。
- }
- 公共 静的void main(String[] args) {
- テストラウンドロビン testRoundRobin=新しいテストラウンドロビン();
- ( int i=0;i<10;i++)の場合{
- 文字列 serverIp=testRoundRobin.RoundRobin();
- System.out.println(サーバーIP ) ;
- }
- }
- }
2. 加重ラウンドロビン - java.util.* をインポートします。
- java.util.concurrent.ConcurrentHashMap をインポートします。
- パブリッククラスTestWeightRobin {
- // 1.map、キー-ip、値-重み
- 静的Map<String, Integer > ipMap = new HashMap<>();
- 静的{
- ipMap.put( "192.168.13.1" ,1);
- ipMap.put( "192.168.13.2" ,2);
- ipMap.put( "192.168.13.3" ,4);
- }
- 整数pos=0;
- パブリック文字列WeightRobin(){
- Map<String, Integer > ipServerMap = 新しい ConcurrentHashMap<>();
- ipServerMap.putAll(ipMap);
- <文字列> ipSet = ipServerMap.keySet() を設定します。
- イテレータ<文字列> ipIterator=ipSet.iterator();
- //すべてのサーバーを配置するリストを定義する
- ArrayList<文字列> ipArrayList=新しいArrayList<文字列>();
- //セットをループし、マップの値を使用してセットの値を見つけ、対応する数のサーバーをリストに追加します。
- (ipIterator.hasNext()) の間{
- 文字列 serverName = ipIterator.next ();
- 整数の重み=ipServerMap.get(serverName);
- ( int i = 0; i < 重み; i++) {
- ipArrayList.add (サーバー名);
- }
- }
- 文字列 serverName = null ;
- if (pos>= ipArrayList.size ()){
- 位置=0;
- }
- serverName=ipArrayList.get(pos);
- // 投票 +1
- 位置++;
- serverNameを返します。
- }
- 公共 静的void main(String[] args) {
- テストウェイトロビン testWeightRobin=新しいテストウェイトロビン();
- ( int i =0;i<10;i++)の場合{
- 文字列 server=testWeightRobin.WeightRobin();
- System.out.println (サーバー) ;
- }
- }
- }
3. ランダム法 - java.util.* をインポートします。
- java.util.concurrent.ConcurrentHashMap をインポートします。
- パブリッククラスTestRandom{
- // 1. マップ、キー-ip、値-weightを定義する
- 静的Map<String, Integer > ipMap = new HashMap<>();
- 静的{
- ipMap.put( "192.168.13.1" ,1);
- ipMap.put( "192.168.13.2" ,2);
- ipMap.put( "192.168.13.3" ,4);
- }
- パブリック文字列ランダム() {
- Map<String, Integer > ipServerMap = 新しい ConcurrentHashMap<>();
- ipServerMap.putAll(ipMap);
- <文字列> ipSet = ipServerMap.keySet() を設定します。
- //すべてのサーバーを配置するリストを定義する
- ArrayList<文字列> ipArrayList=新しいArrayList<文字列>();
- ipArrayList.addAll(ipSet);
- // 乱数をループする
- ランダム random=new Random();
- //リストから乱数を取得します (1- list.size )
- int pos=random.nextInt(ipArrayList.size ( ));
- 文字列 serverNameReturn = ipArrayList.get(pos);
- serverNameReturnを返します。
- }
- 公共 静的void main(String[] args) {
- TestRandom testRandom=新しい TestRandom();
- ( int i =0;i<10;i++)の場合{
- 文字列 server=testRandom.Random();
- System.out.println (サーバー) ;
- }
- }
- }
4. 加重ランダム - java.util.* をインポートします。
- java.util.concurrent.ConcurrentHashMap をインポートします。
- パブリッククラスTestRobinRandom{
- // 1. マップ、キー-ip、値-weightを定義する
- 静的Map<String, Integer > ipMap = new HashMap<>();
- 静的{
- ipMap.put( "192.168.13.1" ,1);
- ipMap.put( "192.168.13.2" ,2);
- ipMap.put( "192.168.13.3" ,4);
- }
- パブリック文字列RobinRandom(){
- Map<String, Integer > ipServerMap = 新しい ConcurrentHashMap<>();
- ipServerMap.putAll(ipMap);
- <文字列> ipSet = ipServerMap.keySet() を設定します。
- イテレータ<文字列> ipIterator=ipSet.iterator();
- //すべてのサーバーを配置するリストを定義する
- ArrayList<文字列> ipArrayList=新しいArrayList<文字列>();
- //セットをループし、マップの値を使用してセットの値を見つけ、対応する数のサーバーをリストに追加します。
- (ipIterator.hasNext()) の間{
- 文字列 serverName = ipIterator.next ();
- 整数の重み=ipServerMap.get(serverName);
- ( int i=0;i<weight;i++)の場合{
- ipArrayList.add (サーバー名);
- }
- }
- // 乱数をループする
- ランダム random=new Random();
- //リストから乱数を取得します (1- list.size )
- int pos=random.nextInt(ipArrayList.size ( ));
- 文字列 serverNameReturn = ipArrayList.get(pos);
- serverNameReturnを返します。
- }
- 公共 静的void main(String[] args) {
- TestRobinRandom testRobinRandom=新しい TestRobinRandom();
- ( int i =0;i<10;i++)の場合{
- 文字列 server=testRobinRandom.RobinRandom();
- System.out.println (サーバー) ;
- }
- }
- }
5. 送信元アドレスのハッシュ - java.util.ArrayList をインポートします。
- java.util.HashMap をインポートします。
- java.util.Map をインポートします。
- java.util.Setをインポートします。
- java.util.concurrent.ConcurrentHashMap をインポートします。
- パブリッククラスipHash{
- // 1. マップ、キー-ip、値-weightを定義する
- 静的Map<String, Integer > ipMap = new HashMap<>();
- 静的{
- ipMap.put( "192.168.13.1" ,1);
- ipMap.put( "192.168.13.2" ,2);
- ipMap.put( "192.168.13.3" ,4);
- }
- パブリック文字列ipHash(文字列クライアントIP){
- Map<String, Integer > ipServerMap = 新しい ConcurrentHashMap<>();
- ipServerMap.putAll(ipMap);
- // 2.キーを取り出してセットに入れる
- <文字列> ipset = ipServerMap.keySet()を設定します。
- // 3.セットをリストに入れ、リストをループして取り出す
- ArrayList<文字列> iplist=新しいArrayList<文字列>();
- iplist.addAll(ipset);
- // IPのハッシュコード値の残りを取得します。これは毎回同じです
- intハッシュコード = クライアントIP.ハッシュコード();
- int serverListsize = iplist.size ( );
- int pos=ハッシュコード%サーバーリストサイズ;
- iplist.get(pos);を返します。
- }
- 公共 静的void main(String[] args) {
- ipHash iphash = 新しい ipHash();
- 文字列サーバー名 = iphash.ipHash( "192.168.21.2" );
- System.out.println (サーバー名) ;
- }
- }
要約する前進しなければ遅れを取ってしまいます。一緒に頑張りましょう! |