1.負載均衡,實現輪詢機制 2.路由命中的機率分析

一、代碼實現

詳見 我的github:https://github.com/sunxiaoning90/com_live_test

 

二、測試結果

10次訪問

1W次訪問

 

package com.live.test.api.core.serverloadbalance.routeAcc;
     
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.concurrent.ConcurrentHashMap;
     
    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
     
    /**
    * 路由訪問 對象
    *
    * @author live
    * @2019年12月9日 @下午2:46:59
    */
    public class RouteAcc {
    private Map<String, RouteNodeAcc> accMap;// route:routeNodeAcc
    private String route;// 路由 module.service.method
    private String keepCountRouteNode;// 連續命中最大值是哪個路由節點 module.service.method.server
    private long keepCount;// 連續命中最大值
    private long count;// 命中總數
    private String last;// 最後一次命中哪個路由節點:module.service.method.server
     
    private RouteAcc() {
    this.accMap = new ConcurrentHashMap<String, RouteNodeAcc>();
    }
     
    public RouteAcc(String route) {
    this();
    this.setRoute(route);
    }
     
    public String getRoute() {
    return route;
    }
     
    public void setRoute(String abc) {
    this.route = abc;
    }
     
    public String getLast() {
    return last;
    }
     
    public void setLast(String last) {
    this.last = last;
    }
     
    public void put(String route) {
    this.incrementCount();
     
    RouteNodeAcc acc;
    if (!this.accMap.containsKey(route)) {
    acc = new RouteNodeAcc(route);
    this.accMap.put(route, acc);
    } else {
    acc = this.accMap.get(route);
    }
    acc.incrementCount();
     
    if (route.equals(this.getLast())) {
    acc.incrementKeepCountTmp();
    } else {
    this.setLast(route);// 設置最後一次訪問
    accMap.get(route).setKeepCountTmpReset();
    }
     
    if (acc.getKeepCount() > this.getKeepCount()) {// 設置命中最大值
    this.setKeepCountAbcd(acc.getRouteNode());
    this.setKeepCount(acc.getKeepCount());
    }
    }
     
    public String getKeepCountRouteNode() {
    return keepCountRouteNode;
    }
     
    public void setKeepCountAbcd(String keepCount) {
    this.keepCountRouteNode = keepCount;
    }
     
    public long getKeepCount() {
    return keepCount;
    }
     
    public void setKeepCount(long keepCount) {
    this.keepCount = keepCount;
    }
     
    public long getCount() {
    return count;
    }
     
    public void setCount(long count) {
    this.count = count;
    }
     
    public void incrementCount() {
    this.setCount(this.getCount() + 1);
    }
     
    public JSONObject toJson() {
    JSONObject json = new JSONObject();
    json.put("route(路由)", this.getRoute());
    json.put("count(命中總數)", this.getCount());
    json.put("keepCountRouteNode(最高連續命中路由節點)", this.getKeepCountRouteNode());
    json.put("keepCount(最高連續命中計數器)", this.getKeepCount());
     
    JSONArray accArray = new JSONArray();
    Iterator<Entry<String, RouteNodeAcc>> iterator = this.accMap.entrySet().iterator();
    while (iterator.hasNext()) {
    Entry<String, RouteNodeAcc> next = iterator.next();
    JSONObject accJson = new JSONObject();
    accJson.put(next.getKey(), next.getValue().toJson());
    accArray.add(accJson);
    }
    json.put("routeNodeAcc", accArray);
     
    return json;
    }
    }

 74  ...core/src/main/java/com/live/test/api/core/serverloadbalance/routeAcc/RouteAccManager.java 

    @@ -0,0 +1,74 @@
    package com.live.test.api.core.serverloadbalance.routeAcc;
     
    import java.util.Date;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.concurrent.ConcurrentHashMap;
     
    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
     
    /**
    * 路由訪問管理
    *
    * @author live
    * @2019年12月3日 @上午11:01:56
    */
    public class RouteAccManager {
     
    /**
    * 路由訪問記錄: k:v鍵值對 route: routeAcc
    */
    private Map<String, RouteAcc> accPoMap = new ConcurrentHashMap<String, RouteAcc>();
    private Date date;
     
    private RouteAccManager() {
    setDate(new Date());
    }
     
    public static RouteAccManager getInstance() {
    return SingletonHolder.instance;
    }
     
    private static class SingletonHolder {
    private static RouteAccManager instance = new RouteAccManager();
    }
     
    public void put(String routeNode) {
    String route = routeNode.substring(0, routeNode.lastIndexOf("."));
     
    if (!this.accPoMap.containsKey(route)) {
    this.accPoMap.put(route, new RouteAcc(route));
    }
     
    RouteAcc accPo = this.accPoMap.get(route);
    accPo.put(routeNode);
    }
     
    public Date getDate() {
    return date;
    }
     
    public void setDate(Date date) {
    this.date = date;
    }
     
    @SuppressWarnings("deprecation")
    public JSONObject toJson() {
    JSONObject json = new JSONObject();
    json.put("date(開始時間)", this.getDate().toLocaleString());
     
    JSONArray routeAccArray = new JSONArray();
    Iterator<Entry<String, RouteAcc>> iterator = this.accPoMap.entrySet().iterator();
    while (iterator.hasNext()) {
    Entry<String, RouteAcc> next = iterator.next();
    JSONObject routeAcc = new JSONObject();
    routeAcc.put(next.getKey(), next.getValue().toJson());
    routeAccArray.add(routeAcc);
    }
     
    json.put("routeAccs", routeAccArray);
    return json;
    }
    }

 81  ...pi_core/src/main/java/com/live/test/api/core/serverloadbalance/routeAcc/RouteNodeAcc.java 

    @@ -0,0 +1,81 @@
    package com.live.test.api.core.serverloadbalance.routeAcc;
     
    import com.alibaba.fastjson.JSONObject;
     
    /**
    * 路由節點訪問 對象
    *
    * @author live
    * @2019年12月10日 @下午3:26:43
    */
    public class RouteNodeAcc {
     
    private String routeNode;// 路由節點 module.service.method.server
    private long keepCount;// 最高連續命中計數器
    private long count;// 命中總數數計數器
    private long keepCountTmp;// 臨時連續命中計數器,當 臨時連續命中計數器 大於 最高連續命中計數器時,刷新 最高連續命中計數器
     
    private RouteNodeAcc() {
    }
     
    public RouteNodeAcc(String routeNode) {
    this();
    this.setRouteNode(routeNode);
    }
     
    public String getRouteNode() {
    return routeNode;
    }
     
    public void setRouteNode(String routeNode) {
    this.routeNode = routeNode;
    }
     
    public long getKeepCountTmp() {
    return keepCountTmp;
    }
     
    public void setKeepCountTmp(long keepCountTmp) {
    this.keepCountTmp = keepCountTmp;
    if (keepCountTmp > this.getKeepCount()) {// 當 臨時連續命中計數器 大於 最高連續命中計數器時,刷新 最高連續命中計數器
    this.setKeepCount(keepCountTmp);
    }
    }
     
    public void incrementCount() {
    this.setCount(this.getCount() + 1);
    }
     
    public long getKeepCount() {
    return keepCount;
    }
     
    public void setKeepCount(long keepCount) {
    this.keepCount = keepCount;
    }
     
    public long getCount() {
    return count;
    }
     
    public void setCount(long count) {
    this.count = count;
    }
     
    public void setKeepCountTmpReset() {
    this.setKeepCountTmp(0);
    }
     
    public void incrementKeepCountTmp() {
    this.setKeepCountTmp(this.getKeepCountTmp() + 1);
    }
     
    public JSONObject toJson() {
    JSONObject json = new JSONObject();
    json.put("routeNode(路由節點)", routeNode);
    json.put("count(命中總數數計數器)", count);
    json.put("keepCountTmp(臨時連續命中計數器)", keepCountTmp);
    json.put("keepCount(最高連續命中計數器)", keepCount);
    return json;
    }
    }

 36  ..._core/src/main/java/com/live/test/api/core/serverloadbalance/serverdispatcher/Client.java 

    @@ -0,0 +1,36 @@
    package com.live.test.api.core.serverloadbalance.serverdispatcher;
     
    import com.live.test.api.core.serverloadbalance.serverdispatcher.impl.PollServerDispatcher;
     
    public class Client {
    public static void main(String[] args) {
    new Client().test1();
    }
     
    private void test1() {
    int min = 1;
    int max = 5;
    IServerDispatcher sd = new PollServerDispatcher(min, max);
     
    new java.lang.Thread(new Runnable() {
     
    @Override
    public void run() {
    for (int i = 1; i <= 10; i++) {
    testGetNext(sd);
    }
    }
    }).start();
     
    for (int i = 1; i <= 10; i++) {
    testGetNext(sd);
    }
    }
     
    private void testGetNext(IServerDispatcher sd) {
    // int next = sd.getNext();
    // long count = sd.getCount();
    // int last = sd.getLast();
    // System.out.println("count:" + count + ",last:" + last + ",next:" + next);
    }
    }

 34  ...ain/java/com/live/test/api/core/serverloadbalance/serverdispatcher/IServerDispatcher.java 

    @@ -0,0 +1,34 @@
    package com.live.test.api.core.serverloadbalance.serverdispatcher;
     
    public interface IServerDispatcher {
     
    /**
    * 初始化最小值
    * @return
    */
    void setMin(int min);
     
    /**
    * 初始化最大值
    * @return
    */
    void setMax(int max);
     
    /**
    * 最後一次取值
    * @return
    */
    int getLast();
     
    /**
    * 下一次取值
    * @return
    */
    int getNext();
     
    /**
    * 自啓動後,訪問過多少次
    * @return
    */
    long getCount();
    }

 72  .../live/test/api/core/serverloadbalance/serverdispatcher/impl/KeepLastServerDispatcher.java 

    @@ -0,0 +1,72 @@
    package com.live.test.api.core.serverloadbalance.serverdispatcher.impl;
     
    import com.live.test.api.core.serverloadbalance.serverdispatcher.IServerDispatcher;
     
    /**
    * 負載均衡-每次獲取上一次的路由:
    * @author live
    * @2019年12月10日 @下午12:22:38
    */
    public class KeepLastServerDispatcher implements IServerDispatcher {
     
    private int max; // max 和 min必須填寫
    private int min;
    private int last;
     
    private long count = 0;//自啓動後,訪問過多少次
     
    public KeepLastServerDispatcher() {
     
    }
     
    public KeepLastServerDispatcher(int min, int max) {
    this();
    this.setMin(min);
    this.setMax(max);
    }
     
    public int getMax() {
    return max;
    }
     
    public int getMin() {
    return min;
    }
     
    @Override
    public void setMin(int min) {
    this.min = min;
    }
     
    @Override
    public void setMax(int max) {
    this.max = max;
    }
     
    @Override
    public int getLast() {
    return this.last;
    }
     
    @Override
    public synchronized int getNext() {
    return this.getLast();
    }
     
    public void setLast(int last) {
    this.last = last;
    }
     
    public long getCount() {
    return count;
    }
     
    public void setCount(long count) {
    this.count = count;
    }
     
    public void incrementCount() {
    this.setCount(this.getCount()+1);
    }
     
    }

 88  .../com/live/test/api/core/serverloadbalance/serverdispatcher/impl/PollServerDispatcher.java 

    @@ -0,0 +1,88 @@
    package com.live.test.api.core.serverloadbalance.serverdispatcher.impl;
     
    import com.live.test.api.core.serverloadbalance.serverdispatcher.IServerDispatcher;
     
    /**
    * 負載均衡-輪詢獲取路由:1,2,3,1,2,3...
    * @author live
    * @2019年12月10日 @下午12:22:38
    */
    public class PollServerDispatcher implements IServerDispatcher {
     
    private int max; // max 和 min必須填寫
    private int min;
    private int last;
     
    private long count = 0;//自啓動後,訪問過多少次
     
    private PollServerDispatcher() {
     
    }
     
    public PollServerDispatcher(int min, int max) {
    this();
    this.setMin(min);
    this.setMax(max);
    }
     
    public int getMax() {
    return max;
    }
     
    public int getMin() {
    return min;
    }
     
    @Override
    public void setMin(int min) {
    this.min = min;
    }
     
    @Override
    public void setMax(int max) {
    this.max = max;
    }
     
    @Override
    public int getLast() {
    return this.last;
    }
     
    @Override
    public synchronized int getNext() {
    int next ;// 取值
    if(this.getCount() == 0) {// 第一次取值取最小值
    next = this.getMin();
    }else {
    next = this.getLast() + 1;
    }
     
    if (next > this.getMax()) {// 若取值小於最小值,取最小值
    next = this.getMin();
    } else if (next < this.getMin()) {// 若取值小於最小值,取最小值
    next = this.getMin();
    }
     
    System.out.println("上一次概況:count:" + this.getCount() + ",last:" + this.getLast()+",next:" + next);
    this.setLast(next);// 刷新 last
    this.incrementCount();//刷新總數
    return next;
    }
     
    public void setLast(int last) {
    this.last = last;
    }
     
    public long getCount() {
    return count;
    }
     
    public void setCount(long count) {
    this.count = count;
    }
     
    public void incrementCount() {
    this.setCount(this.getCount()+1);
    }
     
    }
發佈了49 篇原創文章 · 獲贊 4 · 訪問量 3712
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章