From bb73b6955f107f07f42e1d3f8becc317be403e0b Mon Sep 17 00:00:00 2001 From: icanci Date: Tue, 31 Jan 2023 21:12:21 +0800 Subject: [PATCH 1/2] feat:icancifix --- .../ConsistencyHashLoadBalancing.java | 3 +- .../cache/loadbalancing/LBCacheHolder.java | 38 +++++++++++++++++++ .../loadbalancing/LoadBalancingCache.java | 8 +++- 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LBCacheHolder.java diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/ConsistencyHashLoadBalancing.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/ConsistencyHashLoadBalancing.java index 4ba556a..99c4d2a 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/ConsistencyHashLoadBalancing.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/ConsistencyHashLoadBalancing.java @@ -19,7 +19,7 @@ public class ConsistencyHashLoadBalancing extends LoadBalancingCache implements @Override public void init() { - + // } @Override @@ -29,6 +29,7 @@ public class ConsistencyHashLoadBalancing extends LoadBalancingCache implements @Override public Optional route(String appId) { + LBCacheHolder lbCacheHolder = LOAD_BALANCE_HOLDER_MAP.get(appId); return Optional.empty(); } } diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LBCacheHolder.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LBCacheHolder.java new file mode 100644 index 0000000..75c975d --- /dev/null +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LBCacheHolder.java @@ -0,0 +1,38 @@ +package cn.icanci.loopstack.ras.client.cache.loadbalancing; + +import cn.icanci.loopstack.ras.client.cache.model.ApplicationValue; + +import java.util.Comparator; +import java.util.Set; +import java.util.TreeSet; + +/** + * 负载均衡执行缓存 + * + * @author icanci + * @since 1.0 Created in 2023/01/30 20:08 + */ +public class LBCacheHolder { + /** + * 当前的所有缓存 + */ + private final Set applicationValues = new TreeSet<>(new Comparator() { + @Override + public int compare(ApplicationValue o1, ApplicationValue o2) { + return 0; + } + }); + /** + * 当前运行的ApplicationValue + */ + private ApplicationValue currClientValue; + /** + * 下一个需要被执行的ApplicationValue + */ + private ApplicationValue nextClientValue; + + public void refresh() { + + } + +} diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LoadBalancingCache.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LoadBalancingCache.java index d9f3961..60fdbf9 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LoadBalancingCache.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LoadBalancingCache.java @@ -2,6 +2,9 @@ package cn.icanci.loopstack.ras.client.cache.loadbalancing; import cn.icanci.loopstack.ras.client.cache.MetaCacheHolder; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + /** * 负载均衡缓存 * - 存储执行的过程和结果 @@ -11,5 +14,8 @@ import cn.icanci.loopstack.ras.client.cache.MetaCacheHolder; * @since 1.0 Created in 2023/01/23 10:24 */ public abstract class LoadBalancingCache extends MetaCacheHolder { - + /** + * 缓存 + */ + protected static final Map LOAD_BALANCE_HOLDER_MAP = new ConcurrentHashMap<>(); } -- Gitee From 7359636bc215f9458e5d942636074acde8a6aa29 Mon Sep 17 00:00:00 2001 From: icanci Date: Sat, 4 Feb 2023 19:14:10 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E8=B4=9F=E8=BD=BD=E5=9D=87=E8=A1=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../loopstack/ras/client/aop/RpcCallAop.java | 2 +- .../ras/client/cache/MetaCacheHolder.java | 8 +++ .../cache/holder/ApplicationHolder.java | 14 ----- .../cache/holder/RasRepositoryHolder.java | 2 + .../ConsistencyHashLoadBalancing.java | 1 - .../loadbalancing/FirstLoadBalancing.java | 35 +++++++++++- .../cache/loadbalancing/LBCacheHolder.java | 38 ------------- .../loadbalancing/LastLoadBalancing.java | 38 ++++++++++++- .../cache/loadbalancing/LoadBalancing.java | 2 +- .../loadbalancing/LoadBalancingCache.java | 20 ++++--- .../model/FirstLoadBalancingHolder.java | 44 +++++++++++++++ .../model/LastLoadBalancingHolder.java | 54 +++++++++++++++++++ .../model/LoadBalancingHolder.java | 19 +++++++ .../loadbalancing/model/package-info.java | 7 +++ 14 files changed, 219 insertions(+), 65 deletions(-) delete mode 100644 client/src/main/java/cn/icanci/loopstack/ras/client/cache/holder/ApplicationHolder.java delete mode 100644 client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LBCacheHolder.java create mode 100644 client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/FirstLoadBalancingHolder.java create mode 100644 client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/LastLoadBalancingHolder.java create mode 100644 client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/LoadBalancingHolder.java create mode 100644 client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/package-info.java diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/aop/RpcCallAop.java b/client/src/main/java/cn/icanci/loopstack/ras/client/aop/RpcCallAop.java index 8d056b9..9f37274 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/aop/RpcCallAop.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/aop/RpcCallAop.java @@ -28,7 +28,7 @@ public class RpcCallAop { long startTime = System.currentTimeMillis(); Object returnVal = pjp.proceed(); long endTime = System.currentTimeMillis(); - // TODO 只记录执行时间即可,但是要记录执行的内容 + // TODO 记录执行时间、执行的内容 return returnVal; } } diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/MetaCacheHolder.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/MetaCacheHolder.java index a873d9d..5df78f8 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/MetaCacheHolder.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/MetaCacheHolder.java @@ -5,6 +5,7 @@ import cn.icanci.loopstack.ras.client.cache.model.ApplicationValue; import cn.icanci.loopstack.ras.client.cache.model.ClientApplicationValue; import cn.icanci.loopstack.ras.client.properties.RasProperties; +import java.util.Collection; import java.util.Map; import javax.annotation.Resource; @@ -12,6 +13,7 @@ import javax.annotation.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; /** @@ -44,4 +46,10 @@ public abstract class MetaCacheHolder { * 只在一个bean写,在另一个bean读 */ protected static final Map CLIENT_APPLICATION_MAP = Maps.newConcurrentMap(); + /** + * 客户端缓存 读个bean共享数据 + * + * 只在一个bean写,在另一个bean读 + */ + protected static Collection LD_APPLICATIONS = Lists.newArrayList(); } diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/holder/ApplicationHolder.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/holder/ApplicationHolder.java deleted file mode 100644 index c620051..0000000 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/holder/ApplicationHolder.java +++ /dev/null @@ -1,14 +0,0 @@ -package cn.icanci.loopstack.ras.client.cache.holder; - -import cn.icanci.loopstack.ras.common.enums.LoadBalanceTypeEnum; - -/** - * @author icanci - * @since 1.0 Created in 2023/01/19 17:25 - */ -public class ApplicationHolder { - /** - * 负载均衡模式 - */ - private LoadBalanceTypeEnum loadBalanceType; -} diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/holder/RasRepositoryHolder.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/holder/RasRepositoryHolder.java index eaff9d5..3d17351 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/holder/RasRepositoryHolder.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/holder/RasRepositoryHolder.java @@ -273,6 +273,8 @@ public class RasRepositoryHolder extends MetaCacheHolder implements Initializing Set instances = clientApplication.getInstances(); CLIENT_APPLICATION_MAP.put(appId, builderClientApplication(loadBalanceType, clientApplication)); } + // 替换 + LD_APPLICATIONS = CLIENT_APPLICATION_MAP.values(); } /** diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/ConsistencyHashLoadBalancing.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/ConsistencyHashLoadBalancing.java index 99c4d2a..323b13a 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/ConsistencyHashLoadBalancing.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/ConsistencyHashLoadBalancing.java @@ -29,7 +29,6 @@ public class ConsistencyHashLoadBalancing extends LoadBalancingCache implements @Override public Optional route(String appId) { - LBCacheHolder lbCacheHolder = LOAD_BALANCE_HOLDER_MAP.get(appId); return Optional.empty(); } } diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/FirstLoadBalancing.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/FirstLoadBalancing.java index d330fc5..a08767d 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/FirstLoadBalancing.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/FirstLoadBalancing.java @@ -1,10 +1,16 @@ package cn.icanci.loopstack.ras.client.cache.loadbalancing; +import cn.icanci.loopstack.ras.client.cache.loadbalancing.model.FirstLoadBalancingHolder; 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.Optional; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Service; /** @@ -16,19 +22,44 @@ import org.springframework.stereotype.Service; @Service @LoadBalancingBean(LoadBalanceTypeEnum.FIRST) public class FirstLoadBalancing extends LoadBalancingCache implements LoadBalancing { + /** + * 数据缓存结果模型 + */ + private static Map HOLDER = new ConcurrentHashMap<>(); @Override public void init() { + // 1.根据路由表,找到所有的指定路由方式 + if (isLbAppEmpty()) { + return; + } + Set applicationValues = filterLbType(LoadBalanceTypeEnum.FIRST); + 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 FirstLoadBalancingHolder(apps)); + } + // 3.替换 + HOLDER = tempMap; } @Override public void refresh() { - + init(); } @Override public Optional route(String appId) { - return Optional.empty(); + FirstLoadBalancingHolder holder = HOLDER.get(appId); + if (holder == null) { + return Optional.empty(); + } + return Optional.ofNullable(holder.getNext()); } } diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LBCacheHolder.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LBCacheHolder.java deleted file mode 100644 index 75c975d..0000000 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LBCacheHolder.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.icanci.loopstack.ras.client.cache.loadbalancing; - -import cn.icanci.loopstack.ras.client.cache.model.ApplicationValue; - -import java.util.Comparator; -import java.util.Set; -import java.util.TreeSet; - -/** - * 负载均衡执行缓存 - * - * @author icanci - * @since 1.0 Created in 2023/01/30 20:08 - */ -public class LBCacheHolder { - /** - * 当前的所有缓存 - */ - private final Set applicationValues = new TreeSet<>(new Comparator() { - @Override - public int compare(ApplicationValue o1, ApplicationValue o2) { - return 0; - } - }); - /** - * 当前运行的ApplicationValue - */ - private ApplicationValue currClientValue; - /** - * 下一个需要被执行的ApplicationValue - */ - private ApplicationValue nextClientValue; - - public void refresh() { - - } - -} diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LastLoadBalancing.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LastLoadBalancing.java index 404709f..057b549 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LastLoadBalancing.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LastLoadBalancing.java @@ -1,10 +1,16 @@ package cn.icanci.loopstack.ras.client.cache.loadbalancing; +import cn.icanci.loopstack.ras.client.cache.loadbalancing.model.LastLoadBalancingHolder; 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.Optional; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Service; /** @@ -17,18 +23,46 @@ import org.springframework.stereotype.Service; @LoadBalancingBean(LoadBalanceTypeEnum.LAST) public class LastLoadBalancing extends LoadBalancingCache implements LoadBalancing { + /** + * 数据缓存结果模型 + */ + private static Map HOLDER = new ConcurrentHashMap<>(); + @Override public void init() { + // 1.根据路由表,找到所有的指定路由方式 + if (isLbAppEmpty()) { + return; + } + Set applicationValues = filterLbType(LoadBalanceTypeEnum.LAST); + 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 LastLoadBalancingHolder(apps)); + } + // 3.替换 + HOLDER = tempMap; } + + @Override public void refresh() { - + init(); } @Override public Optional route(String appId) { - return Optional.empty(); + LastLoadBalancingHolder holder = HOLDER.get(appId); + if (holder == null) { + return Optional.empty(); + } + return Optional.ofNullable(holder.getNext()); } } diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LoadBalancing.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LoadBalancing.java index fb29013..b0fd323 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LoadBalancing.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LoadBalancing.java @@ -23,7 +23,7 @@ public interface LoadBalancing { void refresh(); /** - * 根据AppId路由到合适的 + * 根据AppId路由到合适App信息 * * @param appId appId * @return 返回目标实现 diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LoadBalancingCache.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LoadBalancingCache.java index 60fdbf9..0cc99c7 100644 --- a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LoadBalancingCache.java +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LoadBalancingCache.java @@ -1,9 +1,13 @@ package cn.icanci.loopstack.ras.client.cache.loadbalancing; import cn.icanci.loopstack.ras.client.cache.MetaCacheHolder; +import cn.icanci.loopstack.ras.client.cache.model.ClientApplicationValue; +import cn.icanci.loopstack.ras.common.enums.LoadBalanceTypeEnum; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.collections4.CollectionUtils; /** * 负载均衡缓存 @@ -14,8 +18,12 @@ import java.util.concurrent.ConcurrentHashMap; * @since 1.0 Created in 2023/01/23 10:24 */ public abstract class LoadBalancingCache extends MetaCacheHolder { - /** - * 缓存 - */ - protected static final Map LOAD_BALANCE_HOLDER_MAP = new ConcurrentHashMap<>(); + + protected static boolean isLbAppEmpty() { + return CollectionUtils.isEmpty(LD_APPLICATIONS); + } + + protected static Set filterLbType(LoadBalanceTypeEnum loadBalanceType) { + return LD_APPLICATIONS.stream().filter(value -> value.getLoadBalanceType() == loadBalanceType).collect(Collectors.toSet()); + } } diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/FirstLoadBalancingHolder.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/FirstLoadBalancingHolder.java new file mode 100644 index 0000000..f901ae0 --- /dev/null +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/FirstLoadBalancingHolder.java @@ -0,0 +1,44 @@ +package cn.icanci.loopstack.ras.client.cache.loadbalancing.model; + +import cn.icanci.loopstack.ras.client.cache.model.ApplicationValue; + +import java.util.Optional; +import java.util.Set; + +/** + * + * @author icanci + * @since 1.0 Created in 2023/02/04 17:44 + */ +public class FirstLoadBalancingHolder implements LoadBalancingHolder { + /** + * 应用列表 + */ + private final Set applications; + + /** + * 下一个需要被调用的 + */ + private ApplicationValue next; + + public FirstLoadBalancingHolder(Set applications) { + this.applications = applications; + setNext(); + } + + private void setNext() { + Optional optional = applications.stream().filter(app -> app.getOnline() == 0 && app.getIsDelete() == 0).findFirst(); + if (optional.isPresent()) { + this.next = optional.get(); + } else { + optional = applications.stream().filter(app -> app.getOnline() == 0).findFirst(); + optional.ifPresent(applicationValue -> this.next = applicationValue); + } + } + + @Override + public ApplicationValue getNext() { + return next; + } + +} diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/LastLoadBalancingHolder.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/LastLoadBalancingHolder.java new file mode 100644 index 0000000..82693ea --- /dev/null +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/LastLoadBalancingHolder.java @@ -0,0 +1,54 @@ +package cn.icanci.loopstack.ras.client.cache.loadbalancing.model; + +import cn.icanci.loopstack.ras.client.cache.model.ApplicationValue; + +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.collections4.CollectionUtils; + +/** + * + * @author icanci + * @since 1.0 Created in 2023/02/04 17:44 + */ +public class LastLoadBalancingHolder implements LoadBalancingHolder { + /** + * 应用列表 + */ + private final Set applications; + + /** + * 下一个需要被调用的 + */ + private ApplicationValue next; + + public LastLoadBalancingHolder(Set applications) { + this.applications = applications; + setNext(); + } + + private void setNext() { + List apps = applications.stream().filter(app -> app.getOnline() == 0 && app.getIsDelete() == 0).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(apps)) { + this.next = apps.get(apps.size() - 1); + } else { + apps = applications.stream().filter(app -> app.getOnline() == 0).collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(apps)) { + this.next = apps.get(apps.size() - 1); + } + } + } + + @Override + public ApplicationValue getNext() { + // 先拿出下一个 + ApplicationValue tmpNext = next; + // 设置下一个 + setNext(); + // 返回当前的 + return tmpNext; + } + +} diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/LoadBalancingHolder.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/LoadBalancingHolder.java new file mode 100644 index 0000000..df1d19a --- /dev/null +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/LoadBalancingHolder.java @@ -0,0 +1,19 @@ +package cn.icanci.loopstack.ras.client.cache.loadbalancing.model; + +import cn.icanci.loopstack.ras.client.cache.model.ApplicationValue; + +/** + * 获取下一个需要被调用的ApplicationValue + * + * @author icanci + * @since 1.0 Created in 2023/02/04 17:44 + */ +public interface LoadBalancingHolder { + + /** + * 获取下一个需要被调用的ApplicationValue + * + * @return ApplicationValue + */ + ApplicationValue getNext(); +} diff --git a/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/package-info.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/package-info.java new file mode 100644 index 0000000..adaef62 --- /dev/null +++ b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/model/package-info.java @@ -0,0 +1,7 @@ +/** + * LoadBalancing 算法执行模型 + * + * @author icanci + * @since 1.0 Created in 2023/02/01 09:37 + */ +package cn.icanci.loopstack.ras.client.cache.loadbalancing.model; \ No newline at end of file -- Gitee