JAVA は、単純な F5負荷分散 機能を実装します。

F5 負荷分散装置は非常に高価で起業家には不向きですが、HTTP サーバーの負荷分散機能を実装するための小さな純粋な JAVA コードであり、基本的な機能を使用できます。

ServerF5.java 

package F5Server;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ServerF5 {

    private int currentIndex = -1;// 最後に選択したサーバー
    private int currentWeight = 0;// 現在のスケジュールの重み
    private int maxWeight = 0; // 最大重量
    private int gcdWeight = 0; //すべてのサーバーの重みの最大公約数
    private int serverCount = 0; //サーバーの数
    private List<Server> serverList; //サーバーコレクションList
    private static ServerF5 context;


     /**
     * F5 コンテキストを初期化する
     */
    public static ServerF5 getContext() {
        if (context == null) {
            context = new ServerF5();
        }
        return ServerF5.context;
    }

    /**
     * 最大公約数を返します
     */
    private static int gcd(int a, int b) {
        BigInteger b1 = new BigInteger(String.valueOf(a));
        BigInteger b2 = new BigInteger(String.valueOf(b));
        BigInteger gcd = b1.gcd(b2);
        return gcd.intValue();
    }

    /**
     * すべてのサーバーの重みの最大公約数を返します
     */
    private static int getGCDForServers(List<Server> serverList) {
        int w = 0;
        if (serverList.size() == 1) {
            w = gcd(w, serverList.get(0).weight);
        }
        for (int i = 0, len = serverList.size(); i < len - 1; i++) {
            if (w == 0) {
                w = gcd(serverList.get(i).weight, serverList.get(i + 1).weight);
            } else {
                w = gcd(w, serverList.get(i + 1).weight);
            }
        }
        return w;
    }

    /**
     * すべてのサーバーの中で最大の重みを返します
     */
    public static int getMaxWeightForServers(List<Server> serverList) {
        int w = 0;
        if (serverList.size() == 1) {
            w = Math.max(w, serverList.get(0).weight);
        }
        for (int i = 0, len = serverList.size(); i < len - 1; i++) {
            if (w == 0) {
                w = Math.max(serverList.get(i).weight, serverList.get(i + 1).weight);
            } else {
                w = Math.max(w, serverList.get(i + 1).weight);
            }
        }
        return w;
    }

    /**
     * アルゴリズム処理:
     * 一連のサーバーがあるとします。 S = {S0, S1, …, Sn-1}
     * 対応する重みがあり、変数 currentIndex は最後に選択されたサーバーを示します。
     * 重み currentWeight は 0 に初期化され、currentIndex は -1 に初期化され、初回の場合は最大の重みを持つサーバーが返されます,
     * 重みを継続的に減少させながら、ポーリングが終了するまで重みが 0 に戻るまで、返す適切なサーバーを見つけます。
     */
    public Server GetServer() {
        while (true) {
            currentIndex = (currentIndex + 1) % serverCount;
            if (currentIndex == 0) {
                currentWeight = currentWeight - gcdWeight;
                if (currentWeight <= 0) {
                    currentWeight = maxWeight;
                    if (currentWeight == 0)
                        return null;
                }
            }
            if (serverList.get(currentIndex).weight >= currentWeight) {
                return serverList.get(currentIndex);
            }
        }
    }

    /*
    * URLリストのF5プロパティを初期化します。
    * */
    public void init(List list) {
        if (serverList != null) {
            serverList.clear();
        } else {
            serverList = new ArrayList<Server>();
        }
        for (int i = 0; i < list.size(); i++) {
            String url[] = list.get(i).toString().split(":");
            String ip = url[0];
            int port = Integer.parseInt(url[1]);
            Server server = new Server(ip, 1, port);
            serverList.add(server);
        }
        currentIndex = -1;
        currentWeight = 0;
        serverCount = serverList.size();
        maxWeight = getMaxWeightForServers(serverList);
        gcdWeight = getGCDForServers(serverList);
    }


    class Server {
        public String ip;
        public int weight;//現在のサーバーの重量
        public int port;

        public Server(String ip, int weight, int port) {
            super();
            this.ip = ip;
            this.weight = weight;
            this.port = port;
        }

        public String getIp() {
            return ip;
        }

        public void setIp(String ip) {
            this.ip = ip;
        }

        public int getWeight() {
            return weight;
        }

        public void setWeight(int weight) {
            this.weight = weight;
        }

        public int getPort() {
            return port;
        }

        public void setPort(int port) {
            this.port = port;
        }
    }


    /*
    * テストして結果を確認する
    * */
    public static void main(String[] args) {
        ServerF5 obj = new ServerF5();
        List list = new ArrayList();
        list.add("11.2.43.4:8080");
        list.add("11.2.43.5:8081");
        list.add("11.2.43.6:8082");
        obj.init(list);

        Map<String, Integer> countResult = new HashMap<String, Integer>();

        for (int i = 0; i < 100; i++) {
            Server s = obj.GetServer();
            String log = "ip:" + s.ip + ";weight:" + s.weight;
            if (countResult.containsKey(log)) {
                countResult.put(log, countResult.get(log) + 1);
            } else {
                countResult.put(log, 1);
            }
            System.out.println(log);
        }

        for (Map.Entry<String, Integer> map : countResult.entrySet()) {
            System.out.println("Server " + map.getKey() + " request count: " + map.getValue());
        }
    }
}

これは、基本的な F5 負荷分散アルゴリズムの実装クラスです,
F5 ロード バランシングの実際の呼び出しツール クラスを見てみましょう。

//ここでインポートする必要があります
httpcore-4.1.4.jar
httpclient-4.1.3.jar


ServerF5Utils.java 

package F5Server;

import org.apache.http.HttpHost;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionRequest;
import org.apache.http.conn.ManagedClientConnection;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.protocol.BasicHttpContext;

import java.net.ConnectException;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

public class ServerF5Utils {

    private static ServerF5Utils context;
    private static List aliveUrlList;
    private Timer timer;
    private static ServerF5 serverF5;

    static {
        serverF5 = ServerF5.getContext();
    }

    public void updateAliveList(List urlLists) {
        try {
            //アクティブな URL リスト
            aliveUrlList = new ArrayList();

            //クライアント構成の URL のリスト。
            for (int i = 0; i < urlLists.size(); i++) {
                String[] urlport = urlLists.get(i).toString().split(":");

                String ipaddr = urlport[0];
                int port = Integer.parseInt(urlport[1]);

                HttpClient httpClient = new DefaultHttpClient();

                HttpRoute route = new HttpRoute(new HttpHost(ipaddr, port));
                ClientConnectionRequest connRequest = httpClient.getConnectionManager().requestConnection(route, null);
                ManagedClientConnection conn = connRequest.getConnection(10, TimeUnit.SECONDS);
                 
                try {
                    //クライアントが構成した URL リストを使用して接続を開きます。
                    conn.open(route, new BasicHttpContext(), new BasicHttpParams());
                } catch (ConnectException e) {
                    System.out.println("AliveList init refuse:[" + ipaddr + ":" + port + "]");
                    continue;
                }

                if (conn.isOpen()) {
           //テスト接続が成功すると、この接続はアクティブなリンクのリストに追加され                          ます。
                    aliveUrlList.add(urlLists.get(i).toString());
                    System.out.println("AliveList init Success:[" + this.aliveUrlList + "]");
                    conn.releaseConnection();
                    continue;
                } else {
                    continue;
                }
            }
        } catch (Exception e) {
            System.out.println("HttpConnection Alive Url List init fail,please check Http URL,Exception:" + e.toString());
        }
        System.out.println("HttpConnection Alive Url List List =[" + aliveUrlList + "]");
        //F5 サービスへのアクティブなリンクのリストを選択用に提供します。
        serverF5.init(aliveUrlList);
    }

    /**
     * アクティブな URL リンクがアルゴリズムによって選択されて返されます。
     */
    public String getServerUrl() {
        ServerF5.Server server = serverF5.GetServer();
        String ip = server.getIp();
        int port = server.getPort();
        String url = ip + ":" + port;
        return url;
    }

    /**
     * ユーザーが呼び出せるように、F5 ツール クラスのコンテキスト環境を初期化します。
     */
    public static ServerF5Utils getContext(final List urlLists) {
        if (context == null) {
            context = new ServerF5Utils();
            context.updateAliveList(urlLists);
            context.timer = new Timer();
            context.timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    context.updateAliveList(urlLists);
                }
            }, 50000, 300000);
        }
        return ServerF5Utils.context;
    }

    //Test
    public static void main(String[] args) {
        List<String> urls= new ArrayList<>();
        urls.add("11.2.43.3:8080");
        urls.add("11.2.43.4:8080");
        urls.add("11.2.43.5:8080");
        String shotUrl = ServerF5Utils.getContext(urls).getServerUrl();
        System.out.println("shotUrl="+shotUrl);
    }
}

テストおよび呼び出しメソッドは、サーバーによって構成された選択された URL のリストを F5 ツール クラス コンテキストに渡します。F5 ロード バランシングの初期化が成功した後、使用可能な選択された URL リンクを呼び出し元に返します。


发表回复

Thanks for your support to bet365fans!