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 b09b31b87ce2a826d24f78d6693d4e31b3a315ee..3aefe5beb020aa893ec447f65aa8e54a3bb648a4 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 4cef718f5ae78fcb53627f7ebeaa52aca339be20..cadb5d22d158521afbc66425842b08eef1cb26e8 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 5b45a5473af260bf3b4a32d3d659e23cb3d64ec8..1dcd575905eb6ee4e69bf37f7811d0424e05f4c1 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 ecf7a567d13fd7f4446e7d0f5cba649d5effc3eb..8bb3ad3780afb4cf4fd0c4f65f66c9ec574cc4b4 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 39744e31fcb224696fbd04c4d5d9651576e7164d..ec5dda39852a7ad96c0e40562cb6c14d7a388957 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 d43505faabb49d91dda740b6a99c40bee5244de0..f9394f3194d522a296771e8afb1685c26f21e74e 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 0000000000000000000000000000000000000000..9e1339d58bc37812af9d7470f561e9b8ec16d485 --- /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 0000000000000000000000000000000000000000..8df8e893e0ba98080e0fc7c2f3ab0f3a0aca6d1d --- /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