From 03260631b1cfe5a6efbdcd794ed5d9726d9d5561 Mon Sep 17 00:00:00 2001 From: icanci Date: Sat, 4 Feb 2023 22:31:17 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=80=E6=96=B0=E8=B0=83=E7=94=A8=E5=92=8C?= =?UTF-8?q?=E6=9C=80=E8=BF=91=E6=9C=AA=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FastestCallSpeedLoadBalancing.java | 2 +- .../LeastFrequentlyUsedLoadBalancing.java | 38 +++++- .../LeastRecentlyUsedLoadBalancing.java | 36 +++++- .../loadbalancing/LoadBalancingSupport.java | 1 + .../loadbalancing/RandomLoadBalancing.java | 2 +- .../FastestCallSpeedLoadBalancingHolder.java | 2 +- ...eastFrequentlyUsedLoadBalancingHolder.java | 121 ++++++++++++++++++ .../LeastRecentlyUsedLoadBalancingHolder.java | 121 ++++++++++++++++++ 8 files changed, 313 insertions(+), 10 deletions(-) create mode 100644 client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/LeastFrequentlyUsedLoadBalancingHolder.java create mode 100644 client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/LeastRecentlyUsedLoadBalancingHolder.java diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/FastestCallSpeedLoadBalancing.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/FastestCallSpeedLoadBalancing.java index b09b31b..3aefe5b 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/FastestCallSpeedLoadBalancing.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/FastestCallSpeedLoadBalancing.java @@ -33,7 +33,7 @@ public class FastestCallSpeedLoadBalancing extends LoadBalancingCache implements if (isLbAppEmpty()) { return; } - Set applicationValues = filterLbType(LoadBalanceTypeEnum.FIRST); + Set applicationValues = filterLbType(LoadBalanceTypeEnum.FASTEST_CALL_SPEED); if (CollectionUtils.isEmpty(applicationValues)) { return; diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LeastFrequentlyUsedLoadBalancing.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LeastFrequentlyUsedLoadBalancing.java index 4cef718..cadb5d2 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LeastFrequentlyUsedLoadBalancing.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LeastFrequentlyUsedLoadBalancing.java @@ -1,8 +1,16 @@ package cn.icanci.loopstack.ras.client.cache.loadbalancing; +import cn.icanci.loopstack.ras.client.cache.loadbalancing.model.LeastFrequentlyUsedLoadBalancingHolder; import cn.icanci.loopstack.ras.client.cache.loadbalancing.model.LoadBalancingHolder; +import cn.icanci.loopstack.ras.client.cache.model.ApplicationValue; +import cn.icanci.loopstack.ras.client.cache.model.ClientApplicationValue; import cn.icanci.loopstack.ras.common.enums.LoadBalanceTypeEnum; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Service; /** @@ -14,19 +22,41 @@ import org.springframework.stereotype.Service; @Service @LoadBalancingBean(LoadBalanceTypeEnum.LEAST_FREQUENTLY_USED) public class LeastFrequentlyUsedLoadBalancing extends LoadBalancingCache implements LoadBalancing { + /** + * 数据缓存结果模型 + */ + private static Map HOLDER = new ConcurrentHashMap<>(); @Override public void init() { - + // 1.根据路由表,找到所有的指定路由方式 + if (isLbAppEmpty()) { + return; + } + Set applicationValues = filterLbType(LoadBalanceTypeEnum.LEAST_FREQUENTLY_USED); + + if (CollectionUtils.isEmpty(applicationValues)) { + return; + } + Map tempMap = new ConcurrentHashMap<>(); + // 2.遍历应用表,构建缓存 + for (ClientApplicationValue applicationValue : applicationValues) { + String appId = applicationValue.getAppId(); + Set apps = applicationValue.getApplicationValues(); + tempMap.put(appId, new LeastFrequentlyUsedLoadBalancingHolder(apps)); + } + // 3.替换 + HOLDER = tempMap; } @Override public void refresh() { - + init(); } @Override protected LoadBalancingHolder getHolder(String appId) { - return null; + return HOLDER.get(appId); } -} + +} \ No newline at end of file diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LeastRecentlyUsedLoadBalancing.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LeastRecentlyUsedLoadBalancing.java index 5b45a54..1dcd575 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LeastRecentlyUsedLoadBalancing.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LeastRecentlyUsedLoadBalancing.java @@ -1,8 +1,16 @@ package cn.icanci.loopstack.ras.client.cache.loadbalancing; +import cn.icanci.loopstack.ras.client.cache.loadbalancing.model.LeastRecentlyUsedLoadBalancingHolder; import cn.icanci.loopstack.ras.client.cache.loadbalancing.model.LoadBalancingHolder; +import cn.icanci.loopstack.ras.client.cache.model.ApplicationValue; +import cn.icanci.loopstack.ras.client.cache.model.ClientApplicationValue; import cn.icanci.loopstack.ras.common.enums.LoadBalanceTypeEnum; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Service; /** @@ -14,19 +22,41 @@ import org.springframework.stereotype.Service; @Service @LoadBalancingBean(LoadBalanceTypeEnum.LEAST_RECENTLY_USED) public class LeastRecentlyUsedLoadBalancing extends LoadBalancingCache implements LoadBalancing { + /** + * 数据缓存结果模型 + */ + private static Map HOLDER = new ConcurrentHashMap<>(); @Override public void init() { - + // 1.根据路由表,找到所有的指定路由方式 + if (isLbAppEmpty()) { + return; + } + Set applicationValues = filterLbType(LoadBalanceTypeEnum.LEAST_RECENTLY_USED); + + if (CollectionUtils.isEmpty(applicationValues)) { + return; + } + Map tempMap = new ConcurrentHashMap<>(); + // 2.遍历应用表,构建缓存 + for (ClientApplicationValue applicationValue : applicationValues) { + String appId = applicationValue.getAppId(); + Set apps = applicationValue.getApplicationValues(); + tempMap.put(appId, new LeastRecentlyUsedLoadBalancingHolder(apps)); + } + // 3.替换 + HOLDER = tempMap; } @Override public void refresh() { - + init(); } @Override protected LoadBalancingHolder getHolder(String appId) { - return null; + return HOLDER.get(appId); } + } diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LoadBalancingSupport.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LoadBalancingSupport.java index ecf7a56..8bb3ad3 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LoadBalancingSupport.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LoadBalancingSupport.java @@ -121,6 +121,7 @@ public final class LoadBalancingSupport extends MetaCacheHolder { } /** + * TODO 这里多创建了一个对象 * 获取端口号 * * @param href 网址 diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/RandomLoadBalancing.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/RandomLoadBalancing.java index 39744e3..ec5dda3 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/RandomLoadBalancing.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/RandomLoadBalancing.java @@ -33,7 +33,7 @@ public class RandomLoadBalancing extends LoadBalancingCache implements LoadBalan if (isLbAppEmpty()) { return; } - Set applicationValues = filterLbType(LoadBalanceTypeEnum.FIRST); + Set applicationValues = filterLbType(LoadBalanceTypeEnum.RANDOM); if (CollectionUtils.isEmpty(applicationValues)) { return; diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/FastestCallSpeedLoadBalancingHolder.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/FastestCallSpeedLoadBalancingHolder.java index d43505f..f9394f3 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/FastestCallSpeedLoadBalancingHolder.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/FastestCallSpeedLoadBalancingHolder.java @@ -108,8 +108,8 @@ public class FastestCallSpeedLoadBalancingHolder extends LoadBalancingHolder { callRuntimeQueue.add(runtime); double average = callRuntimeQueue.stream().mapToDouble(Long::longValue).average().orElse(0D); InnerFastestCallSpeedLoadBalancingHolder temp = new InnerFastestCallSpeedLoadBalancingHolder(applicationValue, (long) average, callRuntimeQueue); - applicationHolder.removeIf(appHolder -> StringUtils.equals(appHolder.getApplicationValue().getAddress(), ip) && appHolder.getApplicationValue().getPort() == port); applicationHolder.add(temp); + applicationHolder.remove(holder); } /** diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/LeastFrequentlyUsedLoadBalancingHolder.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/LeastFrequentlyUsedLoadBalancingHolder.java new file mode 100644 index 0000000..9e1339d --- /dev/null +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/LeastFrequentlyUsedLoadBalancingHolder.java @@ -0,0 +1,121 @@ +package cn.icanci.loopstack.ras.client.cache.loadbalancing.model; + +import cn.icanci.loopstack.ras.client.cache.model.ApplicationValue; + +import java.util.*; + +/** + * @author icanci + * @since 1.0 Created in 2023/02/04 22:12 + */ +public class LeastFrequentlyUsedLoadBalancingHolder extends LoadBalancingHolder { + /** + * 应用列表 + */ + private final Set applicationHolder; + + public LeastFrequentlyUsedLoadBalancingHolder(Set applications) { + // 初始化 + applicationHolder = new TreeSet<>(new Comparator() { + @Override + public int compare(InnerLeastFrequentlyUsedLoadBalancingHolder o1, InnerLeastFrequentlyUsedLoadBalancingHolder o2) { + return o2.getLastInvokeTime().compareTo(o1.getLastInvokeTime()); + } + }); + init(applications); + // 设置下一个 + setNext(); + } + + /** + * 初始化 + * + * @param applications applications + */ + private void init(Set applications) { + Date currentTime = new Date(); + for (ApplicationValue application : applications) { + applicationHolder.add(new InnerLeastFrequentlyUsedLoadBalancingHolder(application, currentTime)); + } + } + + /** + * 设置下一个需要加载的数据 + */ + @Override + public void setNext() { + Optional speedOptional = applicationHolder.stream() + .filter(appHolder -> appHolder.getApplicationValue().getOnline() == 0 && appHolder.getApplicationValue().getIsDelete() == 0).findFirst(); + if (speedOptional.isPresent()) { + this.next = speedOptional.get().getApplicationValue(); + fixHolderTreeSet(speedOptional.get()); + } else { + speedOptional = applicationHolder.stream().filter(appHolder -> appHolder.getApplicationValue().getOnline() == 0).findFirst(); + if (speedOptional.isPresent()) { + this.next = speedOptional.get().getApplicationValue(); + fixHolderTreeSet(speedOptional.get()); + } else { + speedOptional = applicationHolder.stream().filter(appHolder -> appHolder.getApplicationValue().getOnline() == 1).findFirst(); + if (speedOptional.isPresent()) { + this.next = speedOptional.get().getApplicationValue(); + fixHolderTreeSet(speedOptional.get()); + } + } + } + } + + /** + * 树优化 + * + * @param holder holder + */ + private void fixHolderTreeSet(InnerLeastFrequentlyUsedLoadBalancingHolder holder) { + InnerLeastFrequentlyUsedLoadBalancingHolder temp = new InnerLeastFrequentlyUsedLoadBalancingHolder(holder.getApplicationValue(), new Date()); + applicationHolder.add(temp); + applicationHolder.remove(holder); + } + + /** + * 内部对象 + */ + public static class InnerLeastFrequentlyUsedLoadBalancingHolder { + /** + * app 信息 + */ + private final ApplicationValue applicationValue; + + /** + * 上次调用的时间 + */ + private final Date lastInvokeTime; + + public InnerLeastFrequentlyUsedLoadBalancingHolder(ApplicationValue applicationValue, Date lastInvokeTime) { + this.applicationValue = applicationValue; + this.lastInvokeTime = lastInvokeTime; + } + + public ApplicationValue getApplicationValue() { + return applicationValue; + } + + public Date getLastInvokeTime() { + return lastInvokeTime; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + InnerLeastFrequentlyUsedLoadBalancingHolder that = (InnerLeastFrequentlyUsedLoadBalancingHolder) o; + return Objects.equals(applicationValue, that.applicationValue); + } + + @Override + public int hashCode() { + return Objects.hash(applicationValue); + } + } + +} diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/LeastRecentlyUsedLoadBalancingHolder.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/LeastRecentlyUsedLoadBalancingHolder.java new file mode 100644 index 0000000..8df8e89 --- /dev/null +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/LeastRecentlyUsedLoadBalancingHolder.java @@ -0,0 +1,121 @@ +package cn.icanci.loopstack.ras.client.cache.loadbalancing.model; + +import cn.icanci.loopstack.ras.client.cache.model.ApplicationValue; + +import java.util.*; + +/** + * @author icanci + * @since 1.0 Created in 2023/02/04 22:27 + */ +public class LeastRecentlyUsedLoadBalancingHolder extends LoadBalancingHolder { + /** + * 应用列表 + */ + private final Set applicationHolder; + + public LeastRecentlyUsedLoadBalancingHolder(Set applications) { + // 初始化 + applicationHolder = new TreeSet<>(new Comparator() { + @Override + public int compare(InnerLeastRecentlyUsedLoadBalancingHolder o1, InnerLeastRecentlyUsedLoadBalancingHolder o2) { + return o1.getLastInvokeTime().compareTo(o2.getLastInvokeTime()); + } + }); + init(applications); + // 设置下一个 + setNext(); + } + + /** + * 初始化 + * + * @param applications applications + */ + private void init(Set applications) { + Date currentTime = new Date(); + for (ApplicationValue application : applications) { + applicationHolder.add(new InnerLeastRecentlyUsedLoadBalancingHolder(application, currentTime)); + } + } + + /** + * 设置下一个需要加载的数据 + */ + @Override + public void setNext() { + Optional speedOptional = applicationHolder.stream() + .filter(appHolder -> appHolder.getApplicationValue().getOnline() == 0 && appHolder.getApplicationValue().getIsDelete() == 0).findFirst(); + if (speedOptional.isPresent()) { + this.next = speedOptional.get().getApplicationValue(); + fixHolderTreeSet(speedOptional.get()); + } else { + speedOptional = applicationHolder.stream().filter(appHolder -> appHolder.getApplicationValue().getOnline() == 0).findFirst(); + if (speedOptional.isPresent()) { + this.next = speedOptional.get().getApplicationValue(); + fixHolderTreeSet(speedOptional.get()); + } else { + speedOptional = applicationHolder.stream().filter(appHolder -> appHolder.getApplicationValue().getOnline() == 1).findFirst(); + if (speedOptional.isPresent()) { + this.next = speedOptional.get().getApplicationValue(); + fixHolderTreeSet(speedOptional.get()); + } + } + } + } + + /** + * 树优化 + * + * @param holder holder + */ + private void fixHolderTreeSet(InnerLeastRecentlyUsedLoadBalancingHolder holder) { + InnerLeastRecentlyUsedLoadBalancingHolder temp = new InnerLeastRecentlyUsedLoadBalancingHolder(holder.getApplicationValue(), new Date()); + applicationHolder.add(temp); + applicationHolder.remove(holder); + } + + /** + * 内部对象 + */ + public static class InnerLeastRecentlyUsedLoadBalancingHolder { + /** + * app 信息 + */ + private final ApplicationValue applicationValue; + + /** + * 上次调用的时间 + */ + private final Date lastInvokeTime; + + public InnerLeastRecentlyUsedLoadBalancingHolder(ApplicationValue applicationValue, Date lastInvokeTime) { + this.applicationValue = applicationValue; + this.lastInvokeTime = lastInvokeTime; + } + + public ApplicationValue getApplicationValue() { + return applicationValue; + } + + public Date getLastInvokeTime() { + return lastInvokeTime; + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + InnerLeastRecentlyUsedLoadBalancingHolder that = (InnerLeastRecentlyUsedLoadBalancingHolder) o; + return Objects.equals(applicationValue, that.applicationValue); + } + + @Override + public int hashCode() { + return Objects.hash(applicationValue); + } + } + +} \ No newline at end of file -- Gitee