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 8d056b9c5a1643329c12d997bba95ab426253a9c..9f372746c13ea6ca826323bc88ba9d3e0a3d2c0f 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 a873d9dd5e8663b66ee4444372b63308b770a1c7..5df78f81e75dd5890c9749667eccb33cd8ae2275 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 c6200518f200b198b5485b952dbc412fff6fdd78..0000000000000000000000000000000000000000 --- 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 eaff9d5fa054c4fb87258577310ed5890e93cfa1..3d17351bbb6bcfd79b7042ef588534e0b4da2ffd 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 4ba556aff0a6b3a2779534d8879e4d4f0a2514ba..323b13a1f50f4a3e7de8c1064dbda1de6af9b01a 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 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 d330fc5523e0f3e4f9ee7bc8d4abd762743a1a36..a08767d5f3324c77ef2e16034dd3751553a1151e 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/LastLoadBalancing.java b/client/src/main/java/cn/icanci/loopstack/ras/client/cache/loadbalancing/LastLoadBalancing.java index 404709f088aa384d7cb84122ddf78bdad39c33b7..057b549dfcfd2fc2b452ab2f77f38b81da8a7fb0 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 fb2901352aad57c45036ba6f05e073847f796f58..b0fd32392b96c379e11b3ef9e7f43d6f90b5b3a9 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 d9f3961bf06deecc5eb398670c65020b8c9f9605..0cc99c77b1f39cf2e695e8e49a8d1707a54f9673 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,6 +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.Set; +import java.util.stream.Collectors; + +import org.apache.commons.collections4.CollectionUtils; /** * 负载均衡缓存 @@ -12,4 +19,11 @@ import cn.icanci.loopstack.ras.client.cache.MetaCacheHolder; */ public abstract class LoadBalancingCache extends MetaCacheHolder { + 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 0000000000000000000000000000000000000000..f901ae0229d419d6e709a176712679f152573ff0 --- /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 0000000000000000000000000000000000000000..82693eaa8045fda13f50fbd0fad933bee6b2e635 --- /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 0000000000000000000000000000000000000000..df1d19a9cdf470af638f4ed7377e87b8c85620d9 --- /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 0000000000000000000000000000000000000000..adaef62ecc7cf0b9461171e9745edcbe6854f0b6 --- /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